groovy 0.6.8 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc2f1ef55cf22504bc95fd3a143108b0d7097816274606cb557851c588c7ba02
4
- data.tar.gz: 8881018c1036dab4257291bde59c8797317ba1568cafcb7d87ac12f8b7cf9499
3
+ metadata.gz: da506ad46a6a3aad6cd965b7fcc43079fd61903c1e1a9f0bee659342430dc9ad
4
+ data.tar.gz: 6eba099bd0552fcc3ce8aaa15a0d9fb46486a96e1c1eee8dcd427f86a7d44256
5
5
  SHA512:
6
- metadata.gz: 63e936c9c4920be9e27d3567acc575cf75900fcd5be9786b55f171f068dec19ab4b618ce22367ae7856c30d602517574a61fbc2fef37e36dfc62a9f9d2b7bbf6
7
- data.tar.gz: ee9f1292bb74220dd40acc1058151d4ca6f390e94b4f1b6e9c13561d6dfb1aa9a5df774d858a66695906478a70a8ba49c9ce368585496223287ad67a8276f563
6
+ metadata.gz: 4c26e85b1dc605632deff25150f39e3794079c75581c0098c4893d01fced0729a6f4cd99fea8cae1d840aa003b219dfc62a62acbc0fa0743514d2d4464bbf98a
7
+ data.tar.gz: 1efedf625a489694dc51442664438d8d3a1984dfa50398734f97ecccf8f8146ff4543c06f9a1a6b9a0b17c4007d4fd1baa636b5d2ade8a98b300142133e89240
data/lib/groovy/model.rb CHANGED
@@ -17,6 +17,31 @@ module Groovy
17
17
  @models ||= {}
18
18
  end
19
19
 
20
+ module Utils
21
+ def self.singularize(str)
22
+ str.to_s.sub(/ies$/, 'y').sub(/s$/, '')
23
+ end
24
+
25
+ # category -> categories
26
+ # product -> products
27
+ def self.pluralize(str)
28
+ return str if str[-1] == 's' # already ends with s, assume already plural
29
+ str.to_s.sub(/y$/, 'ie') + 's'
30
+ end
31
+
32
+ def self.pluralize_and_classify(str)
33
+ classify(pluralize(str))
34
+ end
35
+
36
+ def self.underscore(str)
37
+ str.gsub(/([A-Z])/) { |x| "_#{x.downcase}" }.sub(/^_/, '')
38
+ end
39
+
40
+ def self.classify(str)
41
+ str.to_s.gsub(/([A-Z])/, '_\1').split('_').collect! { |w| w.capitalize }.join
42
+ end
43
+ end
44
+
20
45
  module Model
21
46
 
22
47
  def self.initialize_from_record(obj)
@@ -30,23 +55,21 @@ module Groovy
30
55
  # end
31
56
 
32
57
  def self.model_from_table(table_name)
33
- get_class(table_name.to_s.sub(/ies$/, 'y').sub(/s$/, ''))
58
+ get_class(Utils.singularize(table_name))
34
59
  end
35
60
 
36
61
  def self.included(base)
37
62
  base.extend(ClassMethods)
38
63
  base.include(Forwardable)
39
- base.table_name = base.name.sub(/y$/, 'ie') + 's'
64
+ base.table_name = Utils.pluralize(base.name)
40
65
 
41
66
  # add to global model list
42
67
  # Groovy.models[base.name] = base
43
68
  Groovy.models[base.table_name] = base
44
69
  end
45
70
 
46
- def self.get_class(table_name)
47
- # classify method
48
- classified = table_name.gsub(/([A-Z])/, '_\1').split('_').collect! { |w| w.capitalize }.join
49
- Kernel.const_get(classified)
71
+ def self.get_class(klass_name)
72
+ Kernel.const_get(Utils.classify(klass_name))
50
73
  end
51
74
 
52
75
  module ClassMethods
@@ -63,11 +86,15 @@ module Groovy
63
86
  end
64
87
 
65
88
  def underscore_name
66
- name.gsub(/([A-Z])/) { |x| "_#{x.downcase}" }.sub(/^_/, '')
89
+ Utils.underscore(name)
67
90
  end
68
91
 
69
92
  def attribute_names
70
- @attribute_names ||= schema.attribute_columns
93
+ schema.attribute_columns
94
+ end
95
+
96
+ def reference_names
97
+ schema.singular_references + schema.plural_references
71
98
  end
72
99
 
73
100
  # def singular_refs
@@ -87,11 +114,13 @@ module Groovy
87
114
  self.context_name = options[:context] || Groovy.first_context_name
88
115
  self.table_name = options[:table_name] if options[:table_name]
89
116
 
90
- s = Schema.new(db_context, table_name, {})
117
+ s = Schema.new(db_context, table_name, options)
91
118
  yield s if block
92
119
  s.sync
93
120
 
94
- extend(PatriciaTrieMethods) if table.is_a?(Groonga::PatriciaTrie)
121
+ include(HashTable) if table.is_a?(Groonga::Hash)
122
+ include(PatriciaTrieTable) if table.is_a?(Groonga::PatriciaTrie)
123
+
95
124
  s.column_names.each { |col| add_accessors_for(col, s) }
96
125
  s
97
126
  end
@@ -118,7 +147,7 @@ module Groovy
118
147
  elsif s.plural_references.include?(col)
119
148
  add_vector_accessors(col)
120
149
  else
121
- puts "WARNING: Unknown column type: #{col}"
150
+ raise "Unknown column type: #{col}"
122
151
  end
123
152
  end
124
153
 
@@ -147,13 +176,13 @@ module Groovy
147
176
  end
148
177
  end
149
178
 
150
- def create(attributes, key = nil)
151
- obj = new(attributes, nil, key)
179
+ def create(attributes)
180
+ obj = new(attributes)
152
181
  obj.save ? obj : false
153
182
  end
154
183
 
155
- def create!(attributes, key = nil)
156
- create(attributes, key) or raise Error, "Invalid"
184
+ def create!(attributes)
185
+ create(attributes) or raise Error, "Invalid"
157
186
  end
158
187
 
159
188
  def update_all(attrs)
@@ -174,6 +203,12 @@ module Groovy
174
203
  # Groonga["#{table_name}.#{name}"] # .search, .similar_search, etc
175
204
  # end
176
205
 
206
+ def search_table
207
+ schema.search_table
208
+ end
209
+
210
+ def_instance_delegators :search_table, :prefix_search, :each_with_prefix # just these two for now
211
+
177
212
  def index_search(column, query, options = {}, &block)
178
213
  results = table.select { |rec| rec[column].match(query) }
179
214
  render_results(results, &block)
@@ -230,6 +265,14 @@ module Groovy
230
265
  query.where(*args, &block)
231
266
  end
232
267
 
268
+ def each(&block)
269
+ query.each(&block)
270
+ end
271
+
272
+ def find_or_create_by(attributes)
273
+ find_by(**attributes) || create(**attributes)
274
+ end
275
+
233
276
  [:first, :last, :select, :find_by, :search, :not, :sort_by, :in_batches, :limit, :offset, :paginate].each do |scope_method|
234
277
  define_method scope_method do |**args, &block|
235
278
  query.public_send(scope_method, **args, &block)
@@ -308,21 +351,80 @@ module Groovy
308
351
  end
309
352
  end
310
353
 
311
- module PatriciaTrieMethods
312
- extend Forwardable
313
- def_instance_delegators :table, :scan, :prefix_search, :open_prefix_cursor, :tag_keys
354
+ module PatriciaTrieTable
355
+ def self.included(base)
356
+ base.extend(ClassMethods)
357
+ end
358
+
359
+ module ClassMethods
360
+ extend Forwardable
361
+ def_instance_delegators :table, :scan, :prefix_search, :open_prefix_cursor, \
362
+ :suffix_search, :open_near_cursor, :tag_keys
314
363
 
315
- def each_with_prefix(prefix, options = {}, &block)
316
- table.open_prefix_cursor(prefix, options) do |cursor|
317
- cursor.each { |r| yield r }
364
+ def each_with_prefix(prefix, options = {}, &block)
365
+ table.open_prefix_cursor(prefix, options) do |cursor|
366
+ cursor.each { |r| yield r }
367
+ end
368
+ end
369
+
370
+ def each_near(str, options = {}, &block)
371
+ table.open_near_cursor(str, options) do |cursor|
372
+ cursor.each { |r| yield r }
373
+ end
318
374
  end
319
375
  end
320
376
  end
321
377
 
378
+ module HashTable
379
+ def self.included(base)
380
+ base.extend(ClassMethods)
381
+ end
382
+
383
+ module ClassMethods
384
+ def find(key)
385
+ if record = table[key.to_s] and record.record_id
386
+ new_from_record(record)
387
+ end
388
+ end
389
+
390
+ def new_from_record(record)
391
+ # new(record.attributes, record)
392
+ new(record._key, nil, record)
393
+ end
394
+
395
+ def create(key, attributes)
396
+ obj = new(key, attributes)
397
+ obj.save ? obj : false
398
+ end
399
+
400
+ def create!(key, attributes)
401
+ create(key, attributes) or raise Error, "Invalid"
402
+ end
403
+ end
404
+
405
+ def initialize(key, attrs = nil, record = nil)
406
+ @key = key
407
+ super(attrs, record)
408
+ end
409
+
410
+ def load_record
411
+ self.class.table[key]
412
+ end
413
+
414
+ # def new_record?
415
+ # key.nil?
416
+ # end
417
+
418
+ def key
419
+ @key || (record ? record._key : nil)
420
+ end
421
+
422
+ end
423
+
322
424
  attr_reader :id, :record, :changes
323
425
 
324
- def initialize(attrs = nil, record = nil, key = nil)
325
- @attributes, @vectors, @_key = {}, {}, key # key is used on creation only
426
+ def initialize(attrs = nil, record = nil)
427
+ @attributes, @vectors = {}, {}
326
428
  @foreign_refs_to_update = {}
327
429
 
328
430
  if set_record(record)
@@ -344,9 +446,9 @@ module Groovy
344
446
 
345
447
  # get reference to the actual record in the Groonga table,
346
448
  # not the temporary one we get as part of a search result.
347
- # def load_record
348
- # self.class.table[id]
349
- # end
449
+ def load_record
450
+ self.class.table[id]
451
+ end
350
452
 
351
453
  def attributes
352
454
  load_attributes_from_record # populate missing
@@ -356,7 +458,7 @@ module Groovy
356
458
  alias_method :attrs, :attributes
357
459
 
358
460
  def inspect
359
- "#<#{self.class.name} id:#{id.inspect} attributes:[#{self.class.attribute_names.join(', ')}]>"
461
+ "#<#{self.class.name} id:#{id.inspect} attributes:[#{self.class.attribute_names.join(', ')}] references:[#{self.class.reference_names.join(', ')}]>"
360
462
  end
361
463
 
362
464
  def dump
@@ -365,7 +467,6 @@ module Groovy
365
467
 
366
468
  def new_record?
367
469
  id.nil?
368
- # _key.nil?
369
470
  end
370
471
 
371
472
  def persisted?
@@ -427,6 +528,9 @@ module Groovy
427
528
  update_attributes(obj) or raise "Invalid!"
428
529
  end
429
530
 
531
+ alias_method :update, :update_attributes
532
+ alias_method :update!, :update_attributes!
533
+
430
534
  def save(options = {})
431
535
  return false if respond_to?(:invalid?) and invalid?
432
536
  if new_record?
@@ -455,7 +559,7 @@ module Groovy
455
559
  unless new_record?
456
560
  # raise RecordNotPersisted if id.nil?
457
561
  # ensure_persisted!
458
- rec = self.class.table[id] # _key
562
+ rec = load_record
459
563
  set_record(rec)
460
564
  # load_attributes_from_record
461
565
  end
@@ -494,11 +598,6 @@ module Groovy
494
598
  return val.to_i == 0 ? nil : val
495
599
  end
496
600
 
497
- # def _key
498
- # return unless record
499
- # record.respond_to?(:_key) ? record._key : id
500
- # end
501
-
502
601
  def load_attributes_from_record
503
602
  self.class.attribute_names.each do |col|
504
603
  public_send("#{col}=", get_record_attribute(col)) unless @attributes.key?(col)
@@ -533,7 +632,14 @@ module Groovy
533
632
  if record.nil? # not persisted yet
534
633
  set_attribute(name, obj.id) # obj should be a groovy model or groonga record
535
634
  else
536
- val = obj.respond_to?(:record) ? obj.record : obj
635
+ val = if obj.is_a?(Groovy::Model)
636
+ obj.id
637
+ elsif obj.respond_to?(:record)
638
+ # obj.record.record_id
639
+ obj.record
640
+ else
641
+ obj
642
+ end
537
643
  record[name] = val
538
644
  end
539
645
  end
@@ -545,7 +651,7 @@ module Groovy
545
651
 
546
652
  def create
547
653
  fire_callbacks(:before_create)
548
- set_record(self.class.insert(@attributes, @_key))
654
+ set_record(self.class.insert(@attributes, @key))
549
655
  update_foreign_refs
550
656
  fire_callbacks(:after_create)
551
657
  self
data/lib/groovy/query.rb CHANGED
@@ -80,20 +80,26 @@ module Groovy
80
80
  add_param(AND + "(#{map_operator(handle_timestamps(conditions))})")
81
81
  when Hash # { foo: 'bar' } or { views: 1..100 }
82
82
  conditions.each do |key, val|
83
- if val.is_a?(Range)
83
+ case val
84
+ when Model
85
+ raise "Object not persisted yet!" unless val.persisted?
86
+ str = "#{key}:#{val.id}"
87
+ add_param(AND + str)
88
+
89
+ when Range
84
90
  add_param(AND + [key, val.min].join(':>=')) if val.min # lte
85
91
  add_param(AND + [key, val.max].join(':<=')) if val.max # gte
86
92
 
87
- elsif val.is_a?(Regexp)
93
+ when Regexp
88
94
  str = val.source.gsub('/', '_slash_').gsub('(', '_openp_').gsub(')', '_closep_').gsub(REMOVE_INVALID_CHARS_REGEX, '')
89
95
  param = val.source[0] == '^' ? ':^' : val.source[-1] == '$' ? ':$' : ':~' # starts with or regexp
90
96
  add_param(AND + [key, str.downcase].join(param)) # regex must be downcase
91
97
 
92
- elsif val.is_a?(Array) # { foo: [1,2,3] }
98
+ when Array # { foo: [1,2,3] }
93
99
  str = "#{key}:#{val.join(" OR #{key}:")}"
94
100
  add_param(AND + str)
95
101
 
96
- elsif val.is_a?(Time)
102
+ when Time
97
103
  # The second, specify the timestamp as string in following format:
98
104
  # “(YEAR)/(MONTH)/(DAY) (HOUR):(MINUTE):(SECOND)”
99
105
 
data/lib/groovy/schema.rb CHANGED
@@ -4,6 +4,14 @@ module Groovy
4
4
  class Schema
5
5
 
6
6
  SEARCH_TABLE_NAME = 'Terms'.freeze
7
+
8
+ SEARCH_TABLE_OPTIONS = {
9
+ type: :patricia_trie,
10
+ normalizer: :NormalizerAuto,
11
+ key_type: "ShortText",
12
+ default_tokenizer: "TokenBigram"
13
+ }.freeze
14
+
7
15
  COLUMN_DEFAULTS = {
8
16
  compress: :zstandard
9
17
  }.freeze
@@ -33,6 +41,10 @@ module Groovy
33
41
  @table ||= context[table_name]
34
42
  end
35
43
 
44
+ def table_type
45
+ (@opts[:type] || :array).to_sym
46
+ end
47
+
36
48
  # def [](key)
37
49
  # # @spec[key.to_sym]
38
50
  # table.columns.select { |c| c.column? && c.name.to_s == "#{table_name}.#{key.to_s}" }
@@ -115,11 +127,11 @@ module Groovy
115
127
  end
116
128
 
117
129
  def reference(name, table_name = nil, options = {})
118
- table_name = "#{name}s" if table_name.nil?
130
+ table_name = Utils.pluralize_and_classify(name) if table_name.nil?
119
131
 
120
132
  unless context[table_name]
121
133
  log "Table #{table_name} doesn't exist yet! Creating now..."
122
- create_table!(table_name)
134
+ create_table!(table_name, nil)
123
135
  end
124
136
 
125
137
  refs_by_table[table_name] = name.to_sym
@@ -174,19 +186,17 @@ module Groovy
174
186
  name_col = [table_name, col].join('.')
175
187
  log "Adding index on #{name_col}"
176
188
  Groonga::Schema.change_table(SEARCH_TABLE_NAME, context: context) do |table|
177
- # table.index(name_col, name: name_col, with_position: true, with_section: true)
178
- table.index(name_col, name: name_col.sub('.', '_'))
189
+ if opts[:search] # search column requires with_position: true
190
+ table.index(name_col, name: name_col, with_position: true, with_section: true)
191
+ else
192
+ table.index(name_col, name: name_col.sub('.', '_'))
193
+ end
179
194
  end
180
195
  end
181
196
 
182
197
  def ensure_search_table!
183
198
  return if search_table
184
- opts = (@opts[:search_table] || {}).merge({
185
- type: :patricia_trie,
186
- normalizer: :NormalizerAuto,
187
- key_type: "ShortText",
188
- default_tokenizer: "TokenBigram"
189
- })
199
+ opts = (@opts[:search_table] || {}).merge(SEARCH_TABLE_OPTIONS)
190
200
  log("Creating search table with options: #{opts.inspect}")
191
201
  Groonga::Schema.create_table(SEARCH_TABLE_NAME, opts.merge(context: context))
192
202
  end
@@ -225,9 +235,9 @@ module Groovy
225
235
  end
226
236
  end
227
237
 
228
- def create_table!(name = table_name)
229
- log "Creating table #{name}!"
230
- Groonga::Schema.create_table(name, context: context)
238
+ def create_table!(name = table_name, type = table_type)
239
+ log "Creating table #{name} with type #{type.inspect}!"
240
+ Groonga::Schema.create_table(name, context: context, type: type)
231
241
  end
232
242
 
233
243
  def remove_table!(name = table_name)
@@ -1,3 +1,3 @@
1
1
  module Groovy
2
- VERSION = '0.6.8'.freeze
2
+ VERSION = '0.7.1'.freeze
3
3
  end
@@ -4,14 +4,14 @@ describe Groovy::Model do
4
4
 
5
5
  before :all do
6
6
  Groovy.open('tmp/callbacks', 'callbacks_spec')
7
- load_callbacks_schema!
7
+ load_test_schema!
8
8
  end
9
9
 
10
10
  after :all do
11
11
  Groovy.close('callbacks_spec')
12
12
  end
13
13
 
14
- def load_callbacks_schema!
14
+ def load_test_schema!
15
15
  klass = Class.new
16
16
  Object.const_set("User", klass)
17
17
  User.class_eval do
@@ -35,8 +35,6 @@ describe Groovy::Model do
35
35
  # puts "updated"
36
36
  end
37
37
  end
38
-
39
- User.add_reference :comments, "Comments", type: :vector
40
38
  end
41
39
 
42
40
  it 'fires created callbacks' do
data/spec/model_spec.rb CHANGED
@@ -15,7 +15,6 @@ describe Groovy::Model do
15
15
  end
16
16
 
17
17
  describe '.scope' do
18
-
19
18
  before :all do
20
19
  TestProduct.class_eval do
21
20
  scope :with_name, -> (name) { where(name: name) if name }
@@ -120,6 +119,21 @@ describe Groovy::Model do
120
119
  end
121
120
 
122
121
  describe '#update_attributes' do
122
+
123
+ it 'allows setting references out of searches' do
124
+ cat = TestCategory.create!(name: 'A category')
125
+ cat2 = TestCategory.create!(name: 'Another category')
126
+
127
+ prod = TestProduct.create!(name: 'A product', price: 100)
128
+ prod.update_attributes(test_category: cat)
129
+
130
+ last = TestCategory.last
131
+ expect(last).to eq(cat2)
132
+ puts "last: #{last.inspect}"
133
+ prod.update_attributes(test_category: last)
134
+ expect(prod.reload.test_category).to eq(cat2)
135
+ end
136
+
123
137
  end
124
138
 
125
139
  describe '#save' do
@@ -147,15 +161,12 @@ describe Groovy::Model do
147
161
  end
148
162
 
149
163
  describe 'attributes accessors' do
150
-
151
164
  end
152
165
 
153
166
  describe 'singular refs' do
154
-
155
167
  end
156
168
 
157
169
  describe 'plural refs' do
158
-
159
170
  end
160
171
 
161
172
  end
data/spec/query_spec.rb CHANGED
@@ -16,6 +16,13 @@ describe Groovy::Query do
16
16
  Groovy.close('query_spec')
17
17
  end
18
18
 
19
+ # describe '#first' do
20
+ # it 'returns a valid object' do
21
+ # res = TestProduct.first
22
+ # expect(res.record.table.name).to eq(TestProduct.table.name)
23
+ # end
24
+ # end
25
+
19
26
  describe '#where' do
20
27
  describe 'boolean value' do
21
28
  it 'finds expected records' do
@@ -0,0 +1,74 @@
1
+ require_relative './spec_helper'
2
+
3
+ describe Groovy::Model do
4
+
5
+ CONTEXT_NAME = 'schema_spec'
6
+
7
+ before :all do
8
+ Groovy.open('tmp/' + CONTEXT_NAME, CONTEXT_NAME)
9
+ load_test_schema!
10
+ end
11
+
12
+ after :all do
13
+ Groovy.close(CONTEXT_NAME)
14
+ end
15
+
16
+ def load_test_schema!
17
+ klass = Class.new
18
+ Object.const_set("Product", klass)
19
+ Product.class_eval do
20
+ include Groovy::Model
21
+
22
+ schema(type: 'hash', context: CONTEXT_NAME) do |t|
23
+ t.string :name
24
+ t.many :categories
25
+ t.timestamps
26
+ end
27
+ end
28
+
29
+ klass = Class.new
30
+ Object.const_set("Category", klass)
31
+ Category.class_eval do
32
+ include Groovy::Model
33
+
34
+ schema(context: CONTEXT_NAME) do |t|
35
+ t.many :products, "Products"
36
+ t.string :name
37
+ t.timestamps
38
+ end
39
+ end
40
+ end
41
+
42
+ describe 'hash table' do
43
+
44
+ it 'creates, updates and finds records as expected' do
45
+ product = Product.new('ipod-mini', name: 'iPod Mini')
46
+ expect(product.new_record?).to eq(true)
47
+
48
+ expect(product.name).to eq('iPod Mini')
49
+ expect(product.save).to eq(true)
50
+ expect(product.persisted?).to eq(true)
51
+ expect(product.key).to eq('ipod-mini')
52
+
53
+ expect(product.update_attributes(name: 'iPod Mini 2nd Generation'))
54
+ expect(product.name).to eq('iPod Mini 2nd Generation')
55
+
56
+ expect(Product.find('ipod-mini')).to eq(product)
57
+ end
58
+
59
+ it 'works with references too' do
60
+ product = Product.new('ipod-mini', name: 'iPod Mini')
61
+ expect(product.save).to eq(true)
62
+
63
+ category = Category.new(name: 'iPods')
64
+ expect(category.save).to eq(true)
65
+
66
+ category.products << product
67
+ product.categories << category
68
+
69
+ expect(product.reload.categories).to eq([category])
70
+ end
71
+
72
+ end
73
+
74
+ end
data/spec/search_spec.rb CHANGED
@@ -6,7 +6,7 @@ describe Groovy::Model, 'searching' do
6
6
  Groovy.open('tmp/search', 'search_spec')
7
7
  load_schema! 'search_spec'
8
8
 
9
- TestProduct.add_column :description, :string, index: true
9
+ TestProduct.add_column :description, :string, index: true #, search: true
10
10
 
11
11
  TestProduct.create!(name: 'First product', description: 'Lorem ipsum dolor sit amet')
12
12
  TestProduct.create!(name: 'Second product', description: 'Lorea el ipsum poh loco')
@@ -51,4 +51,25 @@ describe Groovy::Model, 'searching' do
51
51
  expect(res.first.name).to eq('Second product')
52
52
  end
53
53
  end
54
+
55
+ describe 'prefix search' do
56
+ it 'returns results' do
57
+ res = TestProduct.prefix_search('Lore')
58
+ expect(res.count).to eq(0)
59
+
60
+ res = TestProduct.prefix_search('lore')
61
+ expect(res.count).to eq(2)
62
+ expect(res.first).to be_a(Groonga::Record)
63
+ parts = res.map { |rec| rec['._key'] }
64
+ expect(parts).to eq(['lorem', 'lorea'])
65
+ end
66
+
67
+ # it 'works with each_with_prefix too' do
68
+ # parts = []
69
+ # res = TestProduct.each_with_prefix('lore') do |rec|
70
+ # parts.push(rec['._key'])
71
+ # end
72
+ # expect(parts).to eq(['lorem', 'lorea'])
73
+ # end
74
+ end
54
75
  end
data/spec/spec_helper.rb CHANGED
@@ -16,12 +16,21 @@ RSpec.configure do |config|
16
16
  end
17
17
  end
18
18
 
19
+ class TestCategory
20
+ include Groovy::Model
21
+ end
22
+
19
23
  class TestProduct
20
24
  include Groovy::Model
21
25
  end
22
26
 
23
27
  def load_schema!(context_name)
28
+ TestCategory.load_schema context: context_name do |t|
29
+ t.string :name
30
+ end
31
+
24
32
  TestProduct.load_schema context: context_name do |t|
33
+ t.one :test_category
25
34
  t.boolean :visible
26
35
  t.string :name
27
36
  t.integer :price
data/spec/vector_spec.rb CHANGED
@@ -63,6 +63,13 @@ describe Groovy::Model do
63
63
  expect(user2.reload.comments).to eq([])
64
64
  end
65
65
 
66
+ it 'finds records using relations too' do
67
+ user = User.create(name: 'John')
68
+ comment = Comment.create(author: user, content: 'Hello there!')
69
+
70
+ expect(Comment.find_by(author: user)).to eq(comment)
71
+ end
72
+
66
73
  end
67
74
 
68
75
  end
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.6.8
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomás Pollak
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-06 00:00:00.000000000 Z
11
+ date: 2024-07-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rroonga
@@ -101,13 +101,14 @@ files:
101
101
  - spec/groovy_spec.rb
102
102
  - spec/model_spec.rb
103
103
  - spec/query_spec.rb
104
+ - spec/schema_spec.rb
104
105
  - spec/search_spec.rb
105
106
  - spec/spec_helper.rb
106
107
  - spec/vector_spec.rb
107
108
  homepage: https://github.com/tomas/groovy
108
109
  licenses: []
109
110
  metadata: {}
110
- post_install_message:
111
+ post_install_message:
111
112
  rdoc_options: []
112
113
  require_paths:
113
114
  - lib
@@ -122,8 +123,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
123
  - !ruby/object:Gem::Version
123
124
  version: '0'
124
125
  requirements: []
125
- rubygems_version: 3.4.10
126
- signing_key:
126
+ rubygems_version: 3.4.6
127
+ signing_key:
127
128
  specification_version: 4
128
129
  summary: A wrapper around Groonga/Rroonga
129
130
  test_files: []