activerecord-utils 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a972ada88d58d419b8cbe37ffd2a8f759ed71317
4
- data.tar.gz: 35bbf160a49f76616d701fb52d6aebff58ee4698
3
+ metadata.gz: 0170989d89e7f272711aa9fb84b0deec2b1c51f3
4
+ data.tar.gz: d0b7a914857f0a9a8f98a73b8cc93069188fde30
5
5
  SHA512:
6
- metadata.gz: 85725b37c1121e4c61eb56e9f917408526ce676f19ec3742894bbfa1a89bef5f35fb1e6fda6e101ca77b33559e56d489c88312350e9df36a24828d5e4baef6c9
7
- data.tar.gz: b161fed850886f04ae9056cdf28253cf831a1390237c1594c7b7b62ec60527ceeef5c3aebb673aaa30e133ccfe3242576d18404cd614cb1779038e18440ff457
6
+ metadata.gz: 5589fde05b548766683fbe697cef2ae9850a771aa79d6ea6745e8a29f489edbbab059ef0d09952cd05c0a230c4c3a44a9ace9d4f7422a5f94eb2ffd2e218ad36
7
+ data.tar.gz: f988280ea2755298f2372db81478307754b4a873df33e2ce9e6a4519808ef2eaca24c333014b1d79d819b8817a7ee2b427e300e1dd310d8c7f3b1f983531fb8f
data/Manifest.txt CHANGED
@@ -4,10 +4,12 @@ README.md
4
4
  Rakefile
5
5
  lib/activerecord/utils.rb
6
6
  lib/activerecord/utils/alias.rb
7
+ lib/activerecord/utils/browser.rb
7
8
  lib/activerecord/utils/comp3.rb
8
9
  lib/activerecord/utils/random.rb
9
10
  lib/activerecord/utils/version.rb
10
11
  test/helper.rb
12
+ test/test_browser.rb
11
13
  test/test_finders.rb
12
14
  test/test_random.rb
13
15
  test/test_readers.rb
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require './lib/activerecord/utils/version.rb'
3
3
 
4
4
  Hoe.spec 'activerecord-utils' do
5
5
 
6
- self.version = ActiveRecord::Utils::VERSION
6
+ self.version = ActiveRecordUtils::VERSION
7
7
 
8
8
  self.summary = 'activerecord-utils - utilities (e.g. random, alias_attr, etc.) for activerecord'
9
9
  self.description = summary
@@ -18,7 +18,8 @@ Hoe.spec 'activerecord-utils' do
18
18
  self.history_file = 'History.md'
19
19
 
20
20
  self.extra_deps = [
21
- ['logutils']
21
+ ['logutils'],
22
+ ['activerecord']
22
23
  ]
23
24
 
24
25
  self.licenses = ['Public Domain']
@@ -28,4 +29,4 @@ Hoe.spec 'activerecord-utils' do
28
29
  }
29
30
 
30
31
 
31
- end
32
+ end
@@ -1,10 +1,10 @@
1
+ # encoding: utf-8
1
2
 
2
- require 'activerecord/utils/version' # let version always go first
3
3
 
4
+ require 'activerecord/utils/version' # let version always go first
4
5
 
5
- module ActiveRecord
6
6
 
7
- module Utils
7
+ module ActiveRecordUtils
8
8
 
9
9
  def self.banner
10
10
  ## add ar PRE too? how?
@@ -16,9 +16,7 @@ module Utils
16
16
  "#{File.expand_path( File.dirname(File.dirname(File.dirname(__FILE__))) )}"
17
17
  end
18
18
 
19
- end # module Utils
20
-
21
- end # module ActiveRecord
19
+ end # module ActiveRecordUtils
22
20
 
23
21
 
24
22
  ########################
@@ -31,9 +29,10 @@ end
31
29
 
32
30
  require 'activerecord/utils/alias'
33
31
  require 'activerecord/utils/random'
32
+ require 'activerecord/utils/browser'
34
33
 
35
34
 
36
- puts ActiveRecord::Utils.banner # say hello
35
+ puts ActiveRecordUtils.banner # say hello
37
36
 
38
- ### puts "root: >#{ActiveRecord::Utils.root}<" # check root path (remove later)
37
+ ### puts "root: >#{ActiveRecordUtils.root}<" # check root path (remove later)
39
38
 
@@ -1,3 +1,4 @@
1
+ # encoding: utf-8
1
2
 
2
3
  module ActiveRecord
3
4
  class Base
@@ -0,0 +1,282 @@
1
+ # encoding: utf-8
2
+
3
+ module ActiveRecordUtils
4
+
5
+ ####
6
+ # simple (generic) database browser - no models required
7
+
8
+
9
+ class Browser # also (formerly) known as connection manager
10
+
11
+ # get connection names
12
+ # def connection_names
13
+ # ActiveRecord::Base.configurations.keys
14
+ # end
15
+
16
+ CONNECTS = {} # cache connections
17
+
18
+ def connection_for( key )
19
+ # cache connections - needed? why? why not??
20
+
21
+ # hack: for now only use cached connection if still active
22
+ # if not; get a new one to avoid connection closed errors in rails
23
+ con = CONNECTS[ key ]
24
+ if con
25
+ puts "[Browser] cached connection found; con.active? #{con.active?}"
26
+ unless con.active?
27
+ puts "[Browser] *** reset cached connection (reason: connection stale/closed/not active)"
28
+ con = CONNECTS[ key ] = nil
29
+ end
30
+ end
31
+
32
+ if con.nil?
33
+ con = CONNECTS[ key ] = AbstractModel.connection_for( key )
34
+ end
35
+
36
+ # note: make sure connection is active?
37
+ # use verify! - will try active? followed by reconnect!
38
+ # - todo: check ourselves if active? - why? why not??
39
+ # -- not working w/ rails - after verify! still getting error w/ closed connection
40
+ # -- con.verify!
41
+
42
+ # wrap ActiveRecord connection in our own connection class
43
+ Connection.new( con, key )
44
+ end
45
+
46
+
47
+ class AbstractModel < ActiveRecord::Base
48
+ self.abstract_class = true # no table; class just used for getting db connection
49
+
50
+ def self.connection_for( key )
51
+ establish_connection( key )
52
+ connection
53
+ end
54
+
55
+ end # class AbstractModel
56
+
57
+
58
+ class Connection
59
+
60
+ def initialize( connection, key )
61
+ @connection = connection
62
+ @key = key
63
+ end
64
+
65
+ attr_reader :connection
66
+ attr_reader :key
67
+
68
+ delegate :select_value, :select_all, :adapter_name,
69
+ :to => :connection
70
+
71
+ def class_name
72
+ @connection.class.name
73
+ end
74
+
75
+ # delegate :quote_table_name, :quote_column_name, :quote,
76
+ # :update, :insert, :delete,
77
+ # :add_limit_offset!,
78
+ # :to => :connection
79
+
80
+ def tables
81
+ @tables ||= fetch_table_defs
82
+ end
83
+
84
+ def table( name )
85
+ tables.find { |t| t.name.downcase == name.downcase }
86
+ end
87
+
88
+ # getting list of column definitions
89
+ # and order them to be more human readable
90
+ def table_columns( name )
91
+ cols = fetch_table_column_defs( name )
92
+ ### fix/to be done
93
+ # cols.sort_by{|col|
94
+ # [
95
+ # fields_to_head.index(col.name) || 1e6,
96
+ # -(fields_to_tail.index(col.name) || 1e6),
97
+ # col.name
98
+ # ]
99
+ # }
100
+ cols
101
+ end
102
+
103
+ def fetch_table_defs
104
+ @connection.tables.sort.map do |name|
105
+ Table.new( self, name )
106
+ end
107
+ end
108
+
109
+ def fetch_table_column_defs( name )
110
+ ### fix/todo: add reference to table_def
111
+ @connection.columns( name ).map do |col|
112
+ Column.new( col.name, col.sql_type, col.default, col.null )
113
+ end
114
+ end
115
+
116
+
117
+ def fetch_table_select_all( name, opts={} )
118
+ limit = (opts[:limit] || 33).to_i # 33 records limit/per page (for now default)
119
+ limit = 33 if limit == 0 # use default page size if limit 0 (from not a number para)
120
+
121
+ offset = (opts[:offset] || 0).to_i
122
+
123
+ sql = "select * from #{name} limit #{limit}"
124
+
125
+ sql << " offset #{offset}" if offset > 0 # add offset if present (e.g greater zero)
126
+
127
+ # page = (opts[:page] || 1 ).try(:to_i)
128
+ # fields = opts[:fields] || nil
129
+
130
+ # rez = { :fields => fields }
131
+ # if sql =~ /\s*select/i && per_page > 0
132
+ # rez[:count] = select_value("select count(*) from (#{sql}) as t").to_i
133
+ # rez[:pages] = (rez[:count].to_f / per_page).ceil
134
+ # sql = "select * from (#{sql}) as t"
135
+ # add_limit_offset!( sql,
136
+ # :limit => per_page,
137
+ # :offset => per_page * (page - 1))
138
+ # end
139
+
140
+ result = {}
141
+ result[ :sql ] = sql # note: lets also always add sql query to result too
142
+ result[ :rows ] = select_all( sql )
143
+
144
+ # unless rez[:rows].blank?
145
+ # rez[:fields] ||= []
146
+ # rez[:fields].concat( self.sort_fields(rez[:rows].first.keys) - rez[:fields] )
147
+ # end
148
+
149
+ Result.new( result )
150
+ rescue StandardError => ex
151
+ Result.new( error: ex )
152
+ end # fetch_table
153
+
154
+
155
+ =begin
156
+ def column_names(table)
157
+ columns(table).map{|c| c.name}
158
+ end
159
+
160
+ # fields to see first
161
+ def fields_to_head
162
+ @fields_to_head ||= %w{id name login value}
163
+ end
164
+
165
+ # fields to see last
166
+ def fields_to_tail
167
+ @fields_to_tail ||= %w{created_at created_on updated_at updated_on}
168
+ end
169
+
170
+ attr_writer :fields_to_head, :fields_to_tail
171
+
172
+ # sort field names in a rezult
173
+ def sort_fields(fields)
174
+ fields = (fields_to_head & fields) | (fields - fields_to_head)
175
+ fields = (fields - fields_to_tail) | (fields_to_tail & fields)
176
+ fields
177
+ end
178
+
179
+ # performs query with appropriate method
180
+ def query(sql, opts={})
181
+ per_page = (opts[:perpage] || nil).to_i
182
+ page = (opts[:page] || 1 ).try(:to_i)
183
+ fields = opts[:fields] || nil
184
+ case sql
185
+ when /\s*select/i , /\s*(update|insert|delete).+returning/im
186
+ rez = {:fields => fields}
187
+ if sql =~ /\s*select/i && per_page > 0
188
+ rez[:count] = select_value("select count(*) from (#{sql}) as t").to_i
189
+ rez[:pages] = (rez[:count].to_f / per_page).ceil
190
+ sql = "select * from (#{sql}) as t"
191
+ add_limit_offset!( sql,
192
+ :limit => per_page,
193
+ :offset => per_page * (page - 1))
194
+ end
195
+
196
+ rez[:rows] = select_all( sql )
197
+
198
+ unless rez[:rows].blank?
199
+ rez[:fields] ||= []
200
+ rez[:fields].concat( self.sort_fields(rez[:rows].first.keys) - rez[:fields] )
201
+ end
202
+
203
+ Result.new(rez)
204
+ when /\s*update/i
205
+ Result.new :value => update( sql )
206
+ when /\s*insert/i
207
+ Result.new :value => insert( sql )
208
+ when /\s*delete/i
209
+ Result.new :value => delete( sql )
210
+ end
211
+ rescue StandardError => e
212
+ Result.new :error => e
213
+ end
214
+
215
+ =end
216
+
217
+ end # class Connection
218
+
219
+
220
+ class Table
221
+
222
+ def initialize(connection, name)
223
+ @connection = connection
224
+ @name = name
225
+ end
226
+
227
+ attr_reader :connection
228
+ attr_reader :name
229
+
230
+ def count
231
+ @connection.select_value( "select count(*) from #{name}").to_i
232
+ end
233
+
234
+ def columns
235
+ # load columns on demand for now (cache on first lookup)
236
+ @columns ||= @connection.table_columns( @name )
237
+ end
238
+
239
+ def query( opts={})
240
+ @connection.fetch_table_select_all( @name, opts )
241
+ end
242
+
243
+ end # class Table
244
+
245
+
246
+ class Column
247
+ def initialize(name, type, default, null)
248
+ @name = name
249
+ @type = type # note: is sql_type
250
+ @default = default
251
+ @null = null # note: true|false depending if NOT NULL or not
252
+ end
253
+
254
+ attr_reader :name, :type, :default, :null
255
+ end # class Column
256
+
257
+
258
+ class Result
259
+ def initialize( opts={} )
260
+ @sql = opts[:sql] # sql statement as a string
261
+
262
+ if opts[:error]
263
+ @error = opts[:error]
264
+ else
265
+ @rows = opts[:rows]
266
+ # @count = opts[:count] || @rows.size
267
+ # @pages = opts[:pages] || 1
268
+ # @fields = opts[:fields]
269
+ end
270
+ end
271
+
272
+ attr_reader :sql, :rows, :error ### to be done :count, :pages, :fields,
273
+
274
+ def error?() @error.present?; end
275
+ def rows?() @rows != nil; end
276
+ end # class Result
277
+
278
+
279
+ end # class Browser
280
+
281
+ end # module ActiveRecordUtils
282
+
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # encoding: utf-8
2
2
 
3
3
  module ActiveRecord
4
4
  class Base
@@ -1,4 +1,4 @@
1
- # encoding: UTF-8
1
+ # encoding: utf-8
2
2
 
3
3
  module ActiveRecord
4
4
  class Base
@@ -1,9 +1,8 @@
1
+ # encoding: utf-8
1
2
 
2
- module ActiveRecord
3
+ module ActiveRecordUtils
3
4
 
4
- module Utils
5
- VERSION = '0.3.0'
6
- end
5
+ VERSION = '0.4.0'
7
6
 
8
- end # module ActiveRecord
7
+ end # module ActiveRecordUtils
9
8
 
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_browser.rb
6
+ # or better
7
+ # rake test
8
+
9
+
10
+ require 'helper'
11
+
12
+ class TestBrowser < MiniTest::Test
13
+
14
+ DB_CONFIG = {
15
+ adapter: 'sqlite3',
16
+ database: ':memory:'
17
+ }
18
+
19
+ def test_connect
20
+
21
+ browser = ActiveRecordUtils::Browser.new
22
+
23
+ ## Note: every connect will create a new empty in memory db
24
+ ## check - is it possible to reconnect to in memory db??
25
+ ## use (try) key instead of connection-spec ??
26
+
27
+ con = browser.connection_for( DB_CONFIG )
28
+ tables = con.tables
29
+
30
+ pp tables
31
+
32
+ assert true # for now if get here; assume it's working so far
33
+ end
34
+
35
+ end # class TestBrowser
36
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-13 00:00:00.000000000 Z
11
+ date: 2015-02-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logutils
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rdoc
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -68,10 +82,12 @@ files:
68
82
  - Rakefile
69
83
  - lib/activerecord/utils.rb
70
84
  - lib/activerecord/utils/alias.rb
85
+ - lib/activerecord/utils/browser.rb
71
86
  - lib/activerecord/utils/comp3.rb
72
87
  - lib/activerecord/utils/random.rb
73
88
  - lib/activerecord/utils/version.rb
74
89
  - test/helper.rb
90
+ - test/test_browser.rb
75
91
  - test/test_finders.rb
76
92
  - test/test_random.rb
77
93
  - test/test_readers.rb
@@ -102,6 +118,7 @@ signing_key:
102
118
  specification_version: 4
103
119
  summary: activerecord-utils - utilities (e.g. random, alias_attr, etc.) for activerecord
104
120
  test_files:
121
+ - test/test_browser.rb
105
122
  - test/test_readers.rb
106
123
  - test/test_finders.rb
107
124
  - test/test_random.rb