rom-sql 2.0.0.beta2 → 2.0.0.beta3

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 (170) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/lib/rom/plugins/relation/sql/postgres/explain.rb +54 -0
  4. data/lib/rom/sql.rb +1 -1
  5. data/lib/rom/sql/attribute.rb +17 -18
  6. data/lib/rom/sql/errors.rb +3 -0
  7. data/lib/rom/sql/extensions/mysql.rb +1 -1
  8. data/lib/rom/sql/extensions/mysql/type_builder.rb +28 -0
  9. data/lib/rom/sql/extensions/postgres.rb +3 -1
  10. data/lib/rom/sql/extensions/postgres/commands.rb +30 -13
  11. data/lib/rom/sql/extensions/postgres/{attributes_inferrer.rb → type_builder.rb} +24 -28
  12. data/lib/rom/sql/extensions/postgres/type_serializer.rb +39 -0
  13. data/lib/rom/sql/extensions/postgres/types.rb +24 -477
  14. data/lib/rom/sql/extensions/postgres/types/array.rb +163 -0
  15. data/lib/rom/sql/extensions/postgres/types/geometric.rb +135 -0
  16. data/lib/rom/sql/extensions/postgres/types/json.rb +235 -0
  17. data/lib/rom/sql/extensions/postgres/types/network.rb +15 -0
  18. data/lib/rom/sql/extensions/sqlite.rb +1 -1
  19. data/lib/rom/sql/extensions/sqlite/{attributes_inferrer.rb → type_builder.rb} +5 -5
  20. data/lib/rom/sql/extensions/sqlite/types.rb +8 -3
  21. data/lib/rom/sql/foreign_key.rb +17 -0
  22. data/lib/rom/sql/function.rb +86 -8
  23. data/lib/rom/sql/gateway.rb +26 -26
  24. data/lib/rom/sql/index.rb +4 -0
  25. data/lib/rom/sql/migration.rb +3 -3
  26. data/lib/rom/sql/migration/inline_runner.rb +9 -83
  27. data/lib/rom/sql/migration/migrator.rb +35 -12
  28. data/lib/rom/sql/migration/recorder.rb +21 -0
  29. data/lib/rom/sql/migration/runner.rb +115 -0
  30. data/lib/rom/sql/migration/schema_diff.rb +108 -53
  31. data/lib/rom/sql/migration/writer.rb +61 -0
  32. data/lib/rom/sql/relation.rb +2 -1
  33. data/lib/rom/sql/relation/reading.rb +63 -3
  34. data/lib/rom/sql/relation/writing.rb +38 -0
  35. data/lib/rom/sql/schema.rb +9 -3
  36. data/lib/rom/sql/schema/attributes_inferrer.rb +3 -119
  37. data/lib/rom/sql/schema/inferrer.rb +99 -18
  38. data/lib/rom/sql/schema/type_builder.rb +94 -0
  39. data/lib/rom/sql/type_dsl.rb +30 -0
  40. data/lib/rom/sql/type_extensions.rb +11 -6
  41. data/lib/rom/sql/type_serializer.rb +46 -0
  42. data/lib/rom/sql/types.rb +12 -0
  43. data/lib/rom/sql/version.rb +1 -1
  44. metadata +26 -244
  45. data/.codeclimate.yml +0 -15
  46. data/.gitignore +0 -17
  47. data/.rspec +0 -3
  48. data/.travis.yml +0 -39
  49. data/.yardopts +0 -2
  50. data/Gemfile +0 -33
  51. data/Guardfile +0 -24
  52. data/LICENSE.txt +0 -22
  53. data/Rakefile +0 -19
  54. data/circle.yml +0 -10
  55. data/lib/rom/sql/extensions/mysql/attributes_inferrer.rb +0 -10
  56. data/lib/rom/sql/relation/sequel_api.rb +0 -133
  57. data/log/.gitkeep +0 -0
  58. data/rom-sql.gemspec +0 -29
  59. data/spec/extensions/postgres/attribute_spec.rb +0 -217
  60. data/spec/extensions/postgres/integration_spec.rb +0 -59
  61. data/spec/extensions/postgres/types_spec.rb +0 -252
  62. data/spec/extensions/sqlite/types_spec.rb +0 -11
  63. data/spec/fixtures/migrations/20150403090603_create_carrots.rb +0 -8
  64. data/spec/integration/associations/many_to_many/custom_fks_spec.rb +0 -76
  65. data/spec/integration/associations/many_to_many/from_view_spec.rb +0 -88
  66. data/spec/integration/associations/many_to_many_spec.rb +0 -162
  67. data/spec/integration/associations/many_to_one/custom_fks_spec.rb +0 -64
  68. data/spec/integration/associations/many_to_one/from_view_spec.rb +0 -84
  69. data/spec/integration/associations/many_to_one/self_ref_spec.rb +0 -53
  70. data/spec/integration/associations/many_to_one_spec.rb +0 -117
  71. data/spec/integration/associations/one_to_many/custom_fks_spec.rb +0 -54
  72. data/spec/integration/associations/one_to_many/from_view_spec.rb +0 -57
  73. data/spec/integration/associations/one_to_many/self_ref_spec.rb +0 -54
  74. data/spec/integration/associations/one_to_many_spec.rb +0 -86
  75. data/spec/integration/associations/one_to_one_spec.rb +0 -69
  76. data/spec/integration/associations/one_to_one_through_spec.rb +0 -92
  77. data/spec/integration/auto_migrations/errors_spec.rb +0 -31
  78. data/spec/integration/auto_migrations/indexes_spec.rb +0 -253
  79. data/spec/integration/auto_migrations/managing_columns_spec.rb +0 -156
  80. data/spec/integration/auto_migrations/postgres/column_types_spec.rb +0 -63
  81. data/spec/integration/combine_with_spec.rb +0 -43
  82. data/spec/integration/commands/create_spec.rb +0 -304
  83. data/spec/integration/commands/delete_spec.rb +0 -84
  84. data/spec/integration/commands/update_spec.rb +0 -90
  85. data/spec/integration/commands/upsert_spec.rb +0 -83
  86. data/spec/integration/gateway_spec.rb +0 -107
  87. data/spec/integration/migration_spec.rb +0 -55
  88. data/spec/integration/plugins/associates/many_to_many_spec.rb +0 -69
  89. data/spec/integration/plugins/associates_spec.rb +0 -250
  90. data/spec/integration/plugins/auto_restrictions_spec.rb +0 -74
  91. data/spec/integration/relation_schema_spec.rb +0 -271
  92. data/spec/integration/schema/call_spec.rb +0 -24
  93. data/spec/integration/schema/inferrer/mysql_spec.rb +0 -45
  94. data/spec/integration/schema/inferrer/postgres_spec.rb +0 -203
  95. data/spec/integration/schema/inferrer/sqlite_spec.rb +0 -37
  96. data/spec/integration/schema/inferrer_spec.rb +0 -390
  97. data/spec/integration/schema/prefix_spec.rb +0 -16
  98. data/spec/integration/schema/qualified_spec.rb +0 -16
  99. data/spec/integration/schema/rename_spec.rb +0 -21
  100. data/spec/integration/schema/view_spec.rb +0 -29
  101. data/spec/integration/sequel_api_spec.rb +0 -36
  102. data/spec/integration/setup_spec.rb +0 -26
  103. data/spec/integration/support/active_support_notifications_spec.rb +0 -24
  104. data/spec/integration/support/rails_log_subscriber_spec.rb +0 -30
  105. data/spec/integration/wrap_spec.rb +0 -91
  106. data/spec/shared/accounts.rb +0 -48
  107. data/spec/shared/database_setup.rb +0 -70
  108. data/spec/shared/notes.rb +0 -23
  109. data/spec/shared/posts.rb +0 -34
  110. data/spec/shared/puppies.rb +0 -15
  111. data/spec/shared/relations.rb +0 -8
  112. data/spec/shared/users.rb +0 -32
  113. data/spec/shared/users_and_tasks.rb +0 -50
  114. data/spec/spec_helper.rb +0 -122
  115. data/spec/support/env_helper.rb +0 -25
  116. data/spec/support/helpers.rb +0 -24
  117. data/spec/support/oracle/create_users.sql +0 -7
  118. data/spec/support/oracle/set_sys_passwords.sql +0 -2
  119. data/spec/support/test_configuration.rb +0 -16
  120. data/spec/unit/attribute_spec.rb +0 -104
  121. data/spec/unit/function_spec.rb +0 -48
  122. data/spec/unit/gateway_spec.rb +0 -70
  123. data/spec/unit/logger_spec.rb +0 -14
  124. data/spec/unit/migration_tasks_spec.rb +0 -111
  125. data/spec/unit/migrator_spec.rb +0 -25
  126. data/spec/unit/order_dsl_spec.rb +0 -43
  127. data/spec/unit/plugin/associates_spec.rb +0 -94
  128. data/spec/unit/plugin/pagination_spec.rb +0 -91
  129. data/spec/unit/plugin/timestamp_spec.rb +0 -117
  130. data/spec/unit/projection_dsl_spec.rb +0 -110
  131. data/spec/unit/relation/assoc_spec.rb +0 -87
  132. data/spec/unit/relation/associations_spec.rb +0 -27
  133. data/spec/unit/relation/avg_spec.rb +0 -11
  134. data/spec/unit/relation/by_pk_spec.rb +0 -62
  135. data/spec/unit/relation/dataset_spec.rb +0 -50
  136. data/spec/unit/relation/distinct_spec.rb +0 -15
  137. data/spec/unit/relation/exclude_spec.rb +0 -11
  138. data/spec/unit/relation/exist_predicate_spec.rb +0 -25
  139. data/spec/unit/relation/exists_spec.rb +0 -18
  140. data/spec/unit/relation/fetch_spec.rb +0 -21
  141. data/spec/unit/relation/group_spec.rb +0 -61
  142. data/spec/unit/relation/having_spec.rb +0 -22
  143. data/spec/unit/relation/inner_join_spec.rb +0 -158
  144. data/spec/unit/relation/inspect_spec.rb +0 -11
  145. data/spec/unit/relation/instrument_spec.rb +0 -45
  146. data/spec/unit/relation/invert_spec.rb +0 -11
  147. data/spec/unit/relation/left_join_spec.rb +0 -55
  148. data/spec/unit/relation/lock_spec.rb +0 -93
  149. data/spec/unit/relation/map_spec.rb +0 -16
  150. data/spec/unit/relation/max_spec.rb +0 -11
  151. data/spec/unit/relation/min_spec.rb +0 -11
  152. data/spec/unit/relation/order_spec.rb +0 -51
  153. data/spec/unit/relation/pluck_spec.rb +0 -11
  154. data/spec/unit/relation/prefix_spec.rb +0 -29
  155. data/spec/unit/relation/primary_key_spec.rb +0 -27
  156. data/spec/unit/relation/project_spec.rb +0 -24
  157. data/spec/unit/relation/qualified_columns_spec.rb +0 -30
  158. data/spec/unit/relation/qualified_spec.rb +0 -25
  159. data/spec/unit/relation/read_spec.rb +0 -25
  160. data/spec/unit/relation/rename_spec.rb +0 -23
  161. data/spec/unit/relation/right_join_spec.rb +0 -57
  162. data/spec/unit/relation/select_append_spec.rb +0 -21
  163. data/spec/unit/relation/select_spec.rb +0 -40
  164. data/spec/unit/relation/sum_spec.rb +0 -11
  165. data/spec/unit/relation/union_spec.rb +0 -19
  166. data/spec/unit/relation/unique_predicate_spec.rb +0 -18
  167. data/spec/unit/relation/where_spec.rb +0 -133
  168. data/spec/unit/restriction_dsl_spec.rb +0 -34
  169. data/spec/unit/schema_spec.rb +0 -25
  170. data/spec/unit/types_spec.rb +0 -65
