groovy 0.4.6 → 0.5.1

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
  SHA256:
3
- metadata.gz: 2569117dfa3663d6c60ed950be2972c58116e7eaf6d21f5c6640cb91642fee4f
4
- data.tar.gz: 33e1651825dd626dab979e9c504d5de1b7d8162363d42cbeca43873e370cad04
3
+ metadata.gz: af9ef6dd23a84a0887fa26436fb1a3f98112621f25b1088c7e5835706fedefc9
4
+ data.tar.gz: 4fa395ca4c1f32c3d31df1707a2ee66e2c6fabf0550957962b7d5efa3fd7458c
5
5
  SHA512:
6
- metadata.gz: 66b311fe79a3f9c8467ddbe9f863a2fd731b9c7dd9df2dbeb49fc1b8d62f4b7b506b2e0ca1f05c6ad7766ede89df0a26cb4a8eae8f96097ff613ab17cadde593
7
- data.tar.gz: c1dbb4f84dfdb79d870a0e498acbc63d7e1268f5cfd1f0951fd16cc7d890b68a6d3679e903eb703b8de4a44b6765070594df0eb53b8cfbeb7ac9fb1499f5dd3f
6
+ metadata.gz: 7c6936e830cb7449843a43882cf5895b452806ab61ca7f01c2e7c97ae272d0daeb456a2f4d9c16b5cad52c46b8f9902e851b4e6e9c43d27de1d995bdca44fdbf
7
+ data.tar.gz: dbde160c35f34339e5f155bea793c0c4fd5671916326a34c9c69efe9e266baffb47ed12e0afe5edd7a1fae5ba46abc7c41cc8957cba511be5ad4f3972df09ed9
data/README.md CHANGED
@@ -2,4 +2,7 @@
2
2
 
3
3
  An ORM for Groonga.
4
4
 
5
+ # TODO:
6
+
7
+ - [ ] Allow using scopes/queries through Vector class.
5
8
 
data/example/basic.rb CHANGED
@@ -28,4 +28,18 @@ populate if Product.count == 0
28
28
 
29
29
  # 50_000 products: 50M
30
30
  # 100_000 products: 50M
31
- # 500_000 products: 62M
31
+ # 500_000 products: 62M
32
+
33
+ module MemInfo
34
+ KERNEL_PAGE_SIZE = `getconf PAGESIZE`.chomp.to_i rescue 4096
35
+ STATM_PATH = "/proc/#{Process.pid}/statm"
36
+ STATM_FOUND = File.exist?(STATM_PATH)
37
+ def self.rss
38
+ STATM_FOUND ? (File.read(STATM_PATH).split(' ')[1].to_i * KERNEL_PAGE_SIZE) / 1024 : 0
39
+ end
40
+ end
41
+
42
+ puts MemInfo.rss
43
+ prices = Product.all.map { |x| x.price }
44
+ puts prices.inspect
45
+ puts MemInfo.rss
data/example/relations.rb CHANGED
@@ -21,6 +21,7 @@ class Category
21
21
 
22
22
  schema do |t|
23
23
  t.string :name
24
+ t.reference :place, "Places"
24
25
  t.timestamps
25
26
  end
26
27
 
data/lib/groovy/model.rb CHANGED
@@ -26,7 +26,7 @@ module Groovy
26
26
  # end
27
27
 
28
28
  def self.model_from_table(table_name)
29
- Kernel.const_get(table_name.sub(/ies$/, 'y').sub(/s$/, '').capitalize)
29
+ Kernel.const_get(table_name.to_s.sub(/ies$/, 'y').sub(/s$/, '').classify)
30
30
  end
31
31
 
32
32
  def self.included(base)
@@ -133,11 +133,11 @@ module Groovy
133
133
  end
134
134
 
135
135
  def update_all(attrs)
136
- find_each { |child| child.update_attributes(attrs) }
136
+ all.each { |child| child.update_attributes(attrs) }
137
137
  end
138
138
 
139
139
  def delete_all
140
- # find_each { |child| child.delete }
140
+ # all.each { |child| child.delete }
141
141
  table.delete { |record| record._id > -1 }
