sequel 4.0.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|