@@ -1,93 +0,0 @@
1
- require 'concurrent/atomic/count_down_latch'
2
-
3
- RSpec.describe ROM::Relation, '#lock' do
4
- include_context 'users and tasks'
5
-
6
- subject(:relation) { users }
7
-
8
- def lock_style(relation)
9
- relation.dataset.opts.fetch(:lock)
10
- end
11
-
12
- context 'with hitting the database' do
13
- let(:latch) { Concurrent::CountDownLatch.new }
14
-
15
- let(:timeout) { (defined? JRUBY_VERSION) ? 2 : 0.2 }
16
-
17
- let!(:start) { Time.now }
18
-
19
- def elapsed_time
20
- Time.now.to_f - start.to_f
21
- end
22
-
23
- with_adapters :postgres, :mysql, :oracle do
24
- it 'locks rows for update' do
25
- Thread.new do
26
- relation.lock do |rel|
27
- latch.count_down
28
-
29
- sleep timeout
30
- end
31
- end
32
-
33
- latch.wait
34
-
35
- expect(elapsed_time).to be < timeout
36
-
37
- relation.lock.to_a
38
-
39
- expect(elapsed_time).to be > timeout
40
- end
41
- end
42
- end
43
-
44
- with_adapters :postgres, :mysql, :oracle do
45
- it 'selects rows for update' do
46
- expect(lock_style(relation.lock)).to eql('FOR UPDATE')
47
- end
48
-
49
- it 'locks without wait' do
50
- expect(lock_style(relation.lock(wait: false))).to eql('FOR UPDATE NOWAIT')
51
- end
52
-
53
- it 'skips locked rows' do
54
- expect(lock_style(relation.lock(skip_locked: true))).to eql('FOR UPDATE SKIP LOCKED')
55
- end
56
-
57
- it 'raises an exception on attempt to use NOWAIT/WAIT with SKIP LOCKED' do
58
- expect { relation.lock(wait: false, skip_locked: true) }
59
- .to raise_error(ArgumentError, /cannot be used/)
60
- end
61
- end
62
-
63
- with_adapters :postgres do
64
- it 'locks with UPDATE OF' do
65
- expect(lock_style(relation.lock(of: :users))).to eql('FOR UPDATE OF users')
66
- expect(lock_style(relation.lock(of: :users, skip_locked: true))).to eql('FOR UPDATE OF users SKIP LOCKED')
67
- end
68
-
69
- it 'locks rows in different modes' do
70
- expect(lock_style(relation.lock(mode: :update))).to eql('FOR UPDATE')
71
- expect(lock_style(relation.lock(mode: :no_key_update))).to eql('FOR NO KEY UPDATE')
72
- expect(lock_style(relation.lock(mode: :share))).to eql('FOR SHARE')
73
- expect(lock_style(relation.lock(mode: :key_share))).to eql('FOR KEY SHARE')
74
- end
75
- end
76
-
77
- with_adapters :mysql do
78
- it 'locks rows in the SHARE mode' do
79
- expect(lock_style(relation.lock(mode: :share))).to eql('LOCK IN SHARE MODE')
80
- end
81
- end
82
-
83
- with_adapters :oracle do
84
- it 'locks with timeout' do
85
- expect(lock_style(relation.lock(wait: 10))).to eql('FOR UPDATE WAIT 10')
86
- end
87
-
88
- it 'locks with UPDATE OF' do
89
- expect(lock_style(relation.lock(of: :name))).to eql('FOR UPDATE OF name')
90
- expect(lock_style(relation.lock(of: %i(id name)))).to eql('FOR UPDATE OF id, name')
91
- end
92
- end
93
- end
@@ -1,16 +0,0 @@
1
- RSpec.describe ROM::Relation, '#map' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users and tasks'
5
-
6
- with_adapters do
7
- it 'yields tuples' do
8
- result = relation.map { |tuple| tuple[:name] }
9
- expect(result).to eql(%w(Jane Joe))
10
- end
11
-
12
- it 'plucks value' do
13
- expect(relation.map(:name)).to eql(%w(Jane Joe))
14
- end
15
- end
16
- end
@@ -1,11 +0,0 @@
1
- RSpec.describe ROM::Relation, '#max' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users'
5
-
6
- with_adapters do
7
- it 'delegates to dataset and return value' do
8
- expect(relation.max(:id)).to eql(2)
9
- end
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- RSpec.describe ROM::Relation, '#min' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users and tasks'
5
-
6
- with_adapters do
7
- it 'returns a min' do
8
- expect(relation.min(:id)).to eql(1)
9
- end
10
- end
11
- end
@@ -1,51 +0,0 @@
1
- RSpec.describe ROM::Relation, '#order' do
2
- subject(:relation) { relations[:users] }
3
-
4
- include_context 'users and tasks'
5
-
6
- before do
7
- relation.insert(id: 3, name: 'Jade')
8
- end
9
-
10
- with_adapters do
11
- it 'orders by provided attribute names' do
12
- ordered = relation.order(:name, :id)
13
-
14
- expect(ordered.to_a).
15
- to eql([{ id: 3, name: 'Jade' }, { id: 1, name: 'Jane' }, { id: 2, name: 'Joe' }])
16
- end
17
-
18
- it 'orders by provided attribute using a block' do
19
- ordered = relation.
20
- qualified.
21
- select(:id, :name).
22
- left_join(:tasks, user_id: :id).
23
- order { name.qualified.desc }
24
-
25
- expect(ordered.to_a).
26
- to eql([{ id: 2, name: 'Joe' }, { id: 1, name: 'Jane' }, { id: 3, name: 'Jade' }])
27
- end
28
-
29
- it 'orders by provided attributes using a block' do
30
- ordered = relation.
31
- qualified.
32
- select(:id, :name).
33
- left_join(:tasks, user_id: :id).
34
- order { [name.qualified.desc, id.qualified.desc] }
35
-
36
- expect(ordered.to_a).
37
- to eql([{ id: 2, name: 'Joe' }, { id: 1, name: 'Jane' }, { id: 3, name: 'Jade' }])
38
- end
39
- end
40
-
41
- with_adapters :postgres, :mysql do
42
- it 'orders by virtual attributes' do
43
- ordered = relation.
44
- select { string::concat(id, '-', name).as(:uid) }.
45
- order(:uid)
46
-
47
- expect(ordered.to_a).
48
- to eql([{ uid: '1-Jane' }, { uid: '2-Joe' }, { uid: '3-Jade' }])
49
- end
50
- end
51
- end
@@ -1,11 +0,0 @@
1
- RSpec.describe ROM::Relation, '#pluck' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users and tasks'
5
-
6
- with_adapters do
7
- it 'returns a list of values from a specific column' do
8
- expect(relation.pluck(:id)).to eql([1, 2])
9
- end
10
- end
11
- end
@@ -1,29 +0,0 @@
1
- RSpec.describe ROM::Relation, '#prefix' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users and tasks'
5
-
6
- before do
7
- conf.relation(:users) do
8
- schema(infer: true)
9
-
10
- def sorted
11
- order(:id)
12
- end
13
- end
14
- end
15
-
16
- with_adapters do
17
- it 'projects the dataset using new column names' do
18
- prefixed = relation.sorted.prefix(:user)
19
-
20
- expect(prefixed.first).to eql(user_id: 1, user_name: 'Jane')
21
- end
22
-
23
- it 'uses singularized table name as the default prefix' do
24
- prefixed = relation.sorted.prefix
25
-
26
- expect(prefixed.first).to eql(user_id: 1, user_name: 'Jane')
27
- end
28
- end
29
- end
@@ -1,27 +0,0 @@
1
- RSpec.describe ROM::Relation, '#primary_key' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users and tasks'
5
-
6
- with_adapters do
7
- context 'with schema' do
8
- it 'returns configured primary key from the schema' do
9
- conf.relation(:users) do
10
- schema do
11
- attribute :name, ROM::SQL::Types::String.meta(primary_key: true)
12
- end
13
- end
14
-
15
- expect(relation.primary_key).to be(:name)
16
- end
17
- end
18
-
19
- context 'without schema' do
20
- it 'returns :id by default' do
21
- conf.relation(:users) { schema(infer: true) }
22
-
23
- expect(relation.primary_key).to be(:id)
24
- end
25
- end
26
- end
27
- end
@@ -1,24 +0,0 @@
1
- RSpec.describe ROM::Relation, '#project' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users and tasks'
5
-
6
- before do
7
- conf.relation(:users) do
8
- schema(infer: true)
9
-
10
- def sorted
11
- order(:id)
12
- end
13
- end
14
- end
15
-
16
- with_adapters do
17
- it 'projects the dataset using new column names' do
18
- projected = relation.sorted.project(:name)
19
-
20
- expect(projected.schema.map(&:to_sql_name)).to match_array(Sequel[:name])
21
- expect(projected.first).to eql(name: 'Jane')
22
- end
23
- end
24
- end
@@ -1,30 +0,0 @@
1
- RSpec.describe ROM::Relation, '#qualified_columns' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users and tasks'
5
-
6
- before do
7
- conf.relation(:users) do
8
- schema(infer: true)
9
-
10
- def sorted
11
- order(:id)
12
- end
13
- end
14
- end
15
-
16
- with_adapters do
17
- it 'returns qualified column names' do
18
- columns = relation.sorted.prefix(:user).qualified_columns
19
-
20
- expect(columns).to eql([Sequel.qualify(:users, :id).as(:user_id),
21
- Sequel.qualify(:users, :name).as(:user_name)])
22
- end
23
-
24
- it 'returns projected qualified column names' do
25
- columns = relation.sorted.project(:id).prefix(:user).qualified_columns
26
-
27
- expect(columns).to eql([Sequel.qualify(:users, :id).as(:user_id)])
28
- end
29
- end
30
- end
@@ -1,25 +0,0 @@
1
- RSpec.describe ROM::Relation, '#qualified' do
2
- subject(:relation) { relations[:users] }
3
-
4
- include_context 'users and tasks'
5
-
6
- with_adapters do
7
- it 'qualifies all attributes' do
8
- qualified = relation.qualified
9
-
10
- expect(qualified.schema.all?(&:qualified)).to be(true)
11
- end
12
-
13
- it 'qualifies virtual attributes' do
14
- qualified = relation.
15
- left_join(:tasks, tasks[:user_id].qualified => relation[:id].qualified).
16
- select(:id, tasks[:id].func { int::count(id).as(:count) }).
17
- qualified.
18
- group(:id)
19
-
20
- expect(qualified.schema.all?(&:qualified)).to be(true)
21
-
22
- expect(qualified.to_a).to eql([{ id: 1, count: 1 }, { id: 2, count: 1 }])
23
- end
24
- end
25
- end
@@ -1,25 +0,0 @@
1
- RSpec.describe ROM::Relation, '#read' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users and tasks'
5
-
6
- with_adapters do
7
- let(:users) do
8
- relation.read('SELECT name FROM users')
9
- end
10
-
11
- it 'returns results from raw SQL' do
12
- expect(users).to match_array([{ name: 'Jane' }, { name: 'Joe' }])
13
- end
14
-
15
- it 'returns a new SQL relation' do
16
- materialized = users.()
17
- expect(materialized).to match_array([{ name: 'Jane' }, { name: 'Joe' }])
18
- expect(materialized.source).to be(users)
19
- end
20
-
21
- it 'has empty schema' do
22
- expect(users.schema).to be_empty
23
- end
24
- end
25
- end
@@ -1,23 +0,0 @@
1
- RSpec.describe ROM::Relation, '#rename' do
2
- subject(:relation) { container.relations.users }
3
-
4
- include_context 'users and tasks'
5
-
6
- before do
7
- conf.relation(:users) do
8
- schema(infer: true)
9
-
10
- def sorted
11
- order(:id)
12
- end
13
- end
14
- end
15
-
16
- with_adapters do
17
- it 'projects the dataset using new column names' do
18
- renamed = relation.sorted.rename(id: :user_id, name: :user_name)
19
-
20
- expect(renamed.first).to eql(user_id: 1, user_name: 'Jane')
21
- end
22
- end
23
- end
@@ -1,57 +0,0 @@
1
- RSpec.describe ROM::Relation, '#right_join' do
2
- subject(:relation) { relations[:tasks] }
3
-
4
- include_context 'users and tasks'
5
-
6
- with_adapters :postgres, :mysql do
7
- it 'joins relations using left outer join' do
8
- users.insert id: 3, name: 'Jade'
9
- relation.insert id: 3, title: 'Unassigned'
10
-
11
- result = relation.
12
- right_join(:users, id: :user_id).
13
- select(:title, users[:name])
14
-
15
- expect(result.schema.map(&:name)).to eql(%i[title name])
16
-
17
- expect(result.to_a).to match_array([
18
- { name: 'Joe', title: "Joe's task" },
19
- { name: 'Jane', title: "Jane's task" },
20
- { name: 'Jade', title: nil }
21
- ])
22
- end
23
-
24
- context 'with associations' do
25
- before do
26
- conf.relation(:users) do
27
- schema(infer: true) do
28
- associations { has_many :tasks }
29
- end
30
- end
31
-
32
- conf.relation(:tasks) do
33
- schema(infer: true) do
34
- associations { belongs_to :user }
35
- end
36
- end
37
- end
38
-
39
- it 'joins relation with join keys inferred' do
40
- users.insert id: 3, name: 'Jade'
41
- relation.insert id: 3, title: 'Unassigned'
42
-
43
- result = relation.
44
- right_join(users).
45
- select(:title, users[:name])
46
-
47
- expect(result.schema.map(&:name)).to eql(%i[title name])
48
-
49
- expect(result.to_a).to match_array([
50
- { name: 'Joe', title: "Joe's task" },
51
- { name: 'Jane', title: "Jane's task" },
52
- { name: 'Jade', title: nil }
53
- ])
54
- end
55
- end
56
- end
57
- end