sequel 3.37.0 → 3.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +56 -0
- data/README.rdoc +82 -58
- data/Rakefile +6 -5
- data/bin/sequel +1 -1
- data/doc/active_record.rdoc +67 -52
- data/doc/advanced_associations.rdoc +33 -48
- data/doc/association_basics.rdoc +41 -51
- data/doc/cheat_sheet.rdoc +21 -21
- data/doc/core_extensions.rdoc +374 -0
- data/doc/dataset_basics.rdoc +5 -5
- data/doc/dataset_filtering.rdoc +47 -43
- data/doc/mass_assignment.rdoc +1 -1
- data/doc/migration.rdoc +4 -5
- data/doc/model_hooks.rdoc +3 -3
- data/doc/object_model.rdoc +31 -25
- data/doc/opening_databases.rdoc +19 -5
- data/doc/prepared_statements.rdoc +2 -2
- data/doc/querying.rdoc +109 -52
- data/doc/reflection.rdoc +6 -6
- data/doc/release_notes/3.38.0.txt +234 -0
- data/doc/schema_modification.rdoc +22 -13
- data/doc/sharding.rdoc +8 -9
- data/doc/sql.rdoc +154 -112
- data/doc/testing.rdoc +47 -7
- data/doc/thread_safety.rdoc +1 -1
- data/doc/transactions.rdoc +1 -1
- data/doc/validations.rdoc +1 -1
- data/doc/virtual_rows.rdoc +29 -43
- data/lib/sequel/adapters/do/postgres.rb +1 -4
- data/lib/sequel/adapters/jdbc.rb +14 -3
- data/lib/sequel/adapters/jdbc/db2.rb +9 -0
- data/lib/sequel/adapters/jdbc/derby.rb +41 -4
- data/lib/sequel/adapters/jdbc/jtds.rb +11 -0
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -6
- data/lib/sequel/adapters/mock.rb +10 -4
- data/lib/sequel/adapters/postgres.rb +1 -28
- data/lib/sequel/adapters/shared/mssql.rb +23 -13
- data/lib/sequel/adapters/shared/postgres.rb +46 -0
- data/lib/sequel/adapters/swift.rb +21 -13
- data/lib/sequel/adapters/swift/mysql.rb +1 -0
- data/lib/sequel/adapters/swift/postgres.rb +4 -5
- data/lib/sequel/adapters/swift/sqlite.rb +2 -1
- data/lib/sequel/adapters/tinytds.rb +14 -2
- data/lib/sequel/adapters/utils/pg_types.rb +5 -0
- data/lib/sequel/core.rb +29 -17
- data/lib/sequel/database/query.rb +1 -1
- data/lib/sequel/database/schema_generator.rb +3 -0
- data/lib/sequel/dataset/actions.rb +5 -6
- data/lib/sequel/dataset/query.rb +7 -7
- data/lib/sequel/dataset/sql.rb +5 -18
- data/lib/sequel/extensions/core_extensions.rb +8 -12
- data/lib/sequel/extensions/pg_array.rb +59 -33
- data/lib/sequel/extensions/pg_array_ops.rb +32 -4
- data/lib/sequel/extensions/pg_auto_parameterize.rb +1 -1
- data/lib/sequel/extensions/pg_hstore.rb +32 -17
- data/lib/sequel/extensions/pg_hstore_ops.rb +32 -3
- data/lib/sequel/extensions/pg_inet.rb +1 -2
- data/lib/sequel/extensions/pg_interval.rb +0 -1
- data/lib/sequel/extensions/pg_json.rb +41 -23
- data/lib/sequel/extensions/pg_range.rb +36 -11
- data/lib/sequel/extensions/pg_range_ops.rb +32 -4
- data/lib/sequel/extensions/pg_row.rb +572 -0
- data/lib/sequel/extensions/pg_row_ops.rb +164 -0
- data/lib/sequel/extensions/query.rb +3 -3
- data/lib/sequel/extensions/schema_dumper.rb +7 -8
- data/lib/sequel/extensions/select_remove.rb +1 -1
- data/lib/sequel/model/base.rb +1 -0
- data/lib/sequel/no_core_ext.rb +1 -1
- data/lib/sequel/plugins/pg_row.rb +121 -0
- data/lib/sequel/plugins/pg_typecast_on_load.rb +65 -0
- data/lib/sequel/plugins/validation_helpers.rb +31 -0
- data/lib/sequel/sql.rb +64 -44
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +37 -12
- data/spec/adapters/mysql_spec.rb +39 -75
- data/spec/adapters/oracle_spec.rb +11 -11
- data/spec/adapters/postgres_spec.rb +414 -237
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +14 -14
- data/spec/core/database_spec.rb +6 -6
- data/spec/core/dataset_spec.rb +169 -205
- data/spec/core/expression_filters_spec.rb +182 -295
- data/spec/core/object_graph_spec.rb +6 -6
- data/spec/core/schema_spec.rb +14 -14
- data/spec/core/spec_helper.rb +1 -0
- data/spec/{extensions/core_extensions_spec.rb → core_extensions_spec.rb} +208 -14
- data/spec/extensions/columns_introspection_spec.rb +5 -5
- data/spec/extensions/hook_class_methods_spec.rb +28 -36
- data/spec/extensions/many_through_many_spec.rb +4 -4
- data/spec/extensions/pg_array_ops_spec.rb +15 -7
- data/spec/extensions/pg_array_spec.rb +81 -48
- data/spec/extensions/pg_auto_parameterize_spec.rb +2 -2
- data/spec/extensions/pg_hstore_ops_spec.rb +13 -9
- data/spec/extensions/pg_hstore_spec.rb +66 -65
- data/spec/extensions/pg_inet_spec.rb +2 -4
- data/spec/extensions/pg_interval_spec.rb +2 -3
- data/spec/extensions/pg_json_spec.rb +20 -18
- data/spec/extensions/pg_range_ops_spec.rb +11 -4
- data/spec/extensions/pg_range_spec.rb +30 -7
- data/spec/extensions/pg_row_ops_spec.rb +48 -0
- data/spec/extensions/pg_row_plugin_spec.rb +45 -0
- data/spec/extensions/pg_row_spec.rb +323 -0
- data/spec/extensions/pg_typecast_on_load_spec.rb +58 -0
- data/spec/extensions/query_literals_spec.rb +11 -11
- data/spec/extensions/query_spec.rb +3 -3
- data/spec/extensions/schema_dumper_spec.rb +20 -4
- data/spec/extensions/schema_spec.rb +18 -41
- data/spec/extensions/select_remove_spec.rb +4 -4
- data/spec/extensions/spec_helper.rb +4 -8
- data/spec/extensions/to_dot_spec.rb +5 -5
- data/spec/extensions/validation_class_methods_spec.rb +28 -16
- data/spec/integration/associations_test.rb +20 -20
- data/spec/integration/dataset_test.rb +98 -98
- data/spec/integration/eager_loader_test.rb +13 -27
- data/spec/integration/plugin_test.rb +5 -5
- data/spec/integration/prepared_statement_test.rb +22 -13
- data/spec/integration/schema_test.rb +28 -18
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/integration/timezone_test.rb +2 -2
- data/spec/integration/type_test.rb +15 -6
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +4 -4
- data/spec/model/base_spec.rb +5 -5
- data/spec/model/eager_loading_spec.rb +15 -15
- data/spec/model/model_spec.rb +32 -32
- data/spec/model/record_spec.rb +16 -0
- data/spec/model/spec_helper.rb +2 -6
- data/spec/model/validations_spec.rb +1 -1
- metadata +16 -4
|
@@ -333,7 +333,7 @@ describe "Polymorphic Associations" do
|
|
|
333
333
|
many_to_one :attachable, :reciprocal=>:assets, \
|
|
334
334
|
:dataset=>(proc do
|
|
335
335
|
klass = m.call(attachable_type)
|
|
336
|
-
klass.
|
|
336
|
+
klass.where(klass.primary_key=>attachable_id)
|
|
337
337
|
end), \
|
|
338
338
|
:eager_loader=>(proc do |eo|
|
|
339
339
|
id_map = {}
|
|
@@ -343,7 +343,7 @@ describe "Polymorphic Associations" do
|
|
|
343
343
|
end
|
|
344
344
|
id_map.each do |klass_name, id_map|
|
|
345
345
|
klass = m.call(klass_name)
|
|
346
|
-
klass.
|
|
346
|
+
klass.where(klass.primary_key=>id_map.keys).all do |attach|
|
|
347
347
|
id_map[attach.pk].each do |asset|
|
|
348
348
|
asset.associations[:attachable] = attach
|
|
349
349
|
end
|
|
@@ -363,25 +363,18 @@ describe "Polymorphic Associations" do
|
|
|
363
363
|
primary_key :id
|
|
364
364
|
end
|
|
365
365
|
class ::Post < Sequel::Model
|
|
366
|
-
one_to_many :assets, :key=>:attachable_id, :reciprocal=>:attachable
|
|
367
|
-
ds.filter(:attachable_type=>'Post')
|
|
368
|
-
end
|
|
366
|
+
one_to_many :assets, :key=>:attachable_id, :reciprocal=>:attachable, :conditions=>{:attachable_type=>'Post'}
|
|
369
367
|
|
|
370
368
|
private
|
|
371
369
|
|
|
372
370
|
def _add_asset(asset)
|
|
373
|
-
asset.attachable_id
|
|
374
|
-
asset.attachable_type = 'Post'
|
|
375
|
-
asset.save
|
|
371
|
+
asset.update(:attachable_id=>pk, :attachable_type=>'Post')
|
|
376
372
|
end
|
|
377
373
|
def _remove_asset(asset)
|
|
378
|
-
asset.attachable_id
|
|
379
|
-
asset.attachable_type = nil
|
|
380
|
-
asset.save
|
|
374
|
+
asset.update(:attachable_id=>nil, :attachable_type=>nil)
|
|
381
375
|
end
|
|
382
376
|
def _remove_all_assets
|
|
383
|
-
|
|
384
|
-
.update(:attachable_id=>nil, :attachable_type=>nil)
|
|
377
|
+
assets_dataset.update(:attachable_id=>nil, :attachable_type=>nil)
|
|
385
378
|
end
|
|
386
379
|
end
|
|
387
380
|
|
|
@@ -389,25 +382,18 @@ describe "Polymorphic Associations" do
|
|
|
389
382
|
primary_key :id
|
|
390
383
|
end
|
|
391
384
|
class ::Note < Sequel::Model
|
|
392
|
-
one_to_many :assets, :key=>:attachable_id, :reciprocal=>:attachable
|
|
393
|
-
|
|
394
|
-
end
|
|
395
|
-
|
|
385
|
+
one_to_many :assets, :key=>:attachable_id, :reciprocal=>:attachable, :conditions=>{:attachable_type=>'Note'}
|
|
386
|
+
|
|
396
387
|
private
|
|
397
388
|
|
|
398
389
|
def _add_asset(asset)
|
|
399
|
-
asset.attachable_id
|
|
400
|
-
asset.attachable_type = 'Note'
|
|
401
|
-
asset.save
|
|
390
|
+
asset.update(:attachable_id=>pk, :attachable_type=>'Note')
|
|
402
391
|
end
|
|
403
392
|
def _remove_asset(asset)
|
|
404
|
-
asset.attachable_id
|
|
405
|
-
asset.attachable_type = nil
|
|
406
|
-
asset.save
|
|
393
|
+
asset.update(:attachable_id=>nil, :attachable_type=>nil)
|
|
407
394
|
end
|
|
408
395
|
def _remove_all_assets
|
|
409
|
-
|
|
410
|
-
.update(:attachable_id=>nil, :attachable_type=>nil)
|
|
396
|
+
assets_dataset.update(:attachable_id=>nil, :attachable_type=>nil)
|
|
411
397
|
end
|
|
412
398
|
end
|
|
413
399
|
end
|
|
@@ -630,8 +616,8 @@ describe "statistics associations" do
|
|
|
630
616
|
:eager_loader=>(proc do |eo|
|
|
631
617
|
eo[:rows].each{|p| p.associations[:ticket_hours] = nil}
|
|
632
618
|
Ticket.filter(:project_id=>eo[:id_map].keys).
|
|
633
|
-
|
|
634
|
-
|
|
619
|
+
select_group(:project_id).
|
|
620
|
+
select_append{sum(hours).as(hours)}.
|
|
635
621
|
all do |t|
|
|
636
622
|
p = eo[:id_map][t.values.delete(:project_id)].first
|
|
637
623
|
p.associations[:ticket_hours] = t
|
|
@@ -199,7 +199,7 @@ describe "Many Through Many Plugin" do
|
|
|
199
199
|
end
|
|
200
200
|
|
|
201
201
|
def self_join(c)
|
|
202
|
-
c.join(c.table_name
|
|
202
|
+
c.join(Sequel.as(c.table_name, :b), Array(c.primary_key).zip(Array(c.primary_key))).select_all(c.table_name)
|
|
203
203
|
end
|
|
204
204
|
|
|
205
205
|
specify "should handle super simple case with 1 join table" do
|
|
@@ -1265,7 +1265,7 @@ describe "List plugin with a scope" do
|
|
|
1265
1265
|
@db.drop_table?(:pages)
|
|
1266
1266
|
end
|
|
1267
1267
|
|
|
1268
|
-
|
|
1268
|
+
specify "should return rows in order of position" do
|
|
1269
1269
|
@c.map(:name).should == %w[ Hm Ps Au P1 P2 P3 ]
|
|
1270
1270
|
end
|
|
1271
1271
|
|
|
@@ -1286,7 +1286,7 @@ describe "List plugin with a scope" do
|
|
|
1286
1286
|
@c[:name => "P3"].next.should == nil
|
|
1287
1287
|
end
|
|
1288
1288
|
|
|
1289
|
-
|
|
1289
|
+
specify "should define move_to" do
|
|
1290
1290
|
@c[:name => "P2"].move_to(1)
|
|
1291
1291
|
@c.map(:name).should == %w[ Hm Ps Au P2 P1 P3 ]
|
|
1292
1292
|
|
|
@@ -1297,7 +1297,7 @@ describe "List plugin with a scope" do
|
|
|
1297
1297
|
proc { @c[:name => "P2"].move_to(10) }.should raise_error(Sequel::Error)
|
|
1298
1298
|
end
|
|
1299
1299
|
|
|
1300
|
-
|
|
1300
|
+
specify "should define move_to_top and move_to_bottom" do
|
|
1301
1301
|
@c[:name => "Au"].move_to_top
|
|
1302
1302
|
@c.map(:name).should == %w[ Hm Au Ps P1 P2 P3 ]
|
|
1303
1303
|
|
|
@@ -1305,7 +1305,7 @@ describe "List plugin with a scope" do
|
|
|
1305
1305
|
@c.map(:name).should == %w[ Hm Ps Au P1 P2 P3 ]
|
|
1306
1306
|
end
|
|
1307
1307
|
|
|
1308
|
-
|
|
1308
|
+
specify "should define move_up and move_down" do
|
|
1309
1309
|
@c[:name => "P2"].move_up
|
|
1310
1310
|
@c.map(:name).should == %w[ Hm Ps Au P2 P1 P3 ]
|
|
1311
1311
|
|
|
@@ -123,7 +123,7 @@ describe "Prepared Statements and Bound Arguments" do
|
|
|
123
123
|
end
|
|
124
124
|
|
|
125
125
|
specify "should support bound variables with update" do
|
|
126
|
-
@ds.filter(:numb=>:$n).call(:update, {:n=>10, :nn=>20}, :numb
|
|
126
|
+
@ds.filter(:numb=>:$n).call(:update, {:n=>10, :nn=>20}, :numb=>Sequel.+(:numb, :$nn)).should == 1
|
|
127
127
|
@ds.all.should == [{:id=>1, :numb=>30}]
|
|
128
128
|
end
|
|
129
129
|
|
|
@@ -235,7 +235,7 @@ describe "Prepared Statements and Bound Arguments" do
|
|
|
235
235
|
end
|
|
236
236
|
|
|
237
237
|
specify "should support prepared statements with update" do
|
|
238
|
-
@ds.filter(:numb=>:$n).prepare(:update, :update_n, :numb
|
|
238
|
+
@ds.filter(:numb=>:$n).prepare(:update, :update_n, :numb=>Sequel.+(:numb, :$nn))
|
|
239
239
|
@db.call(:update_n, :n=>10, :nn=>20).should == 1
|
|
240
240
|
@ds.all.should == [{:id=>1, :numb=>30}]
|
|
241
241
|
end
|
|
@@ -287,12 +287,12 @@ describe "Bound Argument Types" do
|
|
|
287
287
|
@ds.filter(:d=>:$x).prepare(:first, :ps_date).call(:x=>@vs[:d])[:d].should == @vs[:d]
|
|
288
288
|
end
|
|
289
289
|
|
|
290
|
-
cspecify "should handle datetime type", [:do], [:mysql2], [:
|
|
290
|
+
cspecify "should handle datetime type", [:do], [:mysql2], [:jdbc, :sqlite], [:tinytds], [:oracle] do
|
|
291
291
|
Sequel.datetime_class = DateTime
|
|
292
292
|
@ds.filter(:dt=>:$x).prepare(:first, :ps_datetime).call(:x=>@vs[:dt])[:dt].should == @vs[:dt]
|
|
293
293
|
end
|
|
294
294
|
|
|
295
|
-
cspecify "should handle datetime type with fractional seconds", [:do], [:mysql2], [:
|
|
295
|
+
cspecify "should handle datetime type with fractional seconds", [:do], [:mysql2], [:jdbc, :sqlite], [:tinytds], [:oracle] do
|
|
296
296
|
Sequel.datetime_class = DateTime
|
|
297
297
|
fract_time = DateTime.parse('2010-10-12 13:14:15.500000')
|
|
298
298
|
@ds.prepare(:update, :ps_datetime_up, :dt=>:$x).call(:x=>fract_time)
|
|
@@ -303,20 +303,29 @@ describe "Bound Argument Types" do
|
|
|
303
303
|
@ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>@vs[:t])[:t].should == @vs[:t]
|
|
304
304
|
end
|
|
305
305
|
|
|
306
|
-
cspecify "should handle time type with fractional seconds", [:do], [:jdbc, :sqlite], [:oracle] do
|
|
306
|
+
cspecify "should handle time type with fractional seconds", [:do], [:jdbc, :sqlite], [:oracle], [:swift, :postgres] do
|
|
307
307
|
fract_time = @vs[:t] + 0.5
|
|
308
308
|
@ds.prepare(:update, :ps_time_up, :t=>:$x).call(:x=>fract_time)
|
|
309
309
|
@ds.literal(@ds.filter(:t=>:$x).prepare(:first, :ps_time).call(:x=>fract_time)[:t]).should == @ds.literal(fract_time)
|
|
310
310
|
end
|
|
311
311
|
|
|
312
|
-
cspecify "should handle blob type", [:
|
|
313
|
-
@ds.
|
|
312
|
+
cspecify "should handle blob type", [:odbc], [:oracle] do
|
|
313
|
+
@ds.delete
|
|
314
|
+
@ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>@vs[:file])
|
|
315
|
+
@ds.get(:file).should == @vs[:file]
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
cspecify "should handle blob type with nil values", [:oracle], [:tinytds], [:jdbc, proc{|db| defined?(Sequel::JDBC::SQLServer::DatabaseMethods) && db.is_a?(Sequel::JDBC::SQLServer::DatabaseMethods)}] do
|
|
319
|
+
@ds.delete
|
|
320
|
+
@ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>nil)
|
|
321
|
+
@ds.get(:file).should == nil
|
|
314
322
|
end
|
|
315
323
|
|
|
316
|
-
cspecify "should handle blob type with embedded zeros", [:
|
|
324
|
+
cspecify "should handle blob type with embedded zeros", [:odbc], [:oracle] do
|
|
317
325
|
zero_blob = Sequel::SQL::Blob.new("a\0"*100)
|
|
318
|
-
@ds.
|
|
319
|
-
@ds.
|
|
326
|
+
@ds.delete
|
|
327
|
+
@ds.prepare(:insert, :ps_blob, {:file=>:$x}).call(:x=>zero_blob)
|
|
328
|
+
@ds.get(:file).should == zero_blob
|
|
320
329
|
end
|
|
321
330
|
|
|
322
331
|
cspecify "should handle float type", [:swift, :sqlite] do
|
|
@@ -330,7 +339,7 @@ describe "Bound Argument Types" do
|
|
|
330
339
|
cspecify "should handle boolean type", [:do, :sqlite], [:odbc, :mssql], [:jdbc, :sqlite], [:jdbc, :db2], :oracle do
|
|
331
340
|
@ds.filter(:b=>:$x).prepare(:first, :ps_string).call(:x=>@vs[:b])[:b].should == @vs[:b]
|
|
332
341
|
end
|
|
333
|
-
end
|
|
342
|
+
end
|
|
334
343
|
|
|
335
344
|
describe "Dataset#unbind" do
|
|
336
345
|
before do
|
|
@@ -393,8 +402,8 @@ describe "Dataset#unbind" do
|
|
|
393
402
|
Integer :d
|
|
394
403
|
end
|
|
395
404
|
@ds.insert(:a=>2, :b=>0, :c=>3, :d=>5)
|
|
396
|
-
@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and({~
|
|
397
|
-
@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and({~
|
|
405
|
+
@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and(Sequel.case({~Sequel.expr(:d=>4)=>1}, 0) => 1)].should == {:a=>2, :b=>0, :c=>3, :d=>5}
|
|
406
|
+
@u[@ds.filter{a > 1}.and{b < 2}.or(:c=>3).and(Sequel.case({~Sequel.expr(:d=>5)=>1}, 0) => 1)].should == nil
|
|
398
407
|
end
|
|
399
408
|
|
|
400
409
|
specify "should handle case where the same variable has the same value in multiple places " do
|
|
@@ -239,7 +239,9 @@ describe "Database schema modifiers" do
|
|
|
239
239
|
@ds = @db[:items]
|
|
240
240
|
end
|
|
241
241
|
after do
|
|
242
|
-
|
|
242
|
+
# Use instead of drop_table? to work around issues on jdbc/db2
|
|
243
|
+
@db.drop_table(:items) rescue nil
|
|
244
|
+
@db.drop_table(:items2) rescue nil
|
|
243
245
|
end
|
|
244
246
|
|
|
245
247
|
specify "should create tables correctly" do
|
|
@@ -526,30 +528,40 @@ describe "Database schema modifiers" do
|
|
|
526
528
|
proc{@ds.insert(1, 2)}.should_not raise_error
|
|
527
529
|
end
|
|
528
530
|
|
|
529
|
-
|
|
531
|
+
specify "should remove columns from tables correctly" do
|
|
532
|
+
@db.create_table!(:items) do
|
|
533
|
+
primary_key :id
|
|
534
|
+
Integer :i
|
|
535
|
+
end
|
|
536
|
+
@ds.insert(:i=>10)
|
|
537
|
+
@db.drop_column(:items, :i)
|
|
538
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
specify "should remove columns with defaults from tables correctly" do
|
|
542
|
+
@db.create_table!(:items) do
|
|
543
|
+
primary_key :id
|
|
544
|
+
Integer :i, :default=>20
|
|
545
|
+
end
|
|
546
|
+
@ds.insert(:i=>10)
|
|
547
|
+
@db.drop_column(:items, :i)
|
|
548
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
cspecify "should remove foreign key columns from tables correctly", :h2, :mssql, :hsqldb do
|
|
530
552
|
# MySQL with InnoDB cannot drop foreign key columns unless you know the
|
|
531
553
|
# name of the constraint, see Bug #14347
|
|
532
554
|
@db.create_table!(:items, :engine=>:MyISAM) do
|
|
533
555
|
primary_key :id
|
|
534
|
-
|
|
535
|
-
Integer :number
|
|
556
|
+
Integer :i
|
|
536
557
|
foreign_key :item_id, :items
|
|
537
558
|
end
|
|
538
|
-
@ds.insert(:
|
|
539
|
-
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number, :item_id]
|
|
540
|
-
@ds.columns!.should == [:id, :name, :number, :item_id]
|
|
541
|
-
@db.drop_column(:items, :number)
|
|
542
|
-
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :item_id]
|
|
543
|
-
@ds.columns!.should == [:id, :name, :item_id]
|
|
544
|
-
@db.drop_column(:items, :name)
|
|
545
|
-
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
|
546
|
-
@ds.columns!.should == [:id, :item_id]
|
|
559
|
+
@ds.insert(:i=>10)
|
|
547
560
|
@db.drop_column(:items, :item_id)
|
|
548
|
-
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
|
549
|
-
@ds.columns!.should == [:id]
|
|
561
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :i]
|
|
550
562
|
end
|
|
551
563
|
|
|
552
|
-
|
|
564
|
+
specify "should remove multiple columns in a single alter_table block" do
|
|
553
565
|
@db.create_table!(:items) do
|
|
554
566
|
primary_key :id
|
|
555
567
|
String :name
|
|
@@ -557,13 +569,11 @@ describe "Database schema modifiers" do
|
|
|
557
569
|
end
|
|
558
570
|
@ds.insert(:number=>10)
|
|
559
571
|
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :name, :number]
|
|
560
|
-
@ds.columns!.should == [:id, :name, :number]
|
|
561
572
|
@db.alter_table(:items) do
|
|
562
573
|
drop_column :name
|
|
563
574
|
drop_column :number
|
|
564
575
|
end
|
|
565
576
|
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:id]
|
|
566
|
-
@ds.columns!.should == [:id]
|
|
567
577
|
end
|
|
568
578
|
end
|
|
569
579
|
|
|
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
|
2
2
|
require 'logger'
|
|
3
3
|
unless Object.const_defined?('Sequel')
|
|
4
4
|
$:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), "../../lib/"))
|
|
5
|
-
require 'sequel'
|
|
5
|
+
require 'sequel/no_core_ext'
|
|
6
6
|
end
|
|
7
7
|
begin
|
|
8
8
|
require File.join(File.dirname(File.dirname(__FILE__)), 'spec_config.rb') unless defined?(INTEGRATION_DB)
|
|
@@ -58,7 +58,7 @@ describe "Sequel timezone support" do
|
|
|
58
58
|
test_timezone
|
|
59
59
|
end
|
|
60
60
|
|
|
61
|
-
cspecify "should support using UTC for both database storage and for application", [:
|
|
61
|
+
cspecify "should support using UTC for both database storage and for application", [:do, :mysql], [:do, :postgres], [:oracle] do
|
|
62
62
|
Sequel.default_timezone = :utc
|
|
63
63
|
test_timezone
|
|
64
64
|
Sequel.database_timezone = :local
|
|
@@ -79,7 +79,7 @@ describe "Sequel timezone support" do
|
|
|
79
79
|
@db.timezone = :local
|
|
80
80
|
t = Time.now
|
|
81
81
|
@db[:t].insert(t)
|
|
82
|
-
s = @db[:t].get(
|
|
82
|
+
s = @db[:t].get(Sequel.cast(:t, String))
|
|
83
83
|
if o = Date._parse(s)[:offset]
|
|
84
84
|
o.should == t.utc_offset
|
|
85
85
|
end
|
|
@@ -9,10 +9,10 @@ describe "Supported types" do
|
|
|
9
9
|
specify "should support casting correctly" do
|
|
10
10
|
ds = create_items_table_with_column(:number, Integer)
|
|
11
11
|
ds.insert(:number => 1)
|
|
12
|
-
ds.select(:number.
|
|
12
|
+
ds.select(Sequel.cast(:number, String).as(:n)).map(:n).should == %w'1'
|
|
13
13
|
ds = create_items_table_with_column(:name, String)
|
|
14
14
|
ds.insert(:name=> '1')
|
|
15
|
-
ds.select(:name.
|
|
15
|
+
ds.select(Sequel.cast(:name, Integer).as(:n)).map(:n).should == [1]
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
specify "should support NULL correctly" do
|
|
@@ -33,7 +33,7 @@ describe "Supported types" do
|
|
|
33
33
|
ds.all.should == [{:number=>2}]
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
specify "should support generic bignum type" do
|
|
37
37
|
ds = create_items_table_with_column(:number, Bignum)
|
|
38
38
|
ds.insert(:number => 2**34)
|
|
39
39
|
ds.all.should == [{:number=>2**34}]
|
|
@@ -93,10 +93,10 @@ describe "Supported types" do
|
|
|
93
93
|
ds.first[:tim].strftime('%Y%m%d%H%M%S').should == t.strftime('%Y%m%d%H%M%S')
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
-
cspecify "should support generic file type", [:do], [:odbc, :mssql], [:mysql2], [:
|
|
96
|
+
cspecify "should support generic file type", [:do], [:odbc, :mssql], [:mysql2], [:tinytds] do
|
|
97
97
|
ds = create_items_table_with_column(:name, File)
|
|
98
|
-
ds.insert(:name =>
|
|
99
|
-
ds.all.should == [{:name=>("a\0"*300)
|
|
98
|
+
ds.insert(:name =>Sequel.blob("a\0"*300))
|
|
99
|
+
ds.all.should == [{:name=>Sequel.blob("a\0"*300)}]
|
|
100
100
|
ds.first[:name].should be_a_kind_of(::Sequel::SQL::Blob)
|
|
101
101
|
end
|
|
102
102
|
|
|
@@ -108,4 +108,13 @@ describe "Supported types" do
|
|
|
108
108
|
ds.insert(:number => true)
|
|
109
109
|
ds.all.should == [{:number=>true}]
|
|
110
110
|
end
|
|
111
|
+
|
|
112
|
+
cspecify "should support generic boolean type with defaults", [:do, :sqlite], [:jdbc, :sqlite], [:jdbc, :db2], [:odbc, :mssql], :oracle do
|
|
113
|
+
ds = create_items_table_with_column(:number, TrueClass, :default=>true)
|
|
114
|
+
ds.insert
|
|
115
|
+
ds.all.should == [{:number=>true}]
|
|
116
|
+
ds = create_items_table_with_column(:number, FalseClass, :default=>false)
|
|
117
|
+
ds.insert
|
|
118
|
+
ds.all.should == [{:number=>false}]
|
|
119
|
+
end
|
|
111
120
|
end
|
|
@@ -134,7 +134,7 @@ describe Sequel::Model::Associations::AssociationReflection, "#select" do
|
|
|
134
134
|
it "should be the associated_table.* if :select is not present for a many_to_many associaiton" do
|
|
135
135
|
@c.many_to_many :cs, :class=>'ParParent'
|
|
136
136
|
@c.association_reflection(:cs).keys.should_not include(:select)
|
|
137
|
-
@c.association_reflection(:cs).select.should == :par_parents
|
|
137
|
+
@c.association_reflection(:cs).select.should == Sequel::SQL::ColumnAll.new(:par_parents)
|
|
138
138
|
end
|
|
139
139
|
it "should be if :select is not present for a many_to_one and one_to_many associaiton" do
|
|
140
140
|
@c.one_to_many :cs, :class=>'ParParent'
|
|
@@ -259,7 +259,7 @@ describe Sequel::Model, "many_to_one" do
|
|
|
259
259
|
|
|
260
260
|
it "should support :order, :limit (only for offset), and :dataset options, as well as a block" do
|
|
261
261
|
@c2.many_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{model.filter(:parent_id=>pk)}, :limit=>[10,20], :order=>:name do |ds|
|
|
262
|
-
ds.filter
|
|
262
|
+
ds.filter{x > 1}
|
|
263
263
|
end
|
|
264
264
|
@c2.load(:id => 100).child_20
|
|
265
265
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((parent_id = 100) AND (x > 1)) ORDER BY name LIMIT 1 OFFSET 20"]
|
|
@@ -833,7 +833,7 @@ describe Sequel::Model, "one_to_one" do
|
|
|
833
833
|
|
|
834
834
|
it "should support :order, :limit (only for offset), and :dataset options, as well as a block" do
|
|
835
835
|
@c2.one_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{model.filter(:parent_id=>pk)}, :limit=>[10,20], :order=>:name do |ds|
|
|
836
|
-
ds.filter
|
|
836
|
+
ds.filter{x > 1}
|
|
837
837
|
end
|
|
838
838
|
@c2.load(:id => 100).child_20
|
|
839
839
|
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((parent_id = 100) AND (x > 1)) ORDER BY name LIMIT 1 OFFSET 20"]
|
|
@@ -1365,7 +1365,7 @@ describe Sequel::Model, "one_to_many" do
|
|
|
1365
1365
|
it "should support a conditions option" do
|
|
1366
1366
|
@c2.one_to_many :attributes, :class => @c1, :conditions => {:a=>32}
|
|
1367
1367
|
@c2.new(:id => 1234).attributes_dataset.sql.should == "SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (a = 32))"
|
|
1368
|
-
@c2.one_to_many :attributes, :class => @c1, :conditions =>
|
|
1368
|
+
@c2.one_to_many :attributes, :class => @c1, :conditions => Sequel.~(:a)
|
|
1369
1369
|
@c2.new(:id => 1234).attributes_dataset.sql.should == "SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND NOT a)"
|
|
1370
1370
|
end
|
|
1371
1371
|
|
|
@@ -1886,7 +1886,7 @@ describe Sequel::Model, "many_to_many" do
|
|
|
1886
1886
|
end
|
|
1887
1887
|
|
|
1888
1888
|
it "should support an array for the select option" do
|
|
1889
|
-
@c2.many_to_many :attributes, :class => @c1, :select => [:attributes
|
|
1889
|
+
@c2.many_to_many :attributes, :class => @c1, :select => [Sequel::SQL::ColumnAll.new(:attributes), :attribute_nodes__blah2]
|
|
1890
1890
|
|
|
1891
1891
|
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.*, attribute_nodes.blah2 FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))'
|
|
1892
1892
|
end
|
data/spec/model/base_spec.rb
CHANGED
|
@@ -335,12 +335,12 @@ describe "Model.qualified_primary_key_hash" do
|
|
|
335
335
|
end
|
|
336
336
|
|
|
337
337
|
specify "should handle a single primary key" do
|
|
338
|
-
@c.qualified_primary_key_hash(1).should == {
|
|
338
|
+
@c.qualified_primary_key_hash(1).should == {Sequel.qualify(:items, :id)=>1}
|
|
339
339
|
end
|
|
340
340
|
|
|
341
341
|
specify "should handle a composite primary key" do
|
|
342
342
|
@c.set_primary_key([:id1, :id2])
|
|
343
|
-
@c.qualified_primary_key_hash([1, 2]).should == {
|
|
343
|
+
@c.qualified_primary_key_hash([1, 2]).should == {Sequel.qualify(:items, :id1)=>1, Sequel.qualify(:items, :id2)=>2}
|
|
344
344
|
end
|
|
345
345
|
|
|
346
346
|
specify "should raise an error for no primary key" do
|
|
@@ -349,9 +349,9 @@ describe "Model.qualified_primary_key_hash" do
|
|
|
349
349
|
end
|
|
350
350
|
|
|
351
351
|
specify "should allow specifying a different qualifier" do
|
|
352
|
-
@c.qualified_primary_key_hash(1, :apple).should == {
|
|
352
|
+
@c.qualified_primary_key_hash(1, :apple).should == {Sequel.qualify(:apple, :id)=>1}
|
|
353
353
|
@c.set_primary_key([:id1, :id2])
|
|
354
|
-
@c.qualified_primary_key_hash([1, 2], :bear).should == {
|
|
354
|
+
@c.qualified_primary_key_hash([1, 2], :bear).should == {Sequel.qualify(:bear, :id1)=>1, Sequel.qualify(:bear, :id2)=>2}
|
|
355
355
|
end
|
|
356
356
|
end
|
|
357
357
|
|
|
@@ -608,7 +608,7 @@ describe Sequel::Model, ".[] optimization" do
|
|
|
608
608
|
@c.simple_pk.should == '"id"'
|
|
609
609
|
@c.set_primary_key :b
|
|
610
610
|
@c.simple_pk.should == '"b"'
|
|
611
|
-
@c.set_primary_key :b__a
|
|
611
|
+
@c.set_primary_key Sequel.identifier(:b__a)
|
|
612
612
|
@c.simple_pk.should == '"b__a"'
|
|
613
613
|
end
|
|
614
614
|
|