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,43 +0,0 @@
1
- RSpec.describe 'Eager loading' do
2
- include_context 'users and tasks'
3
-
4
- with_adapters do
5
- before do
6
- conf.relation(:users) do
7
- auto_map false
8
-
9
- def by_name(name)
10
- where(name: name)
11
- end
12
- end
13
-
14
- conf.relation(:tasks) do
15
- auto_map false
16
-
17
- def for_users(users)
18
- where(user_id: users.map { |tuple| tuple[:id] })
19
- end
20
- end
21
-
22
- conf.relation(:tags) do
23
- auto_map false
24
-
25
- def for_tasks(tasks)
26
- inner_join(:task_tags, task_id: :id)
27
- .where(task_id: tasks.map { |tuple| tuple[:id] })
28
- end
29
- end
30
- end
31
-
32
- it 'issues 3 queries for 3.graphd relations' do
33
- users = container.relations[:users].by_name('Piotr')
34
- tasks = container.relations[:tasks]
35
- tags = container.relations[:tags]
36
-
37
- relation = users.combine_with(tasks.for_users.combine_with(tags.for_tasks))
38
-
39
- # TODO: figure out a way to assert correct number of issued queries
40
- expect(relation.call).to be_instance_of(ROM::Relation::Loaded)
41
- end
42
- end
43
- end
@@ -1,304 +0,0 @@
1
- require 'dry-struct'
2
-
3
- RSpec.describe 'Commands / Create', :postgres, seeds: false do
4
- include_context 'relations'
5
-
6
- let(:create_user) { user_commands.create }
7
- let(:create_users) { user_commands.create_many }
8
- let(:create_task) { task_commands.create }
9
-
10
- before do |ex|
11
- module Test
12
- class Params < Dry::Struct
13
- attribute :name, Types::Strict::String.optional
14
-
15
- def self.[](input)
16
- new(input)
17
- end
18
- end
19
- end
20
-
21
- conn.add_index :users, :name, unique: true
22
-
23
- if sqlite?(ex)
24
- conn.add_index :tasks, :title, unique: true
25
- else
26
- conn.execute "ALTER TABLE tasks add CONSTRAINT tasks_title_key UNIQUE (title)"
27
- end
28
-
29
- conf.commands(:users) do
30
- define(:create) do
31
- input Test::Params
32
-
33
- result :one
34
- end
35
-
36
- define(:create_many, type: :create) do
37
- result :many
38
- end
39
- end
40
-
41
- conf.commands(:tasks) do
42
- define(:create)
43
- end
44
- end
45
-
46
- with_adapters do
47
- describe '#transaction' do
48
- it 'creates record if nothing was raised' do
49
- result = users.transaction {
50
- create_user.call(name: 'Jane')
51
- }
52
-
53
- expect(result).to eql(id: 1, name: 'Jane')
54
- end
55
-
56
- it 'creates multiple records if nothing was raised' do
57
- result = users.transaction {
58
- create_users.call([{ name: 'Jane' }, { name: 'Jack' }])
59
- }
60
-
61
- expect(result).to match_array([
62
- { id: 1, name: 'Jane' }, { id: 2, name: 'Jack' }
63
- ])
64
- end
65
-
66
- it 'allows for nested transactions' do
67
- result = users.transaction {
68
- users.transaction {
69
- create_user.call(name: 'Jane')
70
- }
71
- }
72
-
73
- expect(result).to eql(id: 1, name: 'Jane')
74
- end
75
-
76
- it 'creates nothing if command error was raised' do
77
- expect {
78
- begin
79
- users.transaction {
80
- create_user.call(name: 'Jane')
81
- create_user.call(name: nil)
82
- }
83
- rescue ROM::SQL::Error
84
- end
85
- }.to_not change { container.relations.users.count }
86
- end
87
-
88
- it 'creates nothing if rollback was raised' do
89
- expect {
90
- result = users.transaction { |t|
91
- create_user.call(name: 'Jane')
92
- create_user.call(name: 'John')
93
- t.rollback!
94
- }
95
-
96
- expect(result).to be(nil)
97
- }.to_not change { container.relations.users.count }
98
- end
99
-
100
- it 'creates nothing if constraint error was raised' do
101
- expect {
102
- begin
103
- passed = false
104
-
105
- users.transaction {
106
- create_user.call(name: 'Jane')
107
- create_user.call(name: 'Jane')
108
- passed = true
109
- }
110
- rescue => error
111
- expect(error).to be_instance_of(ROM::SQL::UniqueConstraintError)
112
- expect(passed).to be(false)
113
- end
114
- }.to_not change { container.relations.users.count }
115
- end
116
-
117
- it 'creates nothing if anything was raised in any nested transaction' do
118
- expect {
119
- expect {
120
- users.transaction {
121
- create_user.call(name: 'John')
122
-
123
- users.transaction {
124
- create_user.call(name: 'Jane')
125
- raise Exception
126
- }
127
- }
128
- }.to raise_error(Exception)
129
- }.to_not change { container.relations.users.count }
130
- end
131
- end
132
-
133
- it 'uses relation schema for the default input handler' do
134
- conf.relation(:users_with_schema) do
135
- schema(:users) do
136
- attribute :id, ROM::SQL::Types::Serial
137
- attribute :name, ROM::SQL::Types::String
138
- end
139
- end
140
-
141
- conf.commands(:users_with_schema) do
142
- define(:create) do
143
- result :one
144
- end
145
- end
146
-
147
- create = container.commands[:users_with_schema][:create]
148
-
149
- expect(create.input[foo: 'bar', id: 1, name: 'Jane']).to eql(
150
- id: 1, name: 'Jane'
151
- )
152
- end
153
-
154
- it 'returns a single tuple when result is set to :one' do
155
- result = create_user.call(name: 'Jane')
156
-
157
- expect(result).to eql(id: 1, name: 'Jane')
158
- end
159
-
160
- it 'returns tuples when result is set to :many' do
161
- result = create_users.call([{ name: 'Jane' }, { name: 'Jack' }])
162
-
163
- expect(result.to_a).to match_array([
164
- { id: 1, name: 'Jane' }, { id: 2, name: 'Jack' }
165
- ])
166
- end
167
-
168
- it 're-raises not-null constraint violation error' do
169
- expect {
170
- create_user.call(name: nil)
171
- }.to raise_error(ROM::SQL::NotNullConstraintError)
172
- end
173
-
174
- # Because Oracle doesn't have boolean in SQL
175
- if !metadata[:oracle]
176
- context 'with puppies' do
177
- include_context 'puppies'
178
-
179
- before do
180
- conf.relation(:puppies) do
181
- schema(infer: true)
182
- end
183
-
184
-
185
- conf.commands(:puppies) do
186
- define(:create)
187
- end
188
- end
189
-
190
- it 're-raises not-null constraint violation error with nil boolean' do
191
- puppies = commands[:puppies]
192
-
193
- expect { puppies.create.call(name: 'Charlie', cute: nil) }.
194
- to raise_error(ROM::SQL::NotNullConstraintError)
195
- end
196
- end
197
- end
198
-
199
- it 'raises uniqueness constraint violation error' do
200
- expect {
201
- user = create_user.call(name: 'Jane')
202
- create_user.call(name: user[:name])
203
- }.to raise_error(ROM::SQL::UniqueConstraintError)
204
- end
205
-
206
- it 're-raises fk constraint violation error' do |ex|
207
- expect { create_task.call(user_id: 918_273_645) }.
208
- to raise_error(ROM::SQL::ForeignKeyConstraintError)
209
- end
210
-
211
- it 're-raises database errors' do
212
- expect {
213
- create_user.call(name: nil)
214
- }.to raise_error(ROM::SQL::NotNullConstraintError)
215
- end
216
-
217
- describe '#execute' do
218
- context 'with a single record' do
219
- it 'materializes the result' do
220
- result = create_user.execute(name: 'Jane')
221
-
222
- expect(result).to eq([{ id: 1, name: 'Jane' }])
223
- end
224
- end
225
-
226
- context 'with multiple records' do
227
- it 'materializes the results' do
228
- result = create_user.execute([
229
- { name: 'Jane' },
230
- { name: 'John' }
231
- ])
232
-
233
- expect(result).to eql([{ id: 1, name: 'Jane' }, { id: 2, name: 'John' }])
234
- end
235
- end
236
-
237
- context 'with a composite pk' do
238
- before do
239
- inferrable_relations.concat %i(user_group)
240
- end
241
-
242
- before do
243
- conn.create_table(:user_group) do
244
- primary_key [:user_id, :group_id]
245
- column :user_id, Integer, null: false
246
- column :group_id, Integer, null: false
247
- end
248
-
249
- conf.relation(:user_group) do
250
- schema(infer: true)
251
- end
252
-
253
- conf.commands(:user_group) do
254
- define(:create) { result :one }
255
- end
256
- end
257
-
258
- # with a composite pk sequel returns 0 when inserting for MySQL
259
- if !metadata[:mysql]
260
- it 'materializes the result' do |ex|
261
- command = container.commands[:user_group][:create]
262
- result = command.call(user_id: 1, group_id: 2)
263
-
264
- pending "if sequel could use Oracle's RETURNING statement, that would be possible" if oracle?(ex)
265
- expect(result).to eql(user_id: 1, group_id: 2)
266
- end
267
- end
268
- end
269
- end
270
- end
271
-
272
- describe '#call' do
273
- it 'raises check constraint violation error' do
274
- expect { create_user.call(name: 'J') }.
275
- to raise_error(ROM::SQL::CheckConstraintError, /name/)
276
- end
277
-
278
- it 'raises constraint violation error' do
279
- expect { create_task.call(title: '') }.to raise_error(ROM::SQL::ConstraintError, /title/)
280
- end
281
- end
282
-
283
- describe '#upsert' do
284
- let(:task) { { title: 'task 1' } }
285
-
286
- before { create_task.call(task) }
287
-
288
- it 'raises error without upsert marker' do
289
- expect {
290
- create_task.call(task)
291
- }.to raise_error(ROM::SQL::UniqueConstraintError)
292
- end
293
-
294
- it 'raises no error for duplicated data' do
295
- expect { create_task.upsert(task) }.to_not raise_error
296
- end
297
-
298
- it 'returns record data' do
299
- expect(create_task.upsert(task, constraint: :tasks_title_key, update: { user_id: nil })).to eql([
300
- id: 1, user_id: nil, title: 'task 1'
301
- ])
302
- end
303
- end if PG_LTE_95
304
- end
@@ -1,84 +0,0 @@
1
- RSpec.describe 'Commands / Delete' do
2
- include_context 'users and tasks'
3
-
4
- let(:delete_user) { user_commands.delete }
5
-
6
- with_adapters do
7
- before do
8
- conf.relation(:users) do
9
- def by_name(name)
10
- where(name: name)
11
- end
12
- end
13
-
14
- conf.commands(:users) do
15
- define(:delete) do
16
- result :one
17
- end
18
- end
19
-
20
- users.insert(id: 3, name: 'Jade')
21
- users.insert(id: 4, name: 'John')
22
- end
23
-
24
- describe '#transaction' do
25
- it 'deletes in normal way if no error raised' do
26
- expect {
27
- users.transaction do
28
- delete_user.by_name('Jade').call
29
- end
30
- }.to change { users.count }.by(-1)
31
- end
32
-
33
- it 'deletes nothing if error was raised' do
34
- expect {
35
- users.transaction do |t|
36
- delete_user.by_name('Jade').call
37
- t.rollback!
38
- end
39
- }.to_not change { users.count }
40
- end
41
- end
42
-
43
- describe '#call' do
44
- it 'deletes all tuples in a restricted relation' do
45
- result = delete_user.by_name('Jade').call
46
-
47
- expect(result).to eql(id: 3, name: 'Jade')
48
- end
49
-
50
- it 're-raises database error' do
51
- command = delete_user.by_name('Jade')
52
-
53
- expect(command.relation).to receive(:delete).and_raise(
54
- Sequel::DatabaseError, 'totally wrong'
55
- )
56
-
57
- expect {
58
- command.call
59
- }.to raise_error(ROM::SQL::DatabaseError, /totally wrong/)
60
- end
61
- end
62
-
63
- describe '#execute' do
64
- context 'with a single record' do
65
- it 'materializes the result' do
66
- result = container.commands[:users].delete.by_name(%w(Jade)).execute
67
- expect(result).to eq([
68
- { id: 3, name: 'Jade' }
69
- ])
70
- end
71
- end
72
-
73
- context 'with multiple records' do
74
- it 'materializes the results' do
75
- result = container.commands[:users].delete.by_name(%w(Jade John)).execute
76
- expect(result).to eq([
77
- { id: 3, name: 'Jade' },
78
- { id: 4, name: 'John' }
79
- ])
80
- end
81
- end
82
- end
83
- end
84
- end
@@ -1,90 +0,0 @@
1
- require 'dry-struct'
2
-
3
- RSpec.describe 'Commands / Update', seeds: false do
4
- include_context 'users'
5
-
6
- let(:update_user) { user_commands[:update] }
7
-
8
- let(:piotr) { users.by_name('Piotr').one }
9
- let(:peter) { { name: 'Peter' } }
10
-
11
- with_adapters do
12
- before do
13
- Test::User = Class.new(Dry::Struct) {
14
- attribute :id, Types::Strict::Int
15
- attribute :name, Types::Strict::String
16
- }
17
-
18
- conf.relation(:users) do
19
- schema(infer: true)
20
-
21
- def by_id(id)
22
- where(id: id)
23
- end
24
-
25
- def by_name(name)
26
- where(name: name)
27
- end
28
- end
29
-
30
- conf.commands(:users) do
31
- define(:update)
32
- end
33
-
34
- conf.mappers do
35
- register :users, entity: -> tuples { tuples.map { |tuple| Test::User.new(tuple) } }
36
- end
37
-
38
- users.insert(name: 'Piotr')
39
- users.insert(name: 'Jane')
40
- end
41
-
42
- context '#transaction' do
43
- it 'update record if there was no errors' do
44
- result = users.transaction do
45
- update_user.by_id(piotr[:id]).call(peter)
46
- end
47
-
48
- expect(result).to eq([{ id: 1, name: 'Peter' }])
49
- end
50
-
51
- it 'updates nothing if error was raised' do
52
- users.transaction do |t|
53
- update_user.by_id(piotr[:id]).call(peter)
54
- t.rollback!
55
- end
56
-
57
- expect(users.first[:name]).to eql('Piotr')
58
- end
59
- end
60
-
61
- describe '#call' do
62
- it 'updates relation tuples' do
63
- result = update_user.by_id(piotr[:id]).call(peter)
64
-
65
- expect(result.to_a).to match_array([{ id: 1, name: 'Peter' }])
66
- end
67
-
68
- it 're-raises database errors' do |example|
69
- expect {
70
- update_user.by_id(piotr[:id]).call(name: nil)
71
- }.to raise_error(ROM::SQL::NotNullConstraintError, /name/i)
72
- end
73
-
74
- it 'materializes single result' do
75
- result = update_user.by_name('Piotr').call(name: 'Pete')
76
- expect(result).to eq([
77
- { id: 1, name: 'Pete' }
78
- ])
79
- end
80
-
81
- it 'materializes multiple results' do
82
- result = update_user.by_name(%w(Piotr Jane)).call(name: 'Josie')
83
- expect(result).to eq([
84
- { id: 1, name: 'Josie' },
85
- { id: 2, name: 'Josie' }
86
- ])
87
- end
88
- end
89
- end
90
- end