142
142
  end
143
143
 
@@ -150,7 +150,6 @@ module Groovy
150
150
  # Groonga["#{table_name}.#{name}"] # .search, .similar_search, etc
151
151
  # end
152
152
 
153
-
154
153
  def index_search(column, query, options = {}, &block)
155
154
  results = table.select { |rec| rec[column].match(query) }
156
155
  render_results(results, &block)
@@ -191,14 +190,19 @@ module Groovy
191
190
  query_class.new(self, table)
192
191
  end
193
192
 
193
+ def scopes
194
+ @scopes ||= []
195
+ end
196
+
194
197
  def scope(name, obj)
198
+ scopes.push(name)
195
199
  query_class.add_scope(name, obj)
196
200
  define_singleton_method(name) do |*args|
197
201
  query.public_send(name, *args)
198
202
  end
199
203
  end
200
204
 
201
- [:first, :last, :select, :find_each, :find_by, :search, :where, :not, :sort_by, :limit, :offset, :paginate, :in_batches].each do |scope_method|
205
+ [:first, :last, :select, :find_by, :search, :where, :not, :sort_by, :limit, :offset, :paginate, :in_batches].each do |scope_method|
202
206
  define_method scope_method do |*args, &block|
203
207
  query.public_send(scope_method, *args, &block)
204
208
  end
@@ -283,13 +287,13 @@ module Groovy
283
287
  end
284
288
  end
285
289
 
286
- attr_reader :id, :attributes, :record, :changes
290
+ attr_reader :id, :record, :changes
287
291
 
288
292
  def initialize(attrs = nil, record = nil, key = nil)
289
293
  @attributes, @vectors, @_key = {}, {}, key # key is used on creation only
290
294
 
291
295
  if set_record(record)
292
- set_attributes_from_record(record)
296
+ # load_attributes_from_record(record)
293
297
  else
294
298
  attrs ||= {}
295
299
  unless attrs.is_a?(Hash)
@@ -307,8 +311,13 @@ module Groovy
307
311
 
308
312
  # get reference to the actual record in the Groonga table,
309
313
  # not the temporary one we get as part of a search result.
310
- def load_record
311
- self.class.table[id]
314
+ # def load_record
315
+ # self.class.table[id]
316
+ # end
317
+
318
+ def attributes
319
+ load_attributes_from_record # populate missing
320
+ @attributes
312
321
  end
313
322
 
314
323
  def inspect
@@ -321,7 +330,9 @@ module Groovy
321
330
  end
322
331
 
323
332
  def [](key)
324
- attributes[key.to_sym]
333
+ k = key.to_sym
334
+ @attributes[k] = get_record_attribute(k) unless @attributes.key?(k)
335
+ @attributes[k]
325
336
  end
326
337
 
327
338
  def []=(key, val)
@@ -382,11 +393,15 @@ module Groovy
382
393
  end
383
394
 
384
395
  def reload
385
- raise RecordNotPersisted if id.nil?
386
- ensure_persisted!
387
- rec = self.class.table[id] # _key
388
- # set_record(rec)
389
- set_attributes_from_record(rec)
396
+ unless new_record?
397
+ # raise RecordNotPersisted if id.nil?
398
+ # ensure_persisted!
399
+ rec = self.class.table[id] # _key
400
+ set_record(rec)
401
+ # load_attributes_from_record
402
+ end
403
+
404
+ @attributes = {}
390
405
  @changes = {}
391
406
  self
392
407
  end
@@ -406,6 +421,7 @@ module Groovy
406
421
  private
407
422
 
408
423
  def get_record_attribute(key)
424
+ return if record.nil?
409
425
  val = record[key]
410
426
  if self.class.schema.time_columns.include?(key)
411
427
  fix_time_value(val)
@@ -423,15 +439,15 @@ module Groovy
423
439
  # record.respond_to?(:_key) ? record._key : id
424
440
  # end
425
441
 
426
- def set_attributes_from_record(rec)
442
+ def load_attributes_from_record
427
443
  self.class.attribute_names.each do |col|
