sequel 4.44.0 → 4.45.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +110 -0
- data/README.rdoc +8 -9
- data/doc/active_record.rdoc +2 -3
- data/doc/model_plugins.rdoc +1 -1
- data/doc/opening_databases.rdoc +0 -46
- data/doc/release_notes/4.45.0.txt +370 -0
- data/lib/sequel/adapters/cubrid.rb +2 -0
- data/lib/sequel/adapters/do.rb +2 -0
- data/lib/sequel/adapters/jdbc/as400.rb +2 -0
- data/lib/sequel/adapters/jdbc/cubrid.rb +2 -0
- data/lib/sequel/adapters/jdbc/firebirdsql.rb +2 -0
- data/lib/sequel/adapters/jdbc/informix-sqli.rb +2 -0
- data/lib/sequel/adapters/jdbc/jdbcprogress.rb +2 -0
- data/lib/sequel/adapters/jdbc/mysql.rb +1 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +5 -0
- data/lib/sequel/adapters/mysql.rb +1 -0
- data/lib/sequel/adapters/mysql2.rb +1 -0
- data/lib/sequel/adapters/odbc/oracle.rb +11 -0
- data/lib/sequel/adapters/odbc/progress.rb +2 -0
- data/lib/sequel/adapters/postgres.rb +0 -2
- data/lib/sequel/adapters/shared/cubrid.rb +2 -0
- data/lib/sequel/adapters/shared/firebird.rb +2 -0
- data/lib/sequel/adapters/shared/informix.rb +2 -0
- data/lib/sequel/adapters/shared/mssql.rb +47 -7
- data/lib/sequel/adapters/shared/mysql.rb +16 -1
- data/lib/sequel/adapters/shared/postgres.rb +9 -1
- data/lib/sequel/adapters/shared/progress.rb +2 -0
- data/lib/sequel/adapters/shared/sqlanywhere.rb +1 -1
- data/lib/sequel/adapters/swift.rb +2 -0
- data/lib/sequel/ast_transformer.rb +13 -6
- data/lib/sequel/core.rb +13 -16
- data/lib/sequel/database/connecting.rb +25 -10
- data/lib/sequel/database/dataset.rb +6 -1
- data/lib/sequel/database/dataset_defaults.rb +9 -2
- data/lib/sequel/database/misc.rb +10 -3
- data/lib/sequel/database/schema_methods.rb +4 -0
- data/lib/sequel/dataset/mutation.rb +8 -20
- data/lib/sequel/dataset/prepared_statements.rb +2 -0
- data/lib/sequel/dataset/query.rb +32 -7
- data/lib/sequel/dataset/sql.rb +13 -3
- data/lib/sequel/deprecated.rb +9 -1
- data/lib/sequel/exceptions.rb +37 -8
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +117 -0
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/identifier_mangling.rb +3 -2
- data/lib/sequel/extensions/pg_hstore.rb +1 -5
- data/lib/sequel/extensions/schema_dumper.rb +3 -1
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +2 -2
- data/lib/sequel/extensions/string_agg.rb +1 -0
- data/lib/sequel/model.rb +23 -10
- data/lib/sequel/model/associations.rb +17 -5
- data/lib/sequel/model/base.rb +115 -62
- data/lib/sequel/model/dataset_module.rb +10 -3
- data/lib/sequel/model/exceptions.rb +7 -5
- data/lib/sequel/plugins/association_pks.rb +13 -1
- data/lib/sequel/plugins/association_proxies.rb +8 -1
- data/lib/sequel/plugins/before_after_save.rb +1 -0
- data/lib/sequel/plugins/class_table_inheritance.rb +7 -3
- data/lib/sequel/plugins/columns_updated.rb +42 -0
- data/lib/sequel/plugins/composition.rb +10 -5
- data/lib/sequel/plugins/error_splitter.rb +1 -1
- data/lib/sequel/plugins/hook_class_methods.rb +39 -5
- data/lib/sequel/plugins/instance_hooks.rb +58 -5
- data/lib/sequel/plugins/lazy_attributes.rb +10 -5
- data/lib/sequel/plugins/nested_attributes.rb +10 -5
- data/lib/sequel/plugins/prepared_statements.rb +7 -0
- data/lib/sequel/plugins/prepared_statements_associations.rb +2 -0
- data/lib/sequel/plugins/prepared_statements_with_pk.rb +2 -0
- data/lib/sequel/plugins/schema.rb +2 -0
- data/lib/sequel/plugins/scissors.rb +2 -0
- data/lib/sequel/plugins/serialization.rb +10 -5
- data/lib/sequel/plugins/split_values.rb +5 -1
- data/lib/sequel/plugins/static_cache.rb +2 -2
- data/lib/sequel/plugins/tactical_eager_loading.rb +1 -1
- data/lib/sequel/plugins/validation_contexts.rb +49 -0
- data/lib/sequel/plugins/validation_helpers.rb +1 -0
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +31 -0
- data/spec/adapters/mysql_spec.rb +20 -2
- data/spec/adapters/postgres_spec.rb +43 -12
- data/spec/adapters/spec_helper.rb +5 -8
- data/spec/core/database_spec.rb +47 -12
- data/spec/core/dataset_mutation_spec.rb +22 -22
- data/spec/core/dataset_spec.rb +88 -20
- data/spec/core/deprecated_spec.rb +1 -1
- data/spec/core/expression_filters_spec.rb +1 -1
- data/spec/core/mock_adapter_spec.rb +0 -3
- data/spec/core/placeholder_literalizer_spec.rb +1 -1
- data/spec/core/schema_spec.rb +8 -1
- data/spec/core/spec_helper.rb +6 -1
- data/spec/core_extensions_spec.rb +4 -0
- data/spec/deprecation_helper.rb +17 -0
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +314 -0
- data/spec/extensions/association_pks_spec.rb +61 -13
- data/spec/extensions/association_proxies_spec.rb +3 -3
- data/spec/extensions/class_table_inheritance_spec.rb +39 -0
- data/spec/extensions/columns_updated_spec.rb +35 -0
- data/spec/extensions/composition_spec.rb +6 -1
- data/spec/extensions/hook_class_methods_spec.rb +114 -26
- data/spec/extensions/identifier_mangling_spec.rb +107 -73
- data/spec/extensions/instance_hooks_spec.rb +78 -14
- data/spec/extensions/lazy_attributes_spec.rb +8 -2
- data/spec/extensions/many_through_many_spec.rb +2 -2
- data/spec/extensions/mssql_optimistic_locking_spec.rb +1 -1
- data/spec/extensions/nested_attributes_spec.rb +8 -2
- data/spec/extensions/pg_array_spec.rb +18 -4
- data/spec/extensions/prepared_statements_associations_spec.rb +48 -39
- data/spec/extensions/prepared_statements_with_pk_spec.rb +13 -11
- data/spec/extensions/query_spec.rb +1 -1
- data/spec/extensions/schema_dumper_spec.rb +34 -6
- data/spec/extensions/schema_spec.rb +13 -7
- data/spec/extensions/scissors_spec.rb +3 -1
- data/spec/extensions/sequel_3_dataset_methods_spec.rb +4 -4
- data/spec/extensions/serialization_spec.rb +7 -1
- data/spec/extensions/set_overrides_spec.rb +2 -2
- data/spec/extensions/shared_caching_spec.rb +19 -15
- data/spec/extensions/spec_helper.rb +7 -3
- data/spec/extensions/split_values_spec.rb +45 -10
- data/spec/extensions/string_agg_spec.rb +2 -2
- data/spec/extensions/subset_conditions_spec.rb +3 -3
- data/spec/extensions/tactical_eager_loading_spec.rb +1 -1
- data/spec/extensions/validation_contexts_spec.rb +31 -0
- data/spec/guards_helper.rb +2 -0
- data/spec/integration/associations_test.rb +22 -20
- data/spec/integration/dataset_test.rb +25 -2
- data/spec/integration/model_test.rb +1 -1
- data/spec/integration/plugin_test.rb +11 -16
- data/spec/integration/prepared_statement_test.rb +40 -32
- data/spec/integration/spec_helper.rb +5 -8
- data/spec/model/association_reflection_spec.rb +4 -0
- data/spec/model/associations_spec.rb +37 -10
- data/spec/model/base_spec.rb +6 -0
- data/spec/model/hooks_spec.rb +56 -35
- data/spec/model/model_spec.rb +21 -5
- data/spec/model/record_spec.rb +14 -11
- data/spec/model/spec_helper.rb +7 -1
- data/spec/sequel_warning.rb +11 -0
- metadata +13 -3
@@ -1,8 +1,9 @@
|
|
1
1
|
require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
2
2
|
|
3
3
|
describe "InstanceHooks plugin" do
|
4
|
-
def r(x)
|
4
|
+
def r(x=nil)
|
5
5
|
@r << x
|
6
|
+
yield if block_given?
|
6
7
|
x
|
7
8
|
end
|
8
9
|
|
@@ -24,7 +25,7 @@ describe "InstanceHooks plugin" do
|
|
24
25
|
@r.must_equal [4, 2, 1, 3]
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
|
+
deprecated "should cancel the save if before_create_hook block returns false" do
|
28
29
|
@o.after_create_hook{r 1}
|
29
30
|
@o.before_create_hook{r false}
|
30
31
|
@o.before_create_hook{r 4}
|
@@ -35,6 +36,17 @@ describe "InstanceHooks plugin" do
|
|
35
36
|
@r.must_equal [4, false]
|
36
37
|
end
|
37
38
|
|
39
|
+
it "should cancel the save if before_create_hook block calls cancel_action" do
|
40
|
+
@o.after_create_hook{r 1}
|
41
|
+
@o.before_create_hook{r{@o.cancel_action}}
|
42
|
+
@o.before_create_hook{r 4}
|
43
|
+
@o.save.must_be_nil
|
44
|
+
@r.must_equal [4, nil]
|
45
|
+
@r.clear
|
46
|
+
@o.save.must_be_nil
|
47
|
+
@r.must_equal [4, nil]
|
48
|
+
end
|
49
|
+
|
38
50
|
it "should support before_update_hook and after_update_hook" do
|
39
51
|
@x.after_update_hook{r 1}
|
40
52
|
@x.before_update_hook{r 2}
|
@@ -46,7 +58,7 @@ describe "InstanceHooks plugin" do
|
|
46
58
|
@r.must_equal [4, 2, 1, 3]
|
47
59
|
end
|
48
60
|
|
49
|
-
|
61
|
+
deprecated "should cancel the save if before_update_hook block returns false" do
|
50
62
|
@x.after_update_hook{r 1}
|
51
63
|
@x.before_update_hook{r false}
|
52
64
|
@x.before_update_hook{r 4}
|
@@ -57,6 +69,17 @@ describe "InstanceHooks plugin" do
|
|
57
69
|
@r.must_equal [4, false]
|
58
70
|
end
|
59
71
|
|
72
|
+
it "should cancel the save if before_update_hook block calls cancel_action" do
|
73
|
+
@x.after_update_hook{r 1}
|
74
|
+
@x.before_update_hook{r{@x.cancel_action}}
|
75
|
+
@x.before_update_hook{r 4}
|
76
|
+
@x.save.must_be_nil
|
77
|
+
@r.must_equal [4, nil]
|
78
|
+
@r.clear
|
79
|
+
@x.save.must_be_nil
|
80
|
+
@r.must_equal [4, nil]
|
81
|
+
end
|
82
|
+
|
60
83
|
it "should support before_save_hook and after_save_hook" do
|
61
84
|
@o.after_save_hook{r 1}
|
62
85
|
@o.before_save_hook{r 2}
|
@@ -76,7 +99,7 @@ describe "InstanceHooks plugin" do
|
|
76
99
|
@r.must_equal [4, 2, 1, 3]
|
77
100
|
end
|
78
101
|
|
79
|
-
|
102
|
+
deprecated "should cancel the save if before_save_hook block returns false" do
|
80
103
|
@x.after_save_hook{r 1}
|
81
104
|
@x.before_save_hook{r false}
|
82
105
|
@x.before_save_hook{r 4}
|
@@ -94,6 +117,24 @@ describe "InstanceHooks plugin" do
|
|
94
117
|
@r.must_equal [4, false]
|
95
118
|
end
|
96
119
|
|
120
|
+
it "should cancel the save if before_save_hook block calls cancel_action" do
|
121
|
+
@x.after_save_hook{r 1}
|
122
|
+
@x.before_save_hook{r{@x.cancel_action}}
|
123
|
+
@x.before_save_hook{r 4}
|
124
|
+
@x.save.must_be_nil
|
125
|
+
@r.must_equal [4, nil]
|
126
|
+
@r.clear
|
127
|
+
|
128
|
+
@x.after_save_hook{r 1}
|
129
|
+
@x.before_save_hook{r{@x.cancel_action}}
|
130
|
+
@x.before_save_hook{r 4}
|
131
|
+
@x.save.must_be_nil
|
132
|
+
@r.must_equal [4, nil]
|
133
|
+
@r.clear
|
134
|
+
@x.save.must_be_nil
|
135
|
+
@r.must_equal [4, nil]
|
136
|
+
end
|
137
|
+
|
97
138
|
it "should support before_destroy_hook and after_destroy_hook" do
|
98
139
|
@x.after_destroy_hook{r 1}
|
99
140
|
@x.before_destroy_hook{r 2}
|
@@ -103,7 +144,7 @@ describe "InstanceHooks plugin" do
|
|
103
144
|
@r.must_equal [4, 2, 1, 3]
|
104
145
|
end
|
105
146
|
|
106
|
-
|
147
|
+
deprecated "should cancel the destroy if before_destroy_hook block returns false" do
|
107
148
|
@x.after_destroy_hook{r 1}
|
108
149
|
@x.before_destroy_hook{r false}
|
109
150
|
@x.before_destroy_hook{r 4}
|
@@ -111,6 +152,14 @@ describe "InstanceHooks plugin" do
|
|
111
152
|
@r.must_equal [4, false]
|
112
153
|
end
|
113
154
|
|
155
|
+
it "should cancel the destroy if before_destroy_hook block calls cancel_action" do
|
156
|
+
@x.after_destroy_hook{r 1}
|
157
|
+
@x.before_destroy_hook{r{@x.cancel_action}}
|
158
|
+
@x.before_destroy_hook{r 4}
|
159
|
+
@x.destroy.must_be_nil
|
160
|
+
@r.must_equal [4, nil]
|
161
|
+
end
|
162
|
+
|
114
163
|
it "should support before_validation_hook and after_validation_hook" do
|
115
164
|
@o.after_validation_hook{r 1}
|
116
165
|
@o.before_validation_hook{r 2}
|
@@ -120,7 +169,7 @@ describe "InstanceHooks plugin" do
|
|
120
169
|
@r.must_equal [4, 2, 1, 3]
|
121
170
|
end
|
122
171
|
|
123
|
-
|
172
|
+
deprecated "should cancel the save if before_validation_hook block returns false" do
|
124
173
|
@o.after_validation_hook{r 1}
|
125
174
|
@o.before_validation_hook{r false}
|
126
175
|
@o.before_validation_hook{r 4}
|
@@ -131,6 +180,17 @@ describe "InstanceHooks plugin" do
|
|
131
180
|
@r.must_equal [4, false]
|
132
181
|
end
|
133
182
|
|
183
|
+
it "should cancel the save if before_validation_hook block calls cancel_action" do
|
184
|
+
@o.after_validation_hook{r 1}
|
185
|
+
@o.before_validation_hook{r{@o.cancel_action}}
|
186
|
+
@o.before_validation_hook{r 4}
|
187
|
+
@o.valid?.must_equal false
|
188
|
+
@r.must_equal [4, nil]
|
189
|
+
@r.clear
|
190
|
+
@o.valid?.must_equal false
|
191
|
+
@r.must_equal [4, nil]
|
192
|
+
end
|
193
|
+
|
134
194
|
it "should clear only related hooks on successful create" do
|
135
195
|
@o.after_destroy_hook{r 1}
|
136
196
|
@o.before_destroy_hook{r 2}
|
@@ -210,10 +270,12 @@ describe "InstanceHooks plugin with transactions" do
|
|
210
270
|
@c = Class.new(Sequel::Model(@db[:items])) do
|
211
271
|
attr_accessor :rb
|
212
272
|
def after_save
|
273
|
+
super
|
213
274
|
db.execute('as')
|
214
275
|
raise Sequel::Rollback if rb
|
215
276
|
end
|
216
277
|
def after_destroy
|
278
|
+
super
|
217
279
|
db.execute('ad')
|
218
280
|
raise Sequel::Rollback if rb
|
219
281
|
end
|
@@ -227,28 +289,28 @@ describe "InstanceHooks plugin with transactions" do
|
|
227
289
|
@db.sqls
|
228
290
|
end
|
229
291
|
|
230
|
-
|
292
|
+
deprecated "should support after_commit_hook" do
|
231
293
|
@o.after_commit_hook{@db.execute('ac1')}
|
232
294
|
@o.after_commit_hook{@db.execute('ac2')}
|
233
295
|
@o.save.wont_equal nil
|
234
296
|
@db.sqls.must_equal ['BEGIN', 'as', 'COMMIT', 'ac1', 'ac2']
|
235
297
|
end
|
236
298
|
|
237
|
-
|
299
|
+
deprecated "should support after_rollback_hook" do
|
238
300
|
@or.after_rollback_hook{@db.execute('ar1')}
|
239
301
|
@or.after_rollback_hook{@db.execute('ar2')}
|
240
302
|
@or.save.must_be_nil
|
241
303
|
@db.sqls.must_equal ['BEGIN', 'as', 'ROLLBACK', 'ar1', 'ar2']
|
242
304
|
end
|
243
305
|
|
244
|
-
|
306
|
+
deprecated "should support after_destroy_commit_hook" do
|
245
307
|
@o.after_destroy_commit_hook{@db.execute('adc1')}
|
246
308
|
@o.after_destroy_commit_hook{@db.execute('adc2')}
|
247
309
|
@o.destroy.wont_equal nil
|
248
310
|
@db.sqls.must_equal ['BEGIN', "DELETE FROM items WHERE (id = 1)", 'ad', 'COMMIT', 'adc1', 'adc2']
|
249
311
|
end
|
250
312
|
|
251
|
-
|
313
|
+
deprecated "should support after_destroy_rollback_hook" do
|
252
314
|
@or.after_destroy_rollback_hook{@db.execute('adr1')}
|
253
315
|
@or.after_destroy_rollback_hook{@db.execute('adr2')}
|
254
316
|
@or.destroy.must_be_nil
|
@@ -267,10 +329,12 @@ describe "InstanceHooks plugin with transactions" do
|
|
267
329
|
@o.after_save_hook{r 1}.must_be_same_as(@o)
|
268
330
|
@o.after_update_hook{r 1}.must_be_same_as(@o)
|
269
331
|
@o.after_create_hook{r 1}.must_be_same_as(@o)
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
332
|
+
deprecated do
|
333
|
+
@o.after_commit_hook{r 1}.must_be_same_as(@o)
|
334
|
+
@o.after_rollback_hook{r 1}.must_be_same_as(@o)
|
335
|
+
@o.after_destroy_commit_hook{r 1}.must_be_same_as(@o)
|
336
|
+
@o.after_destroy_rollback_hook{r 1}.must_be_same_as(@o)
|
337
|
+
end
|
274
338
|
end
|
275
339
|
|
276
340
|
end
|
@@ -42,6 +42,12 @@ describe "Sequel::Plugins::LazyAttributes" do
|
|
42
42
|
Object.send(:remove_const, :LazyAttributesModel)
|
43
43
|
end
|
44
44
|
|
45
|
+
deprecated "should allow access to lazy_attributes_module" do
|
46
|
+
@c.lazy_attributes_module.must_be_kind_of Module
|
47
|
+
@c.lazy_attributes_module = v = Module.new
|
48
|
+
@c.lazy_attributes_module.must_equal v
|
49
|
+
end
|
50
|
+
|
45
51
|
it "should allowing adding additional lazy attributes via plugin :lazy_attributes" do
|
46
52
|
@c.set_dataset(@ds.select(:id, :blah))
|
47
53
|
@c.dataset.sql.must_equal 'SELECT id, blah FROM la'
|
@@ -168,9 +174,9 @@ describe "Sequel::Plugins::LazyAttributes" do
|
|
168
174
|
@db.sqls.must_equal ["SELECT la.id FROM la LIMIT 1", "SELECT la.name FROM la WHERE (id = 1) LIMIT 1"]
|
169
175
|
end
|
170
176
|
|
171
|
-
it "should
|
177
|
+
it "should not allow additional lazy attributes after freezing" do
|
172
178
|
@c.plugin :lazy_attributes, :blah
|
173
179
|
@c.freeze
|
174
|
-
@c.
|
180
|
+
proc{@c.lazy_attributes :name}.must_raise RuntimeError, TypeError
|
175
181
|
end
|
176
182
|
end
|
@@ -440,7 +440,7 @@ describe Sequel::Model, "many_through_many" do
|
|
440
440
|
n = @c1.load(:id => 1234)
|
441
441
|
n.associations[:tags] = []
|
442
442
|
DB.sqls.must_equal []
|
443
|
-
n.tags(true).must_equal [@c2.load(:id=>1)]
|
443
|
+
n.tags(:reload=>true).must_equal [@c2.load(:id=>1)]
|
444
444
|
DB.sqls.must_equal ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id = 1234)']
|
445
445
|
n.associations[:tags].must_equal n.tags
|
446
446
|
DB.sqls.length.must_equal 0
|
@@ -1558,7 +1558,7 @@ describe Sequel::Model, "one_through_many" do
|
|
1558
1558
|
n = @c1.load(:id => 1234)
|
1559
1559
|
n.associations[:tag] = nil
|
1560
1560
|
DB.sqls.must_equal []
|
1561
|
-
n.tag(true).must_equal @c2.load(:id=>1)
|
1561
|
+
n.tag(:reload=>true).must_equal @c2.load(:id=>1)
|
1562
1562
|
DB.sqls.must_equal ['SELECT tags.* FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) INNER JOIN albums_artists ON (albums_artists.album_id = albums.id) WHERE (albums_artists.artist_id = 1234) LIMIT 1']
|
1563
1563
|
n.associations[:tag].must_equal n.tag
|
1564
1564
|
DB.sqls.length.must_equal 0
|
@@ -35,7 +35,7 @@ describe "MSSSQL optimistic locking plugin" do
|
|
35
35
|
@db.numrows = 0
|
36
36
|
@o.timestamp = '2345'
|
37
37
|
proc{@o.destroy}.must_raise(Sequel::NoExistingObject)
|
38
|
-
@db.sqls.must_equal ["DELETE FROM items WHERE ((id = 1) AND (timestamp = 0x32333435))"]
|
38
|
+
@db.sqls.must_equal ["DELETE TOP (1) FROM items WHERE ((id = 1) AND (timestamp = 0x32333435))"]
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should allow refresh after failed save" do
|
@@ -49,6 +49,12 @@ describe "NestedAttributes plugin" do
|
|
49
49
|
@db.sqls
|
50
50
|
end
|
51
51
|
|
52
|
+
deprecated "should allow access to nested_attributes_module" do
|
53
|
+
@Artist.nested_attributes_module.must_be_kind_of Module
|
54
|
+
@Artist.nested_attributes_module = v = Module.new
|
55
|
+
@Artist.nested_attributes_module.must_equal v
|
56
|
+
end
|
57
|
+
|
52
58
|
it "should support creating new many_to_one objects" do
|
53
59
|
a = @Album.new({:name=>'Al', :artist_attributes=>{:name=>'Ar'}})
|
54
60
|
@db.sqls.must_equal []
|
@@ -695,8 +701,8 @@ describe "NestedAttributes plugin" do
|
|
695
701
|
proc{@Album.load(:id=>10, :name=>'Al').set_nested_attributes(:tags, [{:id=>30, :name=>'T2', :number=>3}], :fields=>[:name])}.must_raise(Sequel::Error)
|
696
702
|
end
|
697
703
|
|
698
|
-
it "should
|
704
|
+
it "should not allow modifying ensted attributes after freezing" do
|
699
705
|
@Artist.freeze
|
700
|
-
@Artist.
|
706
|
+
proc{@Artist.nested_attributes :albums}.must_raise RuntimeError, TypeError
|
701
707
|
end
|
702
708
|
end
|
@@ -4,11 +4,9 @@ describe "pg_array extension" do
|
|
4
4
|
before(:all) do
|
5
5
|
Sequel.extension :pg_array
|
6
6
|
@pg_types = Sequel::Postgres::PG_TYPES.dup
|
7
|
-
@pg_named_types = Sequel::Postgres::PG_NAMED_TYPES.dup
|
8
7
|
end
|
9
8
|
after(:all) do
|
10
9
|
Sequel::Postgres::PG_TYPES.replace(@pg_types)
|
11
|
-
Sequel::Postgres::PG_NAMED_TYPES.replace(@pg_named_types)
|
12
10
|
end
|
13
11
|
|
14
12
|
before do
|
@@ -375,10 +373,10 @@ describe "pg_array extension" do
|
|
375
373
|
@db.typecast_value(:banana_array, %w'1 2').must_equal [1,2]
|
376
374
|
end
|
377
375
|
|
378
|
-
it "should set appropriate timestamp conversion procs when
|
379
|
-
Sequel::Postgres::PG_NAMED_TYPES[:foo] = proc{|v| v*2}
|
376
|
+
it "should set appropriate timestamp conversion procs when adding conversion procs" do
|
380
377
|
@db.fetch = [[{:oid=>2222, :typname=>'foo'}], [{:oid=>2222, :typarray=>2223, :typname=>'foo'}]]
|
381
378
|
@db.reset_conversion_procs
|
379
|
+
@db.add_named_conversion_proc(:foo){|v| v*2}
|
382
380
|
procs = @db.conversion_procs
|
383
381
|
procs[1185].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
|
384
382
|
procs[1115].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
|
@@ -386,6 +384,22 @@ describe "pg_array extension" do
|
|
386
384
|
procs[2223].call('{"2"}').must_equal ['22']
|
387
385
|
end
|
388
386
|
|
387
|
+
deprecated "should set appropriate timestamp conversion procs when resetting conversion procs when modifying PG_NAMED_TYPES" do
|
388
|
+
@pg_named_types = Sequel::Postgres::PG_NAMED_TYPES.dup
|
389
|
+
begin
|
390
|
+
Sequel::Postgres::PG_NAMED_TYPES[:foo] = proc{|v| v*2}
|
391
|
+
@db.fetch = [[{:oid=>2222, :typname=>'foo'}], [{:oid=>2222, :typarray=>2223, :typname=>'foo'}]]
|
392
|
+
@db.reset_conversion_procs
|
393
|
+
procs = @db.conversion_procs
|
394
|
+
procs[1185].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
|
395
|
+
procs[1115].call('{"2011-10-20 11:12:13"}').must_equal [Time.local(2011, 10, 20, 11, 12, 13)]
|
396
|
+
procs[2222].call('1').must_equal '11'
|
397
|
+
procs[2223].call('{"2"}').must_equal ['22']
|
398
|
+
ensure
|
399
|
+
Sequel::Postgres::PG_NAMED_TYPES.replace(@pg_named_types)
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
389
403
|
it "should return correct results for Database#schema_type_class" do
|
390
404
|
@db.register_array_type('banana', :oid=>7866, :scalar_typecast=>:integer){|s| s.to_i}
|
391
405
|
@db.schema_type_class(:banana_array).must_equal Sequel::Postgres::PGArray
|
@@ -2,34 +2,36 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
|
|
2
2
|
|
3
3
|
describe "Sequel::Plugins::PreparedStatementsAssociations" do
|
4
4
|
before do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
deprecated do
|
6
|
+
@db = Sequel.mock(:servers=>{:foo=>{}})
|
7
|
+
@db.extend_datasets do
|
8
|
+
def select_sql
|
9
|
+
sql = super
|
10
|
+
sql << ' -- prepared' if is_a?(Sequel::Dataset::PreparedStatementMethods)
|
11
|
+
sql
|
12
|
+
end
|
11
13
|
end
|
14
|
+
@Artist = Class.new(Sequel::Model(@db[:artists]))
|
15
|
+
@Artist.columns :id, :id2
|
16
|
+
@Album= Class.new(Sequel::Model(@db[:albums]))
|
17
|
+
@Album.columns :id, :artist_id, :id2, :artist_id2
|
18
|
+
@Tag = Class.new(Sequel::Model(@db[:tags]))
|
19
|
+
@Tag.columns :id, :id2
|
20
|
+
@Artist.plugin :prepared_statements_associations
|
21
|
+
@Album.plugin :prepared_statements_associations
|
22
|
+
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
23
|
+
@Artist.one_to_one :album, :class=>@Album, :key=>:artist_id
|
24
|
+
@Album.many_to_one :artist, :class=>@Artist
|
25
|
+
@Album.many_to_many :tags, :class=>@Tag, :join_table=>:albums_tags, :left_key=>:album_id
|
26
|
+
@Album.one_through_one :tag, :clone=>:tags
|
27
|
+
@Artist.plugin :many_through_many
|
28
|
+
@Artist.many_through_many :tags, [[:albums, :artist_id, :id], [:albums_tags, :album_id, :tag_id]], :class=>@Tag
|
29
|
+
@Artist.one_through_many :tag, :clone=>:tags
|
30
|
+
@db.sqls
|
12
31
|
end
|
13
|
-
@Artist = Class.new(Sequel::Model(@db[:artists]))
|
14
|
-
@Artist.columns :id, :id2
|
15
|
-
@Album= Class.new(Sequel::Model(@db[:albums]))
|
16
|
-
@Album.columns :id, :artist_id, :id2, :artist_id2
|
17
|
-
@Tag = Class.new(Sequel::Model(@db[:tags]))
|
18
|
-
@Tag.columns :id, :id2
|
19
|
-
@Artist.plugin :prepared_statements_associations
|
20
|
-
@Album.plugin :prepared_statements_associations
|
21
|
-
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
22
|
-
@Artist.one_to_one :album, :class=>@Album, :key=>:artist_id
|
23
|
-
@Album.many_to_one :artist, :class=>@Artist
|
24
|
-
@Album.many_to_many :tags, :class=>@Tag, :join_table=>:albums_tags, :left_key=>:album_id
|
25
|
-
@Album.one_through_one :tag, :clone=>:tags
|
26
|
-
@Artist.plugin :many_through_many
|
27
|
-
@Artist.many_through_many :tags, [[:albums, :artist_id, :id], [:albums_tags, :album_id, :tag_id]], :class=>@Tag
|
28
|
-
@Artist.one_through_many :tag, :clone=>:tags
|
29
|
-
@db.sqls
|
30
32
|
end
|
31
33
|
|
32
|
-
|
34
|
+
deprecated "should run correct SQL for associations" do
|
33
35
|
@Artist.load(:id=>1).albums
|
34
36
|
@db.sqls.must_equal ["SELECT id, artist_id, id2, artist_id2 FROM albums WHERE (albums.artist_id = 1) -- prepared"]
|
35
37
|
|
@@ -52,7 +54,7 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
|
|
52
54
|
@db.sqls.must_equal ["SELECT tags.id, tags.id2 FROM tags INNER JOIN albums_tags ON (albums_tags.tag_id = tags.id) INNER JOIN albums ON (albums.id = albums_tags.album_id) WHERE (albums.artist_id = 1) LIMIT 1 -- prepared"]
|
53
55
|
end
|
54
56
|
|
55
|
-
|
57
|
+
deprecated "should run correct shard for associations when also using sharding plugin" do
|
56
58
|
@Artist.plugin :sharding
|
57
59
|
@Album.plugin :sharding
|
58
60
|
|
@@ -84,12 +86,12 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
|
|
84
86
|
@db.sqls.must_equal ["SELECT albums.id, albums.artist_id, albums.id2, albums.artist_id2 FROM albums INNER JOIN albums_tags ON (albums_tags.album_id = albums.id) WHERE (albums_tags.tag_id = 1) -- prepared -- foo"]
|
85
87
|
end
|
86
88
|
|
87
|
-
|
89
|
+
deprecated "should not override the shard for associations if not using the sharding plugin" do
|
88
90
|
@Artist.load(:id=>1).set_server(:foo).albums
|
89
91
|
@db.sqls.must_equal ["SELECT id, artist_id, id2, artist_id2 FROM albums WHERE (albums.artist_id = 1) -- prepared"]
|
90
92
|
end
|
91
93
|
|
92
|
-
|
94
|
+
deprecated "should run correct SQL for composite key associations" do
|
93
95
|
@Artist.one_to_many :albums, :class=>@Album, :key=>[:artist_id, :artist_id2], :primary_key=>[:id, :id2]
|
94
96
|
@Artist.one_to_one :album, :class=>@Album, :key=>[:artist_id, :artist_id2], :primary_key=>[:id, :id2]
|
95
97
|
@Album.many_to_one :artist, :class=>@Artist, :key=>[:artist_id, :artist_id2], :primary_key=>[:id, :id2]
|
@@ -121,13 +123,13 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
|
|
121
123
|
@db.sqls.must_equal ["SELECT tags.id, tags.id2 FROM tags INNER JOIN albums_tags ON ((albums_tags.tag_id = tags.id) AND (albums_tags.tag_id2 = tags.id2)) INNER JOIN albums ON ((albums.id = albums_tags.album_id) AND (albums.id2 = albums_tags.album_id2)) WHERE ((albums.artist_id = 1) AND (albums.artist_id2 = 2)) LIMIT 1 -- prepared"]
|
122
124
|
end
|
123
125
|
|
124
|
-
|
126
|
+
deprecated "should not run query if no objects can be associated" do
|
125
127
|
@Artist.new.albums.must_equal []
|
126
128
|
@Album.new.artist.must_be_nil
|
127
129
|
@db.sqls.must_equal []
|
128
130
|
end
|
129
131
|
|
130
|
-
|
132
|
+
deprecated "should run a regular query if not caching association metadata" do
|
131
133
|
@Artist.cache_associations = false
|
132
134
|
@Artist.load(:id=>1).albums
|
133
135
|
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
@@ -135,66 +137,73 @@ describe "Sequel::Plugins::PreparedStatementsAssociations" do
|
|
135
137
|
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1) LIMIT 1"]
|
136
138
|
end
|
137
139
|
|
138
|
-
|
140
|
+
deprecated "should run a regular query if there is a callback" do
|
139
141
|
@Artist.load(:id=>1).albums(proc{|ds| ds})
|
140
142
|
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
141
143
|
@Artist.load(:id=>1).album(proc{|ds| ds})
|
142
144
|
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1) LIMIT 1"]
|
143
145
|
end
|
144
146
|
|
145
|
-
|
147
|
+
deprecated "should run a regular query if there is a block" do
|
148
|
+
@Artist.load(:id=>1).albums{|ds| ds}
|
149
|
+
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
150
|
+
@Artist.load(:id=>1).album{|ds| ds}
|
151
|
+
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1) LIMIT 1"]
|
152
|
+
end
|
153
|
+
|
154
|
+
deprecated "should run a regular query if :prepared_statement=>false option is used for the association" do
|
146
155
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :prepared_statement=>false
|
147
156
|
@Artist.load(:id=>1).albums
|
148
157
|
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
149
158
|
end
|
150
159
|
|
151
|
-
|
160
|
+
deprecated "should run a regular query if unrecognized association is used" do
|
152
161
|
a = @Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
153
162
|
a[:type] = :foo
|
154
163
|
@Artist.load(:id=>1).albums
|
155
164
|
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
156
165
|
end
|
157
166
|
|
158
|
-
|
167
|
+
deprecated "should run a regular query if a block is used when defining the association" do
|
159
168
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id do |ds| ds end
|
160
169
|
@Artist.load(:id=>1).albums
|
161
170
|
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
162
171
|
end
|
163
172
|
|
164
|
-
|
173
|
+
deprecated "should use a prepared statement if the associated dataset has conditions" do
|
165
174
|
@Album.dataset = @Album.dataset.where(:a=>2)
|
166
175
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id
|
167
176
|
@Artist.load(:id=>1).albums
|
168
177
|
@db.sqls.must_equal ["SELECT id, artist_id, id2, artist_id2 FROM albums WHERE ((a = 2) AND (albums.artist_id = 1)) -- prepared"]
|
169
178
|
end
|
170
179
|
|
171
|
-
|
180
|
+
deprecated "should use a prepared statement if the :conditions association option" do
|
172
181
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :conditions=>{:a=>2}
|
173
182
|
@Artist.load(:id=>1).albums
|
174
183
|
@db.sqls.must_equal ["SELECT id, artist_id, id2, artist_id2 FROM albums WHERE ((a = 2) AND (albums.artist_id = 1)) -- prepared"]
|
175
184
|
end
|
176
185
|
|
177
|
-
|
186
|
+
deprecated "should not use a prepared statement if :conditions association option uses an identifier" do
|
178
187
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id, :conditions=>{Sequel.identifier('a')=>2}
|
179
188
|
@Artist.load(:id=>1).albums
|
180
189
|
@db.sqls.must_equal ["SELECT id, artist_id, id2, artist_id2 FROM albums WHERE ((a = 2) AND (albums.artist_id = 1)) -- prepared"]
|
181
190
|
end
|
182
191
|
|
183
|
-
|
192
|
+
deprecated "should run a regular query if :dataset option is used when defining the association" do
|
184
193
|
album = @Album
|
185
194
|
@Artist.one_to_many :albums, :class=>@Album, :dataset=>proc{album.filter(:artist_id=>id)}
|
186
195
|
@Artist.load(:id=>1).albums
|
187
196
|
@db.sqls.must_equal ["SELECT * FROM albums WHERE (artist_id = 1)"]
|
188
197
|
end
|
189
198
|
|
190
|
-
|
199
|
+
deprecated "should run a regular query if :cloning an association that doesn't used prepared statements" do
|
191
200
|
@Artist.one_to_many :albums, :class=>@Album, :key=>:artist_id do |ds| ds end
|
192
201
|
@Artist.one_to_many :oalbums, :clone=>:albums
|
193
202
|
@Artist.load(:id=>1).oalbums
|
194
203
|
@db.sqls.must_equal ["SELECT * FROM albums WHERE (albums.artist_id = 1)"]
|
195
204
|
end
|
196
205
|
|
197
|
-
|
206
|
+
deprecated "should work correctly when using an instance specific association" do
|
198
207
|
tag = @Tag
|
199
208
|
@Artist.many_to_one :tag, :key=>nil, :read_only=>true, :dataset=>proc{tag.where(:id=>id).limit(1)}, :reciprocal=>nil, :reciprocal_type=>nil
|
200
209
|
@Artist.load(:id=>1).tag.must_be_nil
|