rasti-db 1.5.0 → 2.3.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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +52 -19
  3. data/lib/rasti/db.rb +11 -2
  4. data/lib/rasti/db/collection.rb +67 -36
  5. data/lib/rasti/db/computed_attribute.rb +22 -0
  6. data/lib/rasti/db/data_source.rb +18 -0
  7. data/lib/rasti/db/environment.rb +32 -0
  8. data/lib/rasti/db/nql/filter_condition_strategies/base.rb +17 -0
  9. data/lib/rasti/db/nql/filter_condition_strategies/postgres.rb +21 -0
  10. data/lib/rasti/db/nql/filter_condition_strategies/sqlite.rb +21 -0
  11. data/lib/rasti/db/nql/filter_condition_strategies/types/generic.rb +49 -0
  12. data/lib/rasti/db/nql/filter_condition_strategies/types/pg_array.rb +32 -0
  13. data/lib/rasti/db/nql/filter_condition_strategies/types/sqlite_array.rb +34 -0
  14. data/lib/rasti/db/nql/filter_condition_strategies/unsupported_type_comparison.rb +22 -0
  15. data/lib/rasti/db/nql/nodes/array_content.rb +21 -0
  16. data/lib/rasti/db/nql/nodes/attribute.rb +37 -0
  17. data/lib/rasti/db/nql/nodes/binary_node.rb +4 -0
  18. data/lib/rasti/db/nql/nodes/comparisons/base.rb +15 -1
  19. data/lib/rasti/db/nql/nodes/comparisons/equal.rb +0 -4
  20. data/lib/rasti/db/nql/nodes/comparisons/greater_than.rb +0 -4
  21. data/lib/rasti/db/nql/nodes/comparisons/greater_than_or_equal.rb +0 -4
  22. data/lib/rasti/db/nql/nodes/comparisons/include.rb +0 -4
  23. data/lib/rasti/db/nql/nodes/comparisons/less_than.rb +0 -4
  24. data/lib/rasti/db/nql/nodes/comparisons/less_than_or_equal.rb +0 -4
  25. data/lib/rasti/db/nql/nodes/comparisons/like.rb +0 -4
  26. data/lib/rasti/db/nql/nodes/comparisons/not_equal.rb +0 -4
  27. data/lib/rasti/db/nql/nodes/comparisons/not_include.rb +0 -4
  28. data/lib/rasti/db/nql/nodes/conjunction.rb +2 -2
  29. data/lib/rasti/db/nql/nodes/constants/array.rb +17 -0
  30. data/lib/rasti/db/nql/nodes/constants/base.rb +17 -0
  31. data/lib/rasti/db/nql/nodes/constants/false.rb +1 -1
  32. data/lib/rasti/db/nql/nodes/constants/float.rb +1 -1
  33. data/lib/rasti/db/nql/nodes/constants/integer.rb +1 -1
  34. data/lib/rasti/db/nql/nodes/constants/literal_string.rb +1 -1
  35. data/lib/rasti/db/nql/nodes/constants/string.rb +1 -1
  36. data/lib/rasti/db/nql/nodes/constants/time.rb +1 -1
  37. data/lib/rasti/db/nql/nodes/constants/true.rb +1 -1
  38. data/lib/rasti/db/nql/nodes/disjunction.rb +2 -2
  39. data/lib/rasti/db/nql/nodes/parenthesis_sentence.rb +6 -2
  40. data/lib/rasti/db/nql/nodes/sentence.rb +6 -2
  41. data/lib/rasti/db/nql/syntax.rb +262 -44
  42. data/lib/rasti/db/nql/syntax.treetop +27 -14
  43. data/lib/rasti/db/query.rb +55 -23
  44. data/lib/rasti/db/relations/base.rb +22 -8
  45. data/lib/rasti/db/relations/graph.rb +10 -16
  46. data/lib/rasti/db/relations/many_to_many.rb +57 -23
  47. data/lib/rasti/db/relations/many_to_one.rb +9 -7
  48. data/lib/rasti/db/relations/one_to_many.rb +21 -13
  49. data/lib/rasti/db/type_converters/sqlite.rb +62 -0
  50. data/lib/rasti/db/type_converters/sqlite_types/array.rb +34 -0
  51. data/lib/rasti/db/version.rb +1 -1
  52. data/rasti-db.gemspec +1 -0
  53. data/spec/collection_spec.rb +210 -50
  54. data/spec/computed_attribute_spec.rb +32 -0
  55. data/spec/minitest_helper.rb +77 -15
  56. data/spec/model_spec.rb +4 -2
  57. data/spec/nql/computed_attributes_spec.rb +29 -0
  58. data/spec/nql/filter_condition_spec.rb +23 -4
  59. data/spec/nql/filter_condition_strategies_spec.rb +112 -0
  60. data/spec/nql/syntax_parser_spec.rb +36 -5
  61. data/spec/query_spec.rb +340 -54
  62. data/spec/relations_spec.rb +27 -7
  63. data/spec/type_converters/sqlite_spec.rb +66 -0
  64. metadata +40 -4
  65. data/lib/rasti/db/helpers.rb +0 -16
  66. data/lib/rasti/db/nql/nodes/field.rb +0 -23
@@ -7,10 +7,10 @@ module Rasti
7
7
  @foreign_key ||= options[:foreign_key] || target_collection_class.foreign_key
8
8
  end
9
9
 
10
- def fetch_graph(rows, db, schema=nil, selected_attributes=nil, excluded_attributes=nil, relations_graph=nil)
10
+ def fetch_graph(environment, rows, selected_attributes=nil, excluded_attributes=nil, relations_graph=nil)
11
11
  fks = rows.map { |row| row[foreign_key] }.uniq
12
12
 
13
- target_collection = target_collection_class.new db, schema
13
+ target_collection = target_collection_class.new environment
14
14
 
15
15
  query = target_collection.where(source_collection_class.primary_key => fks)
16
16
  query = query.exclude_attributes(*excluded_attributes) if excluded_attributes
@@ -26,19 +26,21 @@ module Rasti
26
26
  end
27
27
  end
28
28
 
29
- def add_join(dataset, schema=nil, prefix=nil)
29
+ def add_join(environment, dataset, prefix=nil)
30
+ validate_join!
31
+
30
32
  relation_alias = join_relation_name prefix
31
33
 
32
- qualified_relation_source = prefix ? Sequel[prefix] : qualified_source_collection_name(schema)
34
+ relation_name = prefix ? Sequel[prefix] : Sequel[source_collection_class.collection_name]
33
35
 
34
36
  relation_condition = {
35
- Sequel[relation_alias][target_collection_class.primary_key] => qualified_relation_source[foreign_key]
37
+ Sequel[relation_alias][target_collection_class.primary_key] => relation_name[foreign_key]
36
38
  }
37
39
 
38
- dataset.join(qualified_target_collection_name(schema).as(relation_alias), relation_condition)
40
+ dataset.join(environment.qualify_collection(target_collection_class).as(relation_alias), relation_condition)
39
41
  end
40
42
 
41
- def apply_filter(dataset, schema=nil, primary_keys=[])
43
+ def apply_filter(environment, dataset, primary_keys)
42
44
  dataset.where(foreign_key => primary_keys)
43
45
  end
44
46
 
@@ -7,10 +7,10 @@ module Rasti
7
7
  @foreign_key ||= options[:foreign_key] || source_collection_class.foreign_key
8
8
  end
9
9
 
10
- def fetch_graph(rows, db, schema=nil, selected_attributes=nil, excluded_attributes=nil, relations_graph=nil)
10
+ def fetch_graph(environment, rows, selected_attributes=nil, excluded_attributes=nil, relations_graph=nil)
11
11
  pks = rows.map { |row| row[source_collection_class.primary_key] }.uniq
12
12
 
13
- target_collection = target_collection_class.new db, schema
13
+ target_collection = target_collection_class.new environment
14
14
 
15
15
  query = target_collection.where(foreign_key => pks)
16
16
  query = query.exclude_attributes(*excluded_attributes) if excluded_attributes
@@ -24,25 +24,33 @@ module Rasti
24
24
  end
25
25
  end
26
26
 
27
- def add_join(dataset, schema=nil, prefix=nil)
27
+ def add_join(environment, dataset, prefix=nil)
28
+ validate_join!
29
+
28
30
  relation_alias = join_relation_name prefix
29
31
 
30
- qualified_relation_source = prefix ? Sequel[prefix] : qualified_source_collection_name(schema)
32
+ relation_name = prefix ? Sequel[prefix] : Sequel[source_collection_class.collection_name]
31
33
 
32
34
  relation_condition = {
33
- Sequel[relation_alias][foreign_key] => qualified_relation_source[source_collection_class.primary_key]
35
+ Sequel[relation_alias][foreign_key] => relation_name[source_collection_class.primary_key]
34
36
  }
35
37
 
36
- dataset.join(qualified_target_collection_name(schema).as(relation_alias), relation_condition)
38
+ dataset.join(environment.qualify_collection(target_collection_class).as(relation_alias), relation_condition)
37
39
  end
38
40
 
39
- def apply_filter(dataset, schema=nil, primary_keys=[])
40
- target_name = qualified_target_collection_name schema
41
-
42
- dataset.join(target_name, foreign_key => source_collection_class.primary_key)
43
- .where(Sequel[target_name][target_collection_class.primary_key] => primary_keys)
44
- .select_all(qualified_source_collection_name(schema))
45
- .distinct
41
+ def apply_filter(environment, dataset, primary_keys)
42
+ if source_collection_class.data_source_name == target_collection_class.data_source_name
43
+ dataset.join(environment.qualify_collection(target_collection_class), foreign_key => source_collection_class.primary_key)
44
+ .where(Sequel[target_collection_class.collection_name][target_collection_class.primary_key] => primary_keys)
45
+ .select_all(target_collection_class.collection_name)
46
+ .distinct
47
+ else
48
+ target_collection = target_collection_class.new environment
49
+ fks = target_collection.where(target_collection_class.primary_key => primary_keys)
50
+ .pluck(foreign_key)
51
+ .uniq
52
+ dataset.where(source_collection_class.primary_key => fks)
53
+ end
46
54
  end
47
55
 
48
56
  private
@@ -0,0 +1,62 @@
1
+ module Rasti
2
+ module DB
3
+ module TypeConverters
4
+ class SQLite
5
+
6
+ CONVERTERS = [SQLiteTypes::Array]
7
+
8
+ @to_db_mapping = {}
9
+
10
+ class << self
11
+
12
+ def to_db(db, collection_name, attribute_name, value)
13
+ to_db_mapping = to_db_mapping_for db, collection_name
14
+
15
+ if to_db_mapping.key? attribute_name
16
+ to_db_mapping[attribute_name][:converter].to_db value
17
+ else
18
+ value
19
+ end
20
+ end
21
+
22
+ def from_db(object)
23
+ converter = find_converter_from_db object
24
+ if !converter.nil?
25
+ converter.from_db object
26
+ else
27
+ object
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def to_db_mapping_for(db, collection_name)
34
+ key = [db.opts[:database], collection_name]
35
+
36
+ @to_db_mapping[key] ||= begin
37
+ columns = Hash[db.schema(collection_name)]
38
+
39
+ columns.each_with_object({}) do |(name, schema), hash|
40
+ CONVERTERS.each do |converter|
41
+ unless hash.key? name
42
+ match = converter.column_type_regex.match schema[:db_type]
43
+
44
+ hash[name] = { converter: converter } if match
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def find_converter_from_db(object)
52
+ CONVERTERS.find do |converter|
53
+ converter.respond_for? object
54
+ end
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,34 @@
1
+ module Rasti
2
+ module DB
3
+ module TypeConverters
4
+ module SQLiteTypes
5
+ class Array
6
+
7
+ class << self
8
+
9
+ def column_type_regex
10
+ /^([a-z]+)\[\]$/
11
+ end
12
+
13
+ def to_db(values)
14
+ JSON.dump(values)
15
+ end
16
+
17
+ def respond_for?(object)
18
+ parsed = JSON.parse object
19
+ object == to_db(parsed)
20
+ rescue
21
+ false
22
+ end
23
+
24
+ def from_db(object)
25
+ JSON.parse object
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module Rasti
2
2
  module DB
3
- VERSION = '1.5.0'
3
+ VERSION = '2.3.0'
4
4
  end
5
5
  end
@@ -26,6 +26,7 @@ Gem::Specification.new do |spec|
26
26
  spec.add_runtime_dependency 'multi_require', '~> 1.0'
27
27
  spec.add_runtime_dependency 'hierarchical_graph', '~> 1.0'
28
28
  spec.add_runtime_dependency 'hash_ext', '~> 0.5'
29
+ spec.add_runtime_dependency 'inflecto', '~> 0.0'
29
30
 
30
31
  spec.add_development_dependency 'rake', '~> 12.3'
31
32
  spec.add_development_dependency 'minitest', '~> 5.0', '< 5.11'
@@ -2,6 +2,14 @@ require 'minitest_helper'
2
2
 
3
3
  describe 'Collection' do
4
4
 
5
+ before do
6
+ Rasti::DB.type_converters = [Rasti::DB::TypeConverters::TimeInZone]
7
+ end
8
+
9
+ after do
10
+ Rasti::DB.type_converters = [Rasti::DB::TypeConverters::TimeInZone, Rasti::DB::TypeConverters::SQLite]
11
+ end
12
+
5
13
  describe 'Specification' do
6
14
 
7
15
  it 'Implicit' do
@@ -10,6 +18,7 @@ describe 'Collection' do
10
18
  Users.model.must_equal User
11
19
  Users.primary_key.must_equal :id
12
20
  Users.foreign_key.must_equal :user_id
21
+ Users.data_source_name.must_equal :default
13
22
  end
14
23
 
15
24
  it 'Explicit' do
@@ -18,6 +27,8 @@ describe 'Collection' do
18
27
  People.model.must_equal Person
19
28
  People.primary_key.must_equal :document_number
20
29
  People.foreign_key.must_equal :document_number
30
+
31
+ Languages.data_source_name.must_equal :custom
21
32
  end
22
33
 
23
34
  it 'Lazy model name' do
@@ -42,11 +53,11 @@ describe 'Collection' do
42
53
  user_id = db[:users].insert name: 'User 1'
43
54
 
44
55
  1.upto(2) do |i|
45
- db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...'
56
+ db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...', language_id: 1
46
57
  db[:categories].insert name: "Category #{i}"
47
58
  end
48
59
 
49
- post_id = posts.insert user_id: user_id, title: 'Post title', body: '...', categories: [1,2]
60
+ post_id = posts.insert user_id: user_id, title: 'Post title', body: '...', categories: [1,2], language_id: 1
50
61
  category_id = categories.insert name: 'Category', posts: [1,2]
51
62
 
52
63
  db[:categories_posts].where(post_id: post_id).map(:category_id).must_equal [1,2]
@@ -59,7 +70,7 @@ describe 'Collection' do
59
70
  end
60
71
 
61
72
  user_id = db[:users].insert name: 'User 1'
62
- post_id = db[:posts].insert user_id: user_id, title: 'Post title', body: '...'
73
+ post_id = db[:posts].insert user_id: user_id, title: 'Post title', body: '...', language_id: 1
63
74
  1.upto(2) { |category_id| db[:categories_posts].insert post_id: post_id, category_id: category_id }
64
75
 
65
76
  posts.insert_relations post_id, categories: [3]
@@ -91,7 +102,7 @@ describe 'Collection' do
91
102
  user_id = db[:users].insert name: 'User 1'
92
103
 
93
104
  1.upto(3) do |i|
94
- db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...'
105
+ db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...', language_id: 1
95
106
  db[:categories].insert name: "Category #{i}"
96
107
  end
97
108
 
@@ -114,7 +125,7 @@ describe 'Collection' do
114
125
 
115
126
  it 'Bulk update' do
116
127
  user_id = db[:users].insert name: 'User 1'
117
- 1.upto(3) { |i| db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...' }
128
+ 1.upto(3) { |i| db[:posts].insert user_id: user_id, title: "Post #{i}", body: '...', language_id: 1 }
118
129
 
119
130
  posts.bulk_update(body: 'Updated ...') { where id: [1,2] }
120
131
 
@@ -139,7 +150,7 @@ describe 'Collection' do
139
150
  end
140
151
 
141
152
  user_id = db[:users].insert name: 'User 1'
142
- post_id = db[:posts].insert user_id: user_id, title: 'Post title', body: '...'
153
+ post_id = db[:posts].insert user_id: user_id, title: 'Post title', body: '...', language_id: 1
143
154
  1.upto(3) { |category_id| db[:categories_posts].insert post_id: post_id, category_id: category_id }
144
155
 
145
156
  posts.delete_relations post_id, categories: [3]
@@ -170,7 +181,7 @@ describe 'Collection' do
170
181
  category_id = db[:categories].insert name: "Category #{i}"
171
182
 
172
183
  1.upto(3) do |n|
173
- post_id = db[:posts].insert user_id: user_id, title: "Post #{i}.#{n}", body: '...'
184
+ post_id = db[:posts].insert user_id: user_id, title: "Post #{i}.#{n}", body: '...', language_id: 1
174
185
  db[:categories_posts].insert post_id: post_id, category_id: category_id
175
186
  end
176
187
  end
@@ -227,6 +238,65 @@ describe 'Collection' do
227
238
 
228
239
  end
229
240
 
241
+ describe 'Multiple data sources' do
242
+
243
+ before do
244
+ 1.upto(3) do |i|
245
+ db[:users].insert name: "User #{i}"
246
+ db[:people].insert document_number: "document_#{i}",
247
+ first_name: "John #{i}",
248
+ last_name: "Doe #{i}",
249
+ birth_date: Time.now - i,
250
+ user_id: i
251
+ end
252
+ end
253
+
254
+ it 'Insert' do
255
+ id = languages.insert name: 'Spanish', people: ['document_1', 'document_2']
256
+
257
+ custom_db[:languages][id: id][:name].must_equal 'Spanish'
258
+ db[:languages_people].where(language_id: id).select_map(:document_number).must_equal ['document_1', 'document_2']
259
+ end
260
+
261
+ it 'Update' do
262
+ id = custom_db[:languages].insert name: 'Spanish'
263
+ db[:languages_people].insert language_id: id, document_number: 'document_1'
264
+
265
+ custom_db[:languages][id: id][:name].must_equal 'Spanish'
266
+ db[:languages_people].where(language_id: id).select_map(:document_number).must_equal ['document_1']
267
+
268
+ languages.update id, name: 'English', people: ['document_2', 'document_3']
269
+
270
+ custom_db[:languages][id: id][:name].must_equal 'English'
271
+ db[:languages_people].where(language_id: id).select_map(:document_number).must_equal ['document_2', 'document_3']
272
+ end
273
+
274
+ it 'Delete' do
275
+ id = custom_db[:languages].insert name: 'Spanish'
276
+ db[:languages_people].insert language_id: id, document_number: 'document_1'
277
+ db[:posts].insert user_id: 1, title: 'Post 1', body: '...', language_id: id
278
+
279
+ languages.delete id
280
+
281
+ custom_db[:languages].count.must_equal 0
282
+ db[:languages_people].where(language_id: id).count.must_equal 1
283
+ db[:posts].where(language_id: id).count.must_equal 1
284
+ end
285
+
286
+ it 'Delete cascade' do
287
+ id = custom_db[:languages].insert name: 'Spanish'
288
+ db[:languages_people].insert language_id: id, document_number: 'document_1'
289
+ db[:posts].insert user_id: 1, title: 'Post 1', body: '...', language_id: id
290
+
291
+ languages.delete_cascade id
292
+
293
+ custom_db[:languages].count.must_equal 0
294
+ db[:languages_people].where(language_id: id).count.must_equal 0
295
+ db[:posts].where(language_id: id).count.must_equal 0
296
+ end
297
+
298
+ end
299
+
230
300
  end
231
301
 
232
302
  describe 'Queries' do
@@ -239,7 +309,7 @@ describe 'Collection' do
239
309
 
240
310
  it 'Find graph' do
241
311
  user_id = db[:users].insert name: 'User 1'
242
- db[:posts].insert user_id: user_id, title: 'Post 1', body: '...'
312
+ db[:posts].insert user_id: user_id, title: 'Post 1', body: '...', language_id: 1
243
313
 
244
314
  users.find_graph(user_id, :posts).must_equal User.new id: user_id, name: 'User 1', posts: posts.all
245
315
  end
@@ -316,42 +386,51 @@ describe 'Collection' do
316
386
 
317
387
  it 'Chain dataset as query' do
318
388
  1.upto(2) { |i| db[:users].insert name: "User #{i}" }
319
- 1.upto(3) { |i| db[:posts].insert user_id: 1, title: "Post #{i}", body: '...' }
389
+ 1.upto(3) { |i| db[:posts].insert user_id: 1, title: "Post #{i}", body: '...', language_id: 1 }
320
390
  1.upto(2) { |i| db[:comments].insert post_id: i, user_id: 2, text: 'Comment' }
321
391
 
322
392
  models = posts.commented_by(2).all
323
- models.must_equal [1,2].map { |i| Post.new(id: i, user_id: 1, title: "Post #{i}", body: '...') }
393
+ models.must_equal [1,2].map { |i| Post.new(id: i, user_id: 1, title: "Post #{i}", body: '...', language_id: 1) }
324
394
  end
325
395
 
326
396
  it 'Custom query' do
327
397
  1.upto(2) { |i| db[:users].insert name: "User #{i}" }
328
- 1.upto(3) { |i| db[:posts].insert user_id: 1, title: "Post #{i}", body: '...' }
398
+ 1.upto(3) { |i| db[:posts].insert user_id: 1, title: "Post #{i}", body: '...', language_id: 1 }
329
399
  1.upto(2) { |i| db[:comments].insert post_id: i, user_id: 2, text: 'Comment' }
330
400
 
331
401
  models = comments.posts_commented_by(2)
332
- models.must_equal [1,2].map { |i| Post.new(id: i, user_id: 1, title: "Post #{i}", body: '...') }
402
+ models.must_equal [1,2].map { |i| Post.new(id: i, user_id: 1, title: "Post #{i}", body: '...', language_id: 1) }
333
403
  end
334
404
 
335
405
  describe 'Named queries' do
336
406
 
337
407
  before do
408
+ custom_db[:languages].insert name: 'Spanish'
409
+ custom_db[:languages].insert name: 'English'
410
+
338
411
  1.upto(2) do |i|
339
412
  db[:categories].insert name: "Category #{i}"
413
+
340
414
  db[:users].insert name: "User #{i}"
415
+
341
416
  db[:people].insert document_number: "document_#{i}",
342
417
  first_name: "John #{i}",
343
418
  last_name: "Doe #{i}",
344
419
  birth_date: Time.now - i,
345
420
  user_id: i
421
+
346
422
  end
347
423
 
424
+ db[:languages_people].insert language_id: 1, document_number: 'document_1'
425
+ db[:languages_people].insert language_id: 2, document_number: 'document_2'
426
+
348
427
  1.upto(3) do |i|
349
- db[:posts].insert user_id: 1, title: "Post #{i}", body: '...'
428
+ db[:posts].insert user_id: 1, title: "Post #{i}", body: '...', language_id: 1
350
429
  db[:categories_posts].insert category_id: 1, post_id: i
351
430
  end
352
431
 
353
432
  4.upto(5) do |i|
354
- db[:posts].insert user_id: 2, title: "Post #{i}", body: '...'
433
+ db[:posts].insert user_id: 2, title: "Post #{i}", body: '...', language_id: 2
355
434
  db[:categories_posts].insert category_id: 2, post_id: i
356
435
  end
357
436
  end
@@ -374,6 +453,23 @@ describe 'Collection' do
374
453
  users.with_people('document_1').primary_keys.must_equal [1]
375
454
  end
376
455
 
456
+ describe 'Multiple data sources' do
457
+
458
+ it 'One to many' do
459
+ languages.with_posts([1,2]).primary_keys.must_equal [1]
460
+ end
461
+
462
+ it 'Many to one' do
463
+ posts.with_languages([2]).primary_keys.must_equal [4,5]
464
+ end
465
+
466
+ it 'Many to Many' do
467
+ languages.with_people(['document_1']).primary_keys.must_equal [1]
468
+ people.with_languages([2]).primary_keys.must_equal ['document_2']
469
+ end
470
+
471
+ end
472
+
377
473
  end
378
474
 
379
475
  it 'Global' do
@@ -400,7 +496,7 @@ describe 'Collection' do
400
496
  birth_date: Time.now - i,
401
497
  user_id: i
402
498
  db[:categories].insert name: "Category #{i}"
403
- db[:posts].insert user_id: i, title: "Post #{i}", body: '...'
499
+ db[:posts].insert user_id: i, title: "Post #{i}", body: '...', language_id: 1
404
500
  db[:categories_posts].insert post_id: i, category_id: i
405
501
  end
406
502
 
@@ -448,21 +544,21 @@ describe 'Collection' do
448
544
  stubs = Proc.new do |sql|
449
545
  case sql
450
546
 
451
- when 'SELECT users.* FROM custom_schema.users',
452
- 'SELECT users.* FROM custom_schema.users WHERE (id IN (2, 1))'
547
+ when 'SELECT users.* FROM schema_1.users',
548
+ 'SELECT users.* FROM schema_1.users WHERE (users.id IN (2, 1))'
453
549
  [
454
550
  {id: 1},
455
551
  {id: 2}
456
552
  ]
457
553
 
458
- when 'SELECT posts.* FROM custom_schema.posts',
459
- 'SELECT posts.* FROM custom_schema.posts WHERE (user_id IN (1, 2))'
554
+ when 'SELECT posts.* FROM schema_1.posts',
555
+ 'SELECT posts.* FROM schema_1.posts WHERE (posts.user_id IN (1, 2))'
460
556
  [
461
- {id: 3, user_id: 1},
462
- {id: 4, user_id: 2}
557
+ {id: 3, user_id: 1, language_id: 1},
558
+ {id: 4, user_id: 2, language_id: 2}
463
559
  ]
464
560
 
465
- when 'SELECT comments.* FROM custom_schema.comments WHERE (post_id IN (3, 4))'
561
+ when 'SELECT comments.* FROM schema_1.comments WHERE (comments.post_id IN (3, 4))'
466
562
  [
467
563
  {id: 5, user_id: 2, post_id: 3},
468
564
  {id: 6, user_id: 1, post_id: 3},
@@ -470,88 +566,152 @@ describe 'Collection' do
470
566
  {id: 8, user_id: 2, post_id: 4}
471
567
  ]
472
568
 
473
- else
474
- nil
569
+ when 'SELECT languages.* FROM schema_2.languages WHERE (languages.id IN (1, 2))'
570
+ [
571
+ {id: 1},
572
+ {id: 2}
573
+ ]
574
+
475
575
  end
476
576
  end
477
577
 
478
- Sequel.mock(fetch: stubs, autoid: 1).tap do |mock|
479
- get_schema_block = ->(table_name) { db.schema table_name }
480
- mock.define_singleton_method(:schema_parse_table) do |table_name, opts|
481
- get_schema_block.call table_name
578
+ last_id = 0
579
+ autoid = Proc.new do |sql|
580
+ case sql
581
+ when "INSERT INTO schema_1.people (document_number, first_name, last_name, birth_date, user_id) VALUES ('document_1', 'John', 'Doe', '2020-04-24 00:00:00.000000', 1)"
582
+ 'document_1'
583
+ else
584
+ last_id += 1
482
585
  end
483
586
  end
587
+
588
+ Sequel.mock fetch: stubs, autoid: autoid
484
589
  end
485
590
 
486
- let(:stub_users) { Users.new stub_db, :custom_schema }
487
- let(:stub_posts) { Posts.new stub_db, :custom_schema }
488
- let(:stub_comments) { Comments.new stub_db, :custom_schema }
591
+ let :stub_environment do
592
+ Rasti::DB::Environment.new default: Rasti::DB::DataSource.new(stub_db, :schema_1),
593
+ custom: Rasti::DB::DataSource.new(stub_db, :schema_2)
594
+ end
595
+
596
+ let(:stub_users) { Users.new stub_environment }
597
+ let(:stub_posts) { Posts.new stub_environment }
598
+ let(:stub_comments) { Comments.new stub_environment }
599
+ let(:stub_people) { People.new stub_environment }
600
+ let(:stub_languages) { Languages.new stub_environment }
489
601
 
490
602
  it 'Insert' do
491
603
  stub_users.insert name: 'User 1'
604
+
492
605
  stub_db.sqls.must_equal [
493
606
  'BEGIN',
494
- "INSERT INTO custom_schema.users (name) VALUES ('User 1')",
607
+ "INSERT INTO schema_1.users (name) VALUES ('User 1')",
495
608
  'COMMIT'
496
609
  ]
497
610
  end
498
611
 
499
612
  it 'Insert with many to many relation' do
500
- stub_posts.insert user_id: 1, title: 'Post 1', body: '...', categories: [2,3]
613
+ stub_posts.insert user_id: 1, title: 'Post 1', body: '...', categories: [2,3], language_id: 1
614
+
615
+ stub_db.sqls.must_equal [
616
+ 'BEGIN',
617
+ "INSERT INTO schema_1.posts (user_id, title, body, language_id) VALUES (1, 'Post 1', '...', 1)",
618
+ 'DELETE FROM schema_1.categories_posts WHERE (post_id IN (1))',
619
+ 'INSERT INTO schema_1.categories_posts (post_id, category_id) VALUES (1, 2)',
620
+ 'INSERT INTO schema_1.categories_posts (post_id, category_id) VALUES (1, 3)',
621
+ 'COMMIT'
622
+ ]
623
+ end
624
+
625
+ it 'Insert in multiple schemas' do
626
+ stub_languages.insert name: 'Spanish'
627
+
628
+ stub_users.insert name: 'User 1'
629
+
630
+ stub_people.insert document_number: 'document_1',
631
+ first_name: 'John',
632
+ last_name: 'Doe',
633
+ birth_date: Time.parse('2020-04-24'),
634
+ user_id: 1,
635
+ languages: [1]
636
+
501
637
  stub_db.sqls.must_equal [
502
638
  'BEGIN',
503
- "INSERT INTO custom_schema.posts (user_id, title, body) VALUES (1, 'Post 1', '...')",
504
- 'DELETE FROM custom_schema.categories_posts WHERE (post_id IN (1))',
505
- 'INSERT INTO custom_schema.categories_posts (post_id, category_id) VALUES (1, 2)',
506
- 'INSERT INTO custom_schema.categories_posts (post_id, category_id) VALUES (1, 3)',
639
+ "INSERT INTO schema_2.languages (name) VALUES ('Spanish')",
640
+ 'COMMIT',
641
+ 'BEGIN',
642
+ "INSERT INTO schema_1.users (name) VALUES ('User 1')",
643
+ 'COMMIT',
644
+ 'BEGIN',
645
+ "INSERT INTO schema_1.people (document_number, first_name, last_name, birth_date, user_id) VALUES ('document_1', 'John', 'Doe', '2020-04-24 00:00:00.000000', 1)",
646
+ "DELETE FROM schema_1.languages_people WHERE (document_number IN ('document_1'))",
647
+ "INSERT INTO schema_1.languages_people (document_number, language_id) VALUES ('document_1', 1)",
507
648
  'COMMIT'
508
649
  ]
509
650
  end
510
651
 
511
652
  it 'Update' do
512
653
  stub_users.update 1, name: 'Updated name'
654
+
513
655
  stub_db.sqls.must_equal [
514
656
  'BEGIN',
515
- "UPDATE custom_schema.users SET name = 'Updated name' WHERE (id = 1)",
657
+ "UPDATE schema_1.users SET name = 'Updated name' WHERE (id = 1)",
516
658
  'COMMIT'
517
659
  ]
518
660
  end
519
661
 
520
662
  it 'Delete' do
521
663
  stub_users.delete 1
522
- stub_db.sqls.must_equal ['DELETE FROM custom_schema.users WHERE (id = 1)']
664
+
665
+ stub_db.sqls.must_equal [
666
+ 'DELETE FROM schema_1.users WHERE (id = 1)'
667
+ ]
523
668
  end
524
669
 
525
670
  it 'Chained query' do
526
671
  stub_users.where(id: [1,2]).limit(1).order(:name).all
527
- stub_db.sqls.must_equal ['SELECT users.* FROM custom_schema.users WHERE (id IN (1, 2)) ORDER BY name LIMIT 1']
672
+
673
+ stub_db.sqls.must_equal [
674
+ 'SELECT users.* FROM schema_1.users WHERE (users.id IN (1, 2)) ORDER BY users.name LIMIT 1'
675
+ ]
528
676
  end
529
677
 
530
678
  it 'Graph' do
531
- stub_posts.graph(:user, :categories, 'comments.user.posts.categories').all
679
+ stub_posts.graph(:user, :categories, 'comments.user.posts.categories', 'language.people').all
532
680
 
533
681
  stub_db.sqls.must_equal [
534
- 'SELECT posts.* FROM custom_schema.posts',
535
- 'SELECT categories.*, custom_schema.categories_posts.post_id AS source_foreign_key FROM custom_schema.categories INNER JOIN custom_schema.categories_posts ON (custom_schema.categories_posts.category_id = custom_schema.categories.id) WHERE (custom_schema.categories_posts.post_id IN (3, 4))',
536
- 'SELECT comments.* FROM custom_schema.comments WHERE (post_id IN (3, 4))',
537
- 'SELECT users.* FROM custom_schema.users WHERE (id IN (2, 1))',
538
- 'SELECT posts.* FROM custom_schema.posts WHERE (user_id IN (1, 2))',
539
- 'SELECT categories.*, custom_schema.categories_posts.post_id AS source_foreign_key FROM custom_schema.categories INNER JOIN custom_schema.categories_posts ON (custom_schema.categories_posts.category_id = custom_schema.categories.id) WHERE (custom_schema.categories_posts.post_id IN (3, 4))',
540
- 'SELECT users.* FROM custom_schema.users WHERE (id IN (1, 2))'
682
+ 'SELECT posts.* FROM schema_1.posts',
683
+ 'SELECT categories.*, categories_posts.post_id AS source_foreign_key FROM schema_1.categories INNER JOIN schema_1.categories_posts ON (schema_1.categories_posts.category_id = schema_1.categories.id) WHERE (categories_posts.post_id IN (3, 4))',
684
+ 'SELECT comments.* FROM schema_1.comments WHERE (comments.post_id IN (3, 4))',
685
+ 'SELECT users.* FROM schema_1.users WHERE (users.id IN (2, 1))',
686
+ 'SELECT posts.* FROM schema_1.posts WHERE (posts.user_id IN (1, 2))',
687
+ 'SELECT categories.*, categories_posts.post_id AS source_foreign_key FROM schema_1.categories INNER JOIN schema_1.categories_posts ON (schema_1.categories_posts.category_id = schema_1.categories.id) WHERE (categories_posts.post_id IN (3, 4))',
688
+ 'SELECT languages.* FROM schema_2.languages WHERE (languages.id IN (1, 2))',
689
+ 'SELECT people.*, languages_people.language_id AS source_foreign_key FROM schema_1.people INNER JOIN schema_1.languages_people ON (schema_1.languages_people.document_number = schema_1.people.document_number) WHERE (languages_people.language_id IN (1, 2))',
690
+ 'SELECT users.* FROM schema_1.users WHERE (users.id IN (1, 2))'
691
+ ]
692
+ end
693
+
694
+ it 'Join' do
695
+ stub_posts.join('user.person').where(document_number: 'document_1').all
696
+
697
+ stub_db.sqls.must_equal [
698
+ "SELECT DISTINCT posts.* FROM schema_1.posts INNER JOIN schema_1.users AS user ON (user.id = posts.user_id) INNER JOIN schema_1.people AS user__person ON (user__person.user_id = user.id) WHERE (posts.document_number = 'document_1')"
541
699
  ]
542
700
  end
543
701
 
544
702
  it 'Named query' do
545
703
  stub_posts.commented_by(1).all
704
+
546
705
  stub_db.sqls.must_equal [
547
- 'SELECT DISTINCT posts.* FROM custom_schema.posts INNER JOIN custom_schema.comments ON (custom_schema.comments.post_id = custom_schema.posts.id) WHERE (custom_schema.comments.user_id = 1)'
706
+ 'SELECT DISTINCT posts.* FROM schema_1.posts INNER JOIN schema_1.comments ON (schema_1.comments.post_id = schema_1.posts.id) WHERE (comments.user_id = 1)'
548
707
  ]
549
708
  end
550
709
 
551
710
  it 'Custom query' do
552
711
  stub_comments.posts_commented_by(2)
712
+
553
713
  stub_db.sqls.must_equal [
554
- 'SELECT posts.* FROM custom_schema.comments INNER JOIN custom_schema.posts ON (custom_schema.posts.id = custom_schema.comments.post_id) WHERE (comments.user_id = 2)'
714
+ 'SELECT posts.* FROM schema_1.comments INNER JOIN schema_1.posts ON (schema_1.posts.id = schema_1.comments.post_id) WHERE (comments.user_id = 2)'
555
715
  ]
556
716
  end
557
717