rasti-db 1.5.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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