sequel 4.0.0 → 4.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG +32 -0
- data/doc/active_record.rdoc +2 -2
- data/doc/cheat_sheet.rdoc +0 -5
- data/doc/opening_databases.rdoc +3 -2
- data/doc/prepared_statements.rdoc +6 -0
- data/doc/release_notes/4.1.0.txt +85 -0
- data/doc/schema_modification.rdoc +9 -2
- data/lib/sequel/adapters/jdbc.rb +5 -0
- data/lib/sequel/adapters/mysql2.rb +24 -3
- data/lib/sequel/adapters/odbc.rb +6 -4
- data/lib/sequel/adapters/postgres.rb +25 -0
- data/lib/sequel/adapters/shared/mysql.rb +4 -29
- data/lib/sequel/adapters/shared/postgres.rb +14 -3
- data/lib/sequel/adapters/shared/sqlite.rb +4 -0
- data/lib/sequel/adapters/utils/replace.rb +36 -0
- data/lib/sequel/database/query.rb +1 -0
- data/lib/sequel/database/schema_generator.rb +12 -5
- data/lib/sequel/database/schema_methods.rb +2 -0
- data/lib/sequel/dataset/features.rb +5 -0
- data/lib/sequel/extensions/pg_json_ops.rb +0 -6
- data/lib/sequel/model/associations.rb +1 -1
- data/lib/sequel/plugins/instance_filters.rb +11 -1
- data/lib/sequel/plugins/pg_typecast_on_load.rb +3 -2
- data/lib/sequel/plugins/prepared_statements.rb +38 -9
- data/lib/sequel/plugins/update_primary_key.rb +10 -0
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mysql_spec.rb +1 -22
- data/spec/adapters/postgres_spec.rb +79 -2
- data/spec/core/database_spec.rb +10 -0
- data/spec/core/dataset_spec.rb +8 -3
- data/spec/core/expression_filters_spec.rb +1 -1
- data/spec/core/schema_spec.rb +17 -2
- data/spec/extensions/caching_spec.rb +2 -2
- data/spec/extensions/hook_class_methods_spec.rb +0 -4
- data/spec/extensions/instance_filters_spec.rb +22 -0
- data/spec/extensions/migration_spec.rb +5 -5
- data/spec/extensions/nested_attributes_spec.rb +4 -4
- data/spec/extensions/prepared_statements_spec.rb +37 -26
- data/spec/extensions/update_primary_key_spec.rb +13 -0
- data/spec/integration/dataset_test.rb +36 -0
- data/spec/model/associations_spec.rb +20 -2
- data/spec/model/hooks_spec.rb +1 -7
- metadata +5 -2
data/spec/core/database_spec.rb
CHANGED
@@ -508,6 +508,11 @@ describe "Database#run" do
|
|
508
508
|
@db.sqls.should == ["DELETE FROM items"]
|
509
509
|
end
|
510
510
|
|
511
|
+
specify "should handle placeholder literal strings" do
|
512
|
+
@db.run(Sequel.lit("DELETE FROM ?", :items))
|
513
|
+
@db.sqls.should == ["DELETE FROM items"]
|
514
|
+
end
|
515
|
+
|
511
516
|
specify "should return nil" do
|
512
517
|
@db.run("DELETE FROM items").should be_nil
|
513
518
|
end
|
@@ -528,6 +533,11 @@ describe "Database#<<" do
|
|
528
533
|
@db.sqls.should == ["DELETE FROM items"]
|
529
534
|
end
|
530
535
|
|
536
|
+
specify "should handle placeholder literal strings" do
|
537
|
+
@db << Sequel.lit("DELETE FROM ?", :items)
|
538
|
+
@db.sqls.should == ["DELETE FROM items"]
|
539
|
+
end
|
540
|
+
|
531
541
|
specify "should be chainable" do
|
532
542
|
@db << "DELETE FROM items" << "DELETE FROM items2"
|
533
543
|
@db.sqls.should == ["DELETE FROM items", "DELETE FROM items2"]
|
data/spec/core/dataset_spec.rb
CHANGED
@@ -1609,10 +1609,10 @@ describe "Dataset#limit" do
|
|
1609
1609
|
specify "should raise an error if an invalid limit or offset is used" do
|
1610
1610
|
proc{@dataset.limit(-1)}.should raise_error(Sequel::Error)
|
1611
1611
|
proc{@dataset.limit(0)}.should raise_error(Sequel::Error)
|
1612
|
-
proc{@dataset.limit(1)}.should_not raise_error
|
1612
|
+
proc{@dataset.limit(1)}.should_not raise_error
|
1613
1613
|
proc{@dataset.limit(1, -1)}.should raise_error(Sequel::Error)
|
1614
|
-
proc{@dataset.limit(1, 0)}.should_not raise_error
|
1615
|
-
proc{@dataset.limit(1, 1)}.should_not raise_error
|
1614
|
+
proc{@dataset.limit(1, 0)}.should_not raise_error
|
1615
|
+
proc{@dataset.limit(1, 1)}.should_not raise_error
|
1616
1616
|
end
|
1617
1617
|
end
|
1618
1618
|
|
@@ -4508,3 +4508,8 @@ describe "Dataset#escape_like" do
|
|
4508
4508
|
end
|
4509
4509
|
end
|
4510
4510
|
|
4511
|
+
describe "Dataset#supports_replace?" do
|
4512
|
+
it "should be false by default" do
|
4513
|
+
Sequel::Dataset.new(nil).supports_replace?.should be_false
|
4514
|
+
end
|
4515
|
+
end
|
@@ -429,7 +429,7 @@ describe Sequel::SQL::VirtualRow do
|
|
429
429
|
end
|
430
430
|
|
431
431
|
it "should raise an error if an unsupported argument is used with a block" do
|
432
|
-
proc{@d.
|
432
|
+
proc{@d.where{count(:blah){}}}.should raise_error(Sequel::Error)
|
433
433
|
end
|
434
434
|
|
435
435
|
it "should treat methods with a block and a leading argument :over as a window function call" do
|
data/spec/core/schema_spec.rb
CHANGED
@@ -446,7 +446,7 @@ describe "DB#create_table" do
|
|
446
446
|
meta_def(@db, :execute_ddl){|*a| raise Sequel::DatabaseError if /blah/.match(a.first); super(*a)}
|
447
447
|
lambda{@db.create_table(:cats){Integer :id; index :blah; index :id}}.should raise_error(Sequel::DatabaseError)
|
448
448
|
@db.sqls.should == ['CREATE TABLE cats (id integer)']
|
449
|
-
lambda{@db.create_table(:cats, :ignore_index_errors=>true){Integer :id; index :blah; index :id}}.should_not raise_error
|
449
|
+
lambda{@db.create_table(:cats, :ignore_index_errors=>true){Integer :id; index :blah; index :id}}.should_not raise_error
|
450
450
|
@db.sqls.should == ['CREATE TABLE cats (id integer)', 'CREATE INDEX cats_id_index ON cats (id)']
|
451
451
|
end
|
452
452
|
|
@@ -551,6 +551,14 @@ describe "DB#create_table" do
|
|
551
551
|
@db.sqls.should == ["CREATE TABLE cats (score integer, CONSTRAINT valid_score CHECK (score <= 100))"]
|
552
552
|
end
|
553
553
|
|
554
|
+
specify "should accept named constraint definitions with options" do
|
555
|
+
@db.create_table(:cats) do
|
556
|
+
integer :score
|
557
|
+
constraint({:name=>:valid_score, :deferrable=>true}, 'score <= 100')
|
558
|
+
end
|
559
|
+
@db.sqls.should == ["CREATE TABLE cats (score integer, CONSTRAINT valid_score CHECK (score <= 100) DEFERRABLE INITIALLY DEFERRED)"]
|
560
|
+
end
|
561
|
+
|
554
562
|
specify "should accept named constraint definitions with block" do
|
555
563
|
@db.create_table(:cats) do
|
556
564
|
constraint(:blah_blah){(x.sql_number > 0) & (y.sql_number < 1)}
|
@@ -892,6 +900,13 @@ describe "DB#alter_table" do
|
|
892
900
|
@db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT valid_score CHECK (score <= 100)"]
|
893
901
|
end
|
894
902
|
|
903
|
+
specify "should support add_constraint with options" do
|
904
|
+
@db.alter_table(:cats) do
|
905
|
+
add_constraint({:name=>:valid_score, :deferrable=>true}, 'score <= 100')
|
906
|
+
end
|
907
|
+
@db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT valid_score CHECK (score <= 100) DEFERRABLE INITIALLY DEFERRED"]
|
908
|
+
end
|
909
|
+
|
895
910
|
specify "should support add_constraint with block" do
|
896
911
|
@db.alter_table(:cats) do
|
897
912
|
add_constraint(:blah_blah){(x.sql_number > 0) & (y.sql_number < 1)}
|
@@ -950,7 +965,7 @@ describe "DB#alter_table" do
|
|
950
965
|
specify "should ignore errors if the database raises an error on an add_index call and the :ignore_errors option is used" do
|
951
966
|
meta_def(@db, :execute_ddl){|*a| raise Sequel::DatabaseError}
|
952
967
|
lambda{@db.add_index(:cats, :id)}.should raise_error(Sequel::DatabaseError)
|
953
|
-
lambda{@db.add_index(:cats, :id, :ignore_errors=>true)}.should_not raise_error
|
968
|
+
lambda{@db.add_index(:cats, :id, :ignore_errors=>true)}.should_not raise_error
|
954
969
|
@db.sqls.should == []
|
955
970
|
end
|
956
971
|
|
@@ -125,12 +125,12 @@ describe Sequel::Model, "caching" do
|
|
125
125
|
m = @c.new
|
126
126
|
proc {m.cache_key}.should raise_error(Sequel::Error)
|
127
127
|
m.values[:id] = 1
|
128
|
-
proc {m.cache_key}.should_not raise_error
|
128
|
+
proc {m.cache_key}.should_not raise_error
|
129
129
|
|
130
130
|
m = @c2.new
|
131
131
|
proc {m.cache_key}.should raise_error(Sequel::Error)
|
132
132
|
m.values[:id] = 1
|
133
|
-
proc {m.cache_key}.should_not raise_error
|
133
|
+
proc {m.cache_key}.should_not raise_error
|
134
134
|
end
|
135
135
|
|
136
136
|
it "should not raise error if trying to save a new record" do
|
@@ -184,7 +184,6 @@ describe "Model#before_create && Model#after_create" do
|
|
184
184
|
|
185
185
|
specify ".create should cancel the save and raise an error if before_create returns false and raise_on_save_failure is true" do
|
186
186
|
@c.before_create{false}
|
187
|
-
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
188
187
|
proc{@c.create(:x => 2)}.should raise_error(Sequel::BeforeHookFailed)
|
189
188
|
DB.sqls.should == []
|
190
189
|
end
|
@@ -215,7 +214,6 @@ describe "Model#before_update && Model#after_update" do
|
|
215
214
|
|
216
215
|
specify "#save should cancel the save and raise an error if before_update returns false and raise_on_save_failure is true" do
|
217
216
|
@c.before_update{false}
|
218
|
-
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
219
217
|
proc{@c.load(:id => 2233).save}.should raise_error(Sequel::BeforeHookFailed)
|
220
218
|
DB.sqls.should == []
|
221
219
|
end
|
@@ -254,7 +252,6 @@ describe "Model#before_save && Model#after_save" do
|
|
254
252
|
|
255
253
|
specify "#save should cancel the save and raise an error if before_save returns false and raise_on_save_failure is true" do
|
256
254
|
@c.before_save{false}
|
257
|
-
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
258
255
|
proc{@c.load(:id => 2233).save}.should raise_error(Sequel::BeforeHookFailed)
|
259
256
|
DB.sqls.should == []
|
260
257
|
end
|
@@ -339,7 +336,6 @@ describe "Model#before_validation && Model#after_validation" do
|
|
339
336
|
|
340
337
|
specify "#save should cancel the save and raise an error if before_validation returns false and raise_on_save_failure is true" do
|
341
338
|
@c.before_validation{false}
|
342
|
-
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
343
339
|
proc{@c.load(:id => 2233).save}.should raise_error(Sequel::BeforeHookFailed)
|
344
340
|
DB.sqls.should == []
|
345
341
|
end
|
@@ -28,6 +28,28 @@ describe "instance_filters plugin" do
|
|
28
28
|
DB.sqls.should == ["DELETE FROM people WHERE ((id = 1) AND (name = 'Jim'))"]
|
29
29
|
end
|
30
30
|
|
31
|
+
specify "should work when using the prepared_statements plugin" do
|
32
|
+
@c.plugin :prepared_statements
|
33
|
+
|
34
|
+
@p.update(:name=>'Bob')
|
35
|
+
DB.sqls.should == ["UPDATE people SET name = 'Bob' WHERE (id = 1)"]
|
36
|
+
@p.instance_filter(:name=>'Jim')
|
37
|
+
@p.this.numrows = 0
|
38
|
+
proc{@p.update(:name=>'Joe')}.should raise_error(Sequel::Plugins::InstanceFilters::Error)
|
39
|
+
DB.sqls.should == ["UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Jim'))"]
|
40
|
+
|
41
|
+
@p = @c.load(:id=>1, :name=>'John', :num=>1)
|
42
|
+
@p.this.numrows = 1
|
43
|
+
@p.destroy
|
44
|
+
DB.sqls.should == ["DELETE FROM people WHERE (id = 1)"]
|
45
|
+
@p.instance_filter(:name=>'Jim')
|
46
|
+
@p.this.numrows = 0
|
47
|
+
proc{@p.destroy}.should raise_error(Sequel::Plugins::InstanceFilters::Error)
|
48
|
+
DB.sqls.should == ["DELETE FROM people WHERE ((id = 1) AND (name = 'Jim'))"]
|
49
|
+
|
50
|
+
@c.create.should be_a_kind_of(@c)
|
51
|
+
end
|
52
|
+
|
31
53
|
specify "should apply all instance filters" do
|
32
54
|
@p.instance_filter(:name=>'Jim')
|
33
55
|
@p.instance_filter{num > 2}
|
@@ -194,19 +194,19 @@ describe "Reversible Migrations with Sequel.migration{change{}}" do
|
|
194
194
|
|
195
195
|
specify "should raise in the down direction if migration uses unsupported method" do
|
196
196
|
m = Sequel.migration{change{run 'SQL'}}
|
197
|
-
proc{m.apply(@db, :up)}.should_not raise_error
|
197
|
+
proc{m.apply(@db, :up)}.should_not raise_error
|
198
198
|
proc{m.apply(@db, :down)}.should raise_error(Sequel::Error)
|
199
199
|
end
|
200
200
|
|
201
201
|
specify "should raise in the down direction if migration uses add_primary_key with an array" do
|
202
202
|
m = Sequel.migration{change{alter_table(:a){add_primary_key [:b]}}}
|
203
|
-
proc{m.apply(@db, :up)}.should_not raise_error
|
203
|
+
proc{m.apply(@db, :up)}.should_not raise_error
|
204
204
|
proc{m.apply(@db, :down)}.should raise_error(Sequel::Error)
|
205
205
|
end
|
206
206
|
|
207
207
|
specify "should raise in the down direction if migration uses add_foreign_key with an array" do
|
208
208
|
m = Sequel.migration{change{alter_table(:a){add_foreign_key [:b]}}}
|
209
|
-
proc{m.apply(@db, :up)}.should_not raise_error
|
209
|
+
proc{m.apply(@db, :up)}.should_not raise_error
|
210
210
|
proc{m.apply(@db, :down)}.should raise_error(Sequel::Error)
|
211
211
|
end
|
212
212
|
end
|
@@ -263,7 +263,7 @@ describe "Sequel::IntegerMigrator" do
|
|
263
263
|
end
|
264
264
|
|
265
265
|
specify "should not raise and error if there is a missing integer migration version and allow_missing_migration_files is true" do
|
266
|
-
Sequel::Migrator.run(@db, "spec/files/missing_integer_migrations", :allow_missing_migration_files => true).should_not raise_error
|
266
|
+
proc{Sequel::Migrator.run(@db, "spec/files/missing_integer_migrations", :allow_missing_migration_files => true)}.should_not raise_error
|
267
267
|
end
|
268
268
|
|
269
269
|
specify "should raise and error if there is a duplicate integer migration version" do
|
@@ -622,7 +622,7 @@ describe "Sequel::TimestampMigrator" do
|
|
622
622
|
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb 1273253853_3_create_users.rb'
|
623
623
|
|
624
624
|
@dir = 'spec/files/missing_timestamped_migrations'
|
625
|
-
proc{@m.run(@db, @dir, :allow_missing_migration_files => true)}.should_not raise_error
|
625
|
+
proc{@m.run(@db, @dir, :allow_missing_migration_files => true)}.should_not raise_error
|
626
626
|
[:schema_migrations, :sm1111, :sm2222, :sm3333].each{|n| @db.table_exists?(n).should be_true}
|
627
627
|
@db[:schema_migrations].select_order_map(:filename).should == %w'1273253849_create_sessions.rb 1273253851_create_nodes.rb 1273253853_3_create_users.rb'
|
628
628
|
end
|
@@ -340,7 +340,7 @@ describe "NestedAttributes plugin" do
|
|
340
340
|
@Album.nested_attributes :artist
|
341
341
|
proc{a.set(:artist_attributes=>{:id=>'20', :_delete=>'1'})}.should raise_error(Sequel::Error)
|
342
342
|
@Album.nested_attributes :artist, :destroy=>true
|
343
|
-
proc{a.set(:artist_attributes=>{:id=>'20', :_delete=>'1'})}.should_not raise_error
|
343
|
+
proc{a.set(:artist_attributes=>{:id=>'20', :_delete=>'1'})}.should_not raise_error
|
344
344
|
end
|
345
345
|
|
346
346
|
it "should only allow removing associated objects if :remove option is used in the nested_attributes call" do
|
@@ -350,7 +350,7 @@ describe "NestedAttributes plugin" do
|
|
350
350
|
@Album.nested_attributes :artist
|
351
351
|
proc{a.set(:artist_attributes=>{:id=>'20', :_remove=>'1'})}.should raise_error(Sequel::Error)
|
352
352
|
@Album.nested_attributes :artist, :remove=>true
|
353
|
-
proc{a.set(:artist_attributes=>{:id=>'20', :_remove=>'1'})}.should_not raise_error
|
353
|
+
proc{a.set(:artist_attributes=>{:id=>'20', :_remove=>'1'})}.should_not raise_error
|
354
354
|
end
|
355
355
|
|
356
356
|
it "should raise an Error if a primary key is given in a nested attribute hash, but no matching associated object exists" do
|
@@ -358,7 +358,7 @@ describe "NestedAttributes plugin" do
|
|
358
358
|
ar = @Artist.load(:id=>20, :name=>'Ar')
|
359
359
|
ar.associations[:albums] = [al]
|
360
360
|
proc{ar.set(:albums_attributes=>[{:id=>30, :_delete=>'t'}])}.should raise_error(Sequel::Error)
|
361
|
-
proc{ar.set(:albums_attributes=>[{:id=>10, :_delete=>'t'}])}.should_not raise_error
|
361
|
+
proc{ar.set(:albums_attributes=>[{:id=>10, :_delete=>'t'}])}.should_not raise_error
|
362
362
|
end
|
363
363
|
|
364
364
|
it "should not raise an Error if an unmatched primary key is given, if the :strict=>false option is used" do
|
@@ -388,7 +388,7 @@ describe "NestedAttributes plugin" do
|
|
388
388
|
co = @Concert.load(:tour=>'To', :date=>'2004-04-05', :playlist=>'Pl')
|
389
389
|
ar.associations[:concerts] = [co]
|
390
390
|
proc{ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-04', :_delete=>'t'}])}.should raise_error(Sequel::Error)
|
391
|
-
proc{ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_delete=>'t'}])}.should_not raise_error
|
391
|
+
proc{ar.set(:concerts_attributes=>[{:tour=>'To', :date=>'2004-04-05', :_delete=>'t'}])}.should_not raise_error
|
392
392
|
end
|
393
393
|
|
394
394
|
it "should not raise an Error if an unmatched composite primary key is given, if the :strict=>false option is used" do
|
@@ -16,37 +16,48 @@ describe "prepared_statements plugin" do
|
|
16
16
|
@db.sqls.should == ["SELECT * FROM people WHERE (id = 1) LIMIT 1 -- read_only"]
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
specify "should correctly update instance" do
|
25
|
-
@p.update(:name=>'bar').should == @c.load(:id=>1, :name=>'bar', :i => 2)
|
26
|
-
@db.sqls.should == ["UPDATE people SET name = 'bar' WHERE (id = 1)"]
|
27
|
-
end
|
28
|
-
|
29
|
-
specify "should correctly create instance" do
|
30
|
-
@c.create(:name=>'foo').should == @c.load(:id=>1, :name=>'foo', :i => 2)
|
31
|
-
@db.sqls.should == ["INSERT INTO people (name) VALUES ('foo')", "SELECT * FROM people WHERE (id = 1) LIMIT 1"]
|
32
|
-
end
|
19
|
+
shared_examples_for "prepared_statements plugin" do
|
20
|
+
specify "should correctly delete instance" do
|
21
|
+
@p.destroy.should == @p
|
22
|
+
@db.sqls.should == ["DELETE FROM people WHERE (id = 1)"]
|
23
|
+
end
|
33
24
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
true
|
25
|
+
specify "should correctly update instance" do
|
26
|
+
@p.update(:name=>'bar').should == @c.load(:id=>1, :name=>'bar', :i => 2)
|
27
|
+
@db.sqls.should == ["UPDATE people SET name = 'bar' WHERE (id = 1)"]
|
38
28
|
end
|
39
|
-
|
40
|
-
|
29
|
+
|
30
|
+
specify "should correctly create instance" do
|
31
|
+
@c.create(:name=>'foo').should == @c.load(:id=>1, :name=>'foo', :i => 2)
|
32
|
+
@db.sqls.should == ["INSERT INTO people (name) VALUES ('foo')", "SELECT * FROM people WHERE (id = 1) LIMIT 1"]
|
41
33
|
end
|
42
|
-
|
43
|
-
|
34
|
+
|
35
|
+
specify "should correctly create instance if dataset supports insert_select" do
|
36
|
+
@c.dataset_module do
|
37
|
+
def supports_insert_select?
|
38
|
+
true
|
39
|
+
end
|
40
|
+
def insert_select(h)
|
41
|
+
self._fetch = {:id=>1, :name=>'foo', :i => 2}
|
42
|
+
returning.server(:default).with_sql(:insert_sql, h).first
|
43
|
+
end
|
44
|
+
def insert_sql(*)
|
45
|
+
"#{super}#{' RETURNING *' if opts.has_key?(:returning)}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
@c.create(:name=>'foo').should == @c.load(:id=>1, :name=>'foo', :i => 2)
|
49
|
+
@db.sqls.should == ["INSERT INTO people (name) VALUES ('foo') RETURNING *"]
|
44
50
|
end
|
45
|
-
|
46
|
-
|
51
|
+
end
|
52
|
+
|
53
|
+
it_should_behave_like "prepared_statements plugin"
|
54
|
+
|
55
|
+
describe "when #use_prepared_statements_for? returns false" do
|
56
|
+
before do
|
57
|
+
@c.class_eval{def use_prepared_statements_for?(type) false end}
|
47
58
|
end
|
48
|
-
|
49
|
-
|
59
|
+
|
60
|
+
it_should_behave_like "prepared_statements plugin"
|
50
61
|
end
|
51
62
|
|
52
63
|
specify "should work correctly when subclassing" do
|
@@ -68,6 +68,19 @@ describe "Sequel::Plugins::UpdatePrimaryKey" do
|
|
68
68
|
DB.sqls.should == ["SELECT * FROM a LIMIT 1", "UPDATE a SET a = 2 WHERE (a = 1)", "UPDATE a SET b = 4 WHERE (a = 2)", "UPDATE a SET b = 5 WHERE (a = 2)", "SELECT * FROM a"]
|
69
69
|
end
|
70
70
|
|
71
|
+
specify "should work correctly when using the prepared_statements plugin" do
|
72
|
+
@c.plugin :prepared_statements
|
73
|
+
@ds._fetch = [[{:a=>1, :b=>3}], [{:a=>2, :b=>4}]]
|
74
|
+
o = @c.first
|
75
|
+
o.update(:a=>2, :b=>4)
|
76
|
+
@c.all.should == [@c.load(:a=>2, :b=>4)]
|
77
|
+
sqls = DB.sqls
|
78
|
+
["UPDATE a SET a = 2, b = 4 WHERE (a = 1)", "UPDATE a SET b = 4, a = 2 WHERE (a = 1)"].should include(sqls.slice!(1))
|
79
|
+
sqls.should == ["SELECT * FROM a LIMIT 1", "SELECT * FROM a"]
|
80
|
+
|
81
|
+
o.delete
|
82
|
+
end
|
83
|
+
|
71
84
|
specify "should clear the associations cache of non-many_to_one associations when changing the primary key" do
|
72
85
|
@c.one_to_many :cs, :class=>@c
|
73
86
|
@c.many_to_one :c, :class=>@c
|
@@ -1671,3 +1671,39 @@ describe "Emulated functions" do
|
|
1671
1671
|
@ds.get(Sequel.trim(:a)).should == 'foo22'
|
1672
1672
|
end
|
1673
1673
|
end
|
1674
|
+
|
1675
|
+
describe "Dataset replace" do
|
1676
|
+
before do
|
1677
|
+
DB.create_table(:items){Integer :id, :unique=>true; Integer :value}
|
1678
|
+
sqls = []
|
1679
|
+
DB.loggers << Class.new{%w'info error'.each{|m| define_method(m){|sql| sqls << sql}}}.new
|
1680
|
+
|
1681
|
+
@d = DB[:items]
|
1682
|
+
sqls.clear
|
1683
|
+
end
|
1684
|
+
|
1685
|
+
after do
|
1686
|
+
DB.drop_table?(:items)
|
1687
|
+
end
|
1688
|
+
|
1689
|
+
specify "should use support arrays, datasets, and multiple values" do
|
1690
|
+
@d.replace([1, 2])
|
1691
|
+
@d.all.should == [{:id=>1, :value=>2}]
|
1692
|
+
@d.replace(1, 2)
|
1693
|
+
@d.all.should == [{:id=>1, :value=>2}]
|
1694
|
+
@d.replace(@d)
|
1695
|
+
@d.all.should == [{:id=>1, :value=>2}]
|
1696
|
+
end
|
1697
|
+
|
1698
|
+
specify "should create a record if the condition is not met" do
|
1699
|
+
@d.replace(:id => 111, :value => 333)
|
1700
|
+
@d.all.should == [{:id => 111, :value => 333}]
|
1701
|
+
end
|
1702
|
+
|
1703
|
+
specify "should update a record if the condition is met" do
|
1704
|
+
@d << {:id => 111}
|
1705
|
+
@d.all.should == [{:id => 111, :value => nil}]
|
1706
|
+
@d.replace(:id => 111, :value => 333)
|
1707
|
+
@d.all.should == [{:id => 111, :value => 333}]
|
1708
|
+
end
|
1709
|
+
end if DB.dataset.supports_replace?
|
@@ -134,8 +134,8 @@ describe Sequel::Model, "associate" do
|
|
134
134
|
it "should allow cloning of one_to_many to one_to_one associations and vice-versa" do
|
135
135
|
c = Class.new(Sequel::Model(:c))
|
136
136
|
c.one_to_one :c
|
137
|
-
proc{c.one_to_many :cs, :clone=>:c}.should_not raise_error
|
138
|
-
proc{c.one_to_one :c2, :clone=>:cs}.should_not raise_error
|
137
|
+
proc{c.one_to_many :cs, :clone=>:c}.should_not raise_error
|
138
|
+
proc{c.one_to_one :c2, :clone=>:cs}.should_not raise_error
|
139
139
|
end
|
140
140
|
|
141
141
|
it "should clear associations cache when refreshing object manually" do
|
@@ -1239,6 +1239,14 @@ describe Sequel::Model, "one_to_many" do
|
|
1239
1239
|
DB.sqls.should == ["SELECT * FROM attributes WHERE id = 234", "UPDATE attributes SET node_id = 1234 WHERE (id = 234)"]
|
1240
1240
|
end
|
1241
1241
|
|
1242
|
+
it "should raise an error if the primary key passed to the add_ method does not match an existing record" do
|
1243
|
+
@c2.one_to_many :attributes, :class => @c1
|
1244
|
+
n = @c2.new(:id => 1234)
|
1245
|
+
@c1.dataset._fetch = []
|
1246
|
+
proc{n.add_attribute(234)}.should raise_error(Sequel::NoMatchingRow)
|
1247
|
+
DB.sqls.should == ["SELECT * FROM attributes WHERE id = 234"]
|
1248
|
+
end
|
1249
|
+
|
1242
1250
|
it "should raise an error in the add_ method if the passed associated object is not of the correct type" do
|
1243
1251
|
@c2.one_to_many :attributes, :class => @c1
|
1244
1252
|
proc{@c2.new(:id => 1234).add_attribute(@c2.new)}.should raise_error(Sequel::Error)
|
@@ -2013,6 +2021,16 @@ describe Sequel::Model, "many_to_many" do
|
|
2013
2021
|
sqls.should == ["SELECT * FROM attributes WHERE id = 2345"]
|
2014
2022
|
end
|
2015
2023
|
|
2024
|
+
it "should raise an error if the primary key passed to the add_ method does not match an existing record" do
|
2025
|
+
@c2.many_to_many :attributes, :class => @c1
|
2026
|
+
|
2027
|
+
n = @c2.load(:id => 1234)
|
2028
|
+
a = @c1.load(:id => 2345)
|
2029
|
+
@c1.dataset._fetch = []
|
2030
|
+
proc{n.add_attribute(2345)}.should raise_error(Sequel::NoMatchingRow)
|
2031
|
+
DB.sqls.should == ["SELECT * FROM attributes WHERE id = 2345"]
|
2032
|
+
end
|
2033
|
+
|
2016
2034
|
it "should allow passing a hash to the add_ method which creates a new record" do
|
2017
2035
|
@c2.many_to_many :attributes, :class => @c1
|
2018
2036
|
|
data/spec/model/hooks_spec.rb
CHANGED
@@ -24,7 +24,7 @@ describe "Model#before_create && Model#after_create" do
|
|
24
24
|
@c.send(:define_method, :before_create){false}
|
25
25
|
proc{@c.create(:x => 2)}.should raise_error(Sequel::BeforeHookFailed)
|
26
26
|
DB.sqls.should == []
|
27
|
-
proc{@c.load(:id => 2233).save}.should_not raise_error
|
27
|
+
proc{@c.load(:id => 2233).save}.should_not raise_error
|
28
28
|
end
|
29
29
|
|
30
30
|
specify ".create should cancel the save and return nil if before_create returns false and raise_on_save_failure is false" do
|
@@ -55,7 +55,6 @@ describe "Model#before_update && Model#after_update" do
|
|
55
55
|
|
56
56
|
specify "#save should cancel the save and raise an error if before_update returns false and raise_on_save_failure is true" do
|
57
57
|
@c.send(:define_method, :before_update){false}
|
58
|
-
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
59
58
|
proc{@c.load(:id => 2233).save}.should raise_error(Sequel::BeforeHookFailed)
|
60
59
|
DB.sqls.should == []
|
61
60
|
end
|
@@ -63,7 +62,6 @@ describe "Model#before_update && Model#after_update" do
|
|
63
62
|
specify "#save should cancel the save and raise an error if before_update returns false and raise_on_failure option is true" do
|
64
63
|
@c.send(:define_method, :before_update){false}
|
65
64
|
@c.raise_on_save_failure = false
|
66
|
-
proc{@c.load(:id => 2233).save(:raise_on_failure => true)}.should_not raise_error(Sequel::ValidationFailed)
|
67
65
|
proc{@c.load(:id => 2233).save(:raise_on_failure => true)}.should raise_error(Sequel::BeforeHookFailed)
|
68
66
|
DB.sqls.should == []
|
69
67
|
end
|
@@ -104,7 +102,6 @@ describe "Model#before_save && Model#after_save" do
|
|
104
102
|
|
105
103
|
specify "#save should cancel the save and raise an error if before_save returns false and raise_on_save_failure is true" do
|
106
104
|
@c.send(:define_method, :before_save){false}
|
107
|
-
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
108
105
|
proc{@c.load(:id => 2233).save}.should raise_error(Sequel::BeforeHookFailed)
|
109
106
|
DB.sqls.should == []
|
110
107
|
end
|
@@ -112,7 +109,6 @@ describe "Model#before_save && Model#after_save" do
|
|
112
109
|
specify "#save should cancel the save and raise an error if before_save returns false and raise_on_failure option is true" do
|
113
110
|
@c.send(:define_method, :before_save){false}
|
114
111
|
@c.raise_on_save_failure = false
|
115
|
-
proc{@c.load(:id => 2233).save(:raise_on_failure => true)}.should_not raise_error(Sequel::ValidationFailed)
|
116
112
|
proc{@c.load(:id => 2233).save(:raise_on_failure => true)}.should raise_error(Sequel::BeforeHookFailed)
|
117
113
|
DB.sqls.should == []
|
118
114
|
end
|
@@ -208,7 +204,6 @@ describe "Model#before_validation && Model#after_validation" do
|
|
208
204
|
|
209
205
|
specify "#save should cancel the save and raise an error if before_validation returns false and raise_on_save_failure is true" do
|
210
206
|
@c.send(:define_method, :before_validation){false}
|
211
|
-
proc{@c.load(:id => 2233).save}.should_not raise_error(Sequel::ValidationFailed)
|
212
207
|
proc{@c.load(:id => 2233).save}.should raise_error(Sequel::BeforeHookFailed)
|
213
208
|
DB.sqls.should == []
|
214
209
|
end
|
@@ -216,7 +211,6 @@ describe "Model#before_validation && Model#after_validation" do
|
|
216
211
|
specify "#save should cancel the save and raise an error if before_validation returns false and raise_on_failure option is true" do
|
217
212
|
@c.send(:define_method, :before_validation){false}
|
218
213
|
@c.raise_on_save_failure = false
|
219
|
-
proc{@c.load(:id => 2233).save(:raise_on_failure => true)}.should_not raise_error(Sequel::ValidationFailed)
|
220
214
|
proc{@c.load(:id => 2233).save(:raise_on_failure => true)}.should raise_error(Sequel::BeforeHookFailed)
|
221
215
|
DB.sqls.should == []
|
222
216
|
end
|