428
- public_send("#{col}=", get_record_attribute(col))
444
+ public_send("#{col}=", get_record_attribute(col)) unless @attributes.key?(col)
429
445
  end
430
446
  end
431
447
 
432
448
  def set_attribute(key, val)
433
- changes[key.to_sym] = [self[key], val] if changes # nil when initializing
434
- attributes[key.to_sym] = val
449
+ changes[key.to_sym] = [self[key], val] if changes # nil before initializing
450
+ @attributes[key.to_sym] = val
435
451
  end
436
452
 
437
453
  def get_ref(name)
@@ -456,7 +472,7 @@ module Groovy
456
472
 
457
473
  def create
458
474
  fire_callbacks(:before_create)
459
- set_record(self.class.insert(attributes, @_key))
475
+ set_record(self.class.insert(@attributes, @_key))
460
476
  fire_callbacks(:after_create)
461
477
  self
462
478
  end
data/lib/groovy/query.rb CHANGED
@@ -62,13 +62,13 @@ module Groovy
62
62
  where(conditions).limit(1).first
63
63
  end
64
64
 
65
- def find_each(opts = {}, &block)
66
- count = 0
67
- in_batches({ of: 10 }.merge(opts)) do |group|
68
- group.each { |item| count += 1; yield(item) }
69
- end
70
- count
71
- end
65
+ # def find_each(opts = {}, &block)
66
+ # count = 0
67
+ # in_batches({ of: 10 }.merge(opts)) do |group|
68
+ # group.each { |item| count += 1; yield(item) }
69
+ # end
70
+ # count
71
+ # end
72
72
 
73
73
  # http://groonga.org/docs/reference/grn_expr/query_syntax.html
74
74
  # TODO: support match_columns (search value in two or more columns)
@@ -192,11 +192,16 @@ module Groovy
192
192
  end
193
193
 
194
194
  def [](index)
195
- records[index]
195
+ if r = results[index]
196
+ model.new_from_record(r)
197
+ end
196
198
  end
197
199
 
198
200
  def each(&block)
199
- records.each { |r| block.call(r) }
201
+ # records.each { |r| block.call(r) }
202
+ results.each_with_index do |r, index|
203
+ yield model.new_from_record(r)
204
+ end
200
205
  end
201
206
 
202
207
  def update_all(attrs)
@@ -236,15 +241,15 @@ module Groovy
236
241
  end
237
242
  end
238
243
 
244
+ private
245
+ attr_reader :model, :table, :options, :select_block
246
+
239
247
  def records
240
248
  @records ||= results.map do |r|
241
249
  model.new_from_record(r)
242
250
  end
243
251
  end
244
252
 
245
- private
246
- attr_reader :model, :table, :options, :select_block
247
-
248
253
  def get_last(count = 1)
249
254
  if count > 1
250
255
  records[(size-count)..-1]
data/lib/groovy/schema.rb CHANGED
@@ -26,6 +26,7 @@ module Groovy
26
26
  def initialize(context, table_name, opts = {})
27
27
  @context, @table_name, @opts = context, table_name, opts || {}
28
28
  @spec, @index_columns = {}, []
29
+ @cache = {}
29
30
  end
30
31
 
31
32
  def table
@@ -33,47 +34,44 @@ module Groovy
33
34
  end
34
35
 
35
36
  def search_table
36
- @search_table ||= context[SEARCH_TABLE_NAME]
37
+ @cache[:search_table] ||= context[SEARCH_TABLE_NAME]
37
38
  end
38
39
 
39
40
  def column_names
40
- get_names table.columns
41
+ @cache[:column_names] ||= get_names(table.columns)
41
42
  end
42
43
 
43
44
  def singular_references
44
- # @singular_references ||=
45
- get_names(table.columns.select(&:reference_column?).reject(&:vector?))
45
+ @cache[:singular_references] ||= get_names(table.columns.select(&:reference_column?).reject(&:vector?))
46
46
  end
47
47
 
48
48
  def plural_references
49
- # @plural_references ||=
50
- get_names(table.columns.select(&:vector?))
49
+ @cache[:plural_references] ||= get_names(table.columns.select(&:vector?))
51
50
  end
52
51
 
53
52
  def attribute_columns
54
- # @attribute_columns ||=
55
- get_names(table.columns.select { |c| c.column? && !c.reference_column? && !c.vector? })
53
+ @cache[:attribute_columns] ||= get_names(table.columns.select { |c| c.column? && !c.reference_column? && !c.vector? })
56
54
  end
57
55
 
58
56
  def time_columns
59
- columns_by_type('Time')
57
+ @cache[:time_columns] ||= columns_by_type('Time')
60
58
  end
61
59
 
62
60
  def integer_columns
63
- columns_by_type('Int32')
61
+ @cache[:integer_columns] ||= columns_by_type('Int32')
64
62
  end
65
63
 
66
64
  def boolean_columns
67
- columns_by_type('Bool')
65
+ @cache[:boolean_columns] ||= columns_by_type('Bool')
68
66
  end
69
67
 
70
68
  def columns_by_type(type)
71
69
  get_names(table.columns.select { |c| c.column? && c.range.name == type })
72
70
  end
73
71
 
74
- # def time_column?(name)
75
- # time_columns.include?(name)
76
- # end
72
+ def reload
73
+ @cache = {}
74
+ end
77
75
 
78
76
  def rebuild!
79
77
  log("Rebuilding!")
@@ -116,6 +114,8 @@ module Groovy
116
114
  @index_columns.each do |col|
117
115
  add_index_on(col)
118
116
  end
117
+
118
+ reload
119
119
  self
120
120
  end
121
121
 
data/lib/groovy/vector.rb CHANGED
@@ -74,9 +74,30 @@ module Groovy
74
74
 
75
75
  alias_method :<<, :push
76
76
 
77
+ [:first, :last, :find_by, :search, :where, :not, :sort_by, :limit, :offset, :paginate, :in_batches].each do |scope_method|
78
+ define_method scope_method do |*args, &block|
79
+ query.public_send(scope_method, *args, &block)
80
+ end
81
+ end
82
+
77
83
  private
78
84
  attr_reader :obj, :key
79
85
 
86
+ def query
87
+ model = Model.model_from_table(key.capitalize)
88
+ obj_name = obj.class.name.downcase
89
+ model.query.where(obj_name => obj.id)
90
+ end
91
+
92
+ def method_missing(name, *args, &block)
93
+ model = Model.model_from_table(key.capitalize)
94
+ if model.scopes.include?(name)
95
+ query.send(name)
96
+ else
97
+ super
98
+ end
99
+ end
100
+
80
101
  def remove_record(rec)
81
102
  recs = obj.record[key].delete_if { |r| r == rec }
82
103
  obj.record[key] = recs
@@ -1,3 +1,3 @@
1
1
  module Groovy
2
- VERSION = '0.4.6'.freeze
2
+ VERSION = '0.5.1'.freeze
3
3
  end
data/spec/model_spec.rb CHANGED
@@ -86,6 +86,28 @@ describe Groovy::Model do
86
86
  end
87
87
 
88
88
  describe '#[]' do
89
+ it 'reads value from record' do
90
+ prod = TestProduct.create!(name: 'A product', price: 100)
91
+ expect(prod.name).to eq('A product')
92
+ expect(prod['name']).to eq('A product')
93
+ expect(prod[:name]).to eq('A product')
94
+
95
+ prod = TestProduct.find(prod.id)
96
+ expect(prod.name).to eq('A product')
97
+ expect(prod['name']).to eq('A product')
98
+ expect(prod[:name]).to eq('A product')
99
+
100
+ prod = TestProduct.new
101
+ expect(prod.name).to eq(nil)
102
+ prod.name = 'Another product'
103
+ expect(prod.name).to eq('Another product')
104
+ prod.reload
105
+ expect(prod.name).to eq(nil)
106
+ prod.name = 'Another product'
107
+ prod.save
108
+ prod.reload
109
+ expect(prod.name).to eq('Another product')
110
+ end
89
111
  end
90
112
 
91
113
  describe '#[]=' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: groovy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomás Pollak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-14 00:00:00.000000000 Z
11
+ date: 2022-07-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rroonga