sequel 3.10.0 → 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +68 -0
- data/COPYING +1 -1
- data/README.rdoc +87 -27
- data/bin/sequel +2 -4
- data/doc/association_basics.rdoc +1383 -0
- data/doc/dataset_basics.rdoc +106 -0
- data/doc/opening_databases.rdoc +45 -16
- data/doc/querying.rdoc +210 -0
- data/doc/release_notes/3.11.0.txt +254 -0
- data/doc/virtual_rows.rdoc +217 -31
- data/lib/sequel/adapters/ado.rb +28 -12
- data/lib/sequel/adapters/ado/mssql.rb +33 -1
- data/lib/sequel/adapters/amalgalite.rb +13 -8
- data/lib/sequel/adapters/db2.rb +1 -2
- data/lib/sequel/adapters/dbi.rb +7 -4
- data/lib/sequel/adapters/do.rb +14 -15
- data/lib/sequel/adapters/do/postgres.rb +4 -5
- data/lib/sequel/adapters/do/sqlite.rb +9 -0
- data/lib/sequel/adapters/firebird.rb +5 -10
- data/lib/sequel/adapters/informix.rb +2 -4
- data/lib/sequel/adapters/jdbc.rb +111 -49
- data/lib/sequel/adapters/jdbc/mssql.rb +1 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +11 -0
- data/lib/sequel/adapters/jdbc/oracle.rb +4 -7
- data/lib/sequel/adapters/jdbc/postgresql.rb +8 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +12 -0
- data/lib/sequel/adapters/mysql.rb +14 -5
- data/lib/sequel/adapters/odbc.rb +2 -4
- data/lib/sequel/adapters/odbc/mssql.rb +2 -4
- data/lib/sequel/adapters/openbase.rb +1 -2
- data/lib/sequel/adapters/oracle.rb +4 -8
- data/lib/sequel/adapters/postgres.rb +4 -11
- data/lib/sequel/adapters/shared/mssql.rb +22 -9
- data/lib/sequel/adapters/shared/mysql.rb +33 -30
- data/lib/sequel/adapters/shared/oracle.rb +0 -5
- data/lib/sequel/adapters/shared/postgres.rb +13 -11
- data/lib/sequel/adapters/shared/sqlite.rb +56 -10
- data/lib/sequel/adapters/sqlite.rb +16 -9
- data/lib/sequel/connection_pool.rb +6 -1
- data/lib/sequel/connection_pool/single.rb +1 -0
- data/lib/sequel/core.rb +6 -1
- data/lib/sequel/database.rb +52 -23
- data/lib/sequel/database/schema_generator.rb +6 -0
- data/lib/sequel/database/schema_methods.rb +5 -5
- data/lib/sequel/database/schema_sql.rb +1 -1
- data/lib/sequel/dataset.rb +4 -190
- data/lib/sequel/dataset/actions.rb +323 -1
- data/lib/sequel/dataset/features.rb +18 -2
- data/lib/sequel/dataset/graph.rb +7 -0
- data/lib/sequel/dataset/misc.rb +119 -0
- data/lib/sequel/dataset/mutation.rb +64 -0
- data/lib/sequel/dataset/prepared_statements.rb +6 -0
- data/lib/sequel/dataset/query.rb +272 -6
- data/lib/sequel/dataset/sql.rb +186 -394
- data/lib/sequel/model.rb +4 -2
- data/lib/sequel/model/associations.rb +31 -14
- data/lib/sequel/model/base.rb +32 -13
- data/lib/sequel/model/exceptions.rb +8 -4
- data/lib/sequel/model/plugins.rb +3 -13
- data/lib/sequel/plugins/active_model.rb +26 -7
- data/lib/sequel/plugins/instance_filters.rb +98 -0
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/optimistic_locking.rb +25 -9
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +26 -0
- data/spec/adapters/mysql_spec.rb +33 -4
- data/spec/adapters/postgres_spec.rb +24 -1
- data/spec/adapters/spec_helper.rb +6 -0
- data/spec/adapters/sqlite_spec.rb +28 -0
- data/spec/core/connection_pool_spec.rb +17 -5
- data/spec/core/database_spec.rb +101 -1
- data/spec/core/dataset_spec.rb +42 -4
- data/spec/core/schema_spec.rb +13 -0
- data/spec/extensions/active_model_spec.rb +34 -11
- data/spec/extensions/caching_spec.rb +2 -0
- data/spec/extensions/instance_filters_spec.rb +55 -0
- data/spec/extensions/spec_helper.rb +2 -0
- data/spec/integration/dataset_test.rb +12 -1
- data/spec/integration/model_test.rb +12 -0
- data/spec/integration/plugin_test.rb +61 -1
- data/spec/integration/schema_test.rb +14 -3
- data/spec/model/base_spec.rb +27 -0
- data/spec/model/plugins_spec.rb +0 -22
- data/spec/model/record_spec.rb +32 -1
- data/spec/model/spec_helper.rb +2 -0
- metadata +14 -3
- data/lib/sequel/dataset/convenience.rb +0 -326
data/spec/core/schema_spec.rb
CHANGED
@@ -299,6 +299,15 @@ context "DB#create_table" do
|
|
299
299
|
@db.sqls.should == ["CREATE TABLE cats (name text, UNIQUE (name))"]
|
300
300
|
end
|
301
301
|
|
302
|
+
specify "should not raise on index error for unsupported index definitions if ignore_index_errors is used" do
|
303
|
+
proc {
|
304
|
+
@db.create_table(:cats, :ignore_index_errors=>true) do
|
305
|
+
text :name
|
306
|
+
full_text_index :name
|
307
|
+
end
|
308
|
+
}.should_not raise_error
|
309
|
+
end
|
310
|
+
|
302
311
|
specify "should raise on full-text index definitions" do
|
303
312
|
proc {
|
304
313
|
@db.create_table(:cats) do
|
@@ -812,8 +821,12 @@ context "Schema Parser" do
|
|
812
821
|
@db.schema(:float).first.last[:type].should == :float
|
813
822
|
@db.schema(:double).first.last[:type].should == :float
|
814
823
|
@db.schema(:"double precision").first.last[:type].should == :float
|
824
|
+
@db.schema(:number).first.last[:type].should == :decimal
|
815
825
|
@db.schema(:numeric).first.last[:type].should == :decimal
|
816
826
|
@db.schema(:decimal).first.last[:type].should == :decimal
|
827
|
+
@db.schema(:"number(10,0)").first.last[:type].should == :integer
|
828
|
+
@db.schema(:"numeric(10, 10)").first.last[:type].should == :decimal
|
829
|
+
@db.schema(:"decimal(10,1)").first.last[:type].should == :decimal
|
817
830
|
@db.schema(:money).first.last[:type].should == :decimal
|
818
831
|
@db.schema(:bytea).first.last[:type].should == :blob
|
819
832
|
@db.schema(:blob).first.last[:type].should == :blob
|
@@ -8,15 +8,18 @@ describe "ActiveModel plugin" do
|
|
8
8
|
s = f.read
|
9
9
|
else
|
10
10
|
begin
|
11
|
+
require 'rubygems'
|
11
12
|
require 'active_model'
|
12
13
|
rescue LoadError
|
13
|
-
puts "0 failures, 0 errors"
|
14
|
+
puts "0 failures, 0 errors, skipping tests"
|
14
15
|
else
|
15
16
|
require 'test/unit'
|
16
17
|
require "test/unit/ui/console/testrunner"
|
17
18
|
class AMLintTest < Test::Unit::TestCase
|
18
19
|
def setup
|
19
20
|
@c = Class.new(Sequel::Model) do
|
21
|
+
set_primary_key :id
|
22
|
+
columns :id, :id2
|
20
23
|
def delete; end
|
21
24
|
end
|
22
25
|
@c.plugin :active_model
|
@@ -25,22 +28,42 @@ describe "ActiveModel plugin" do
|
|
25
28
|
end
|
26
29
|
include ActiveModel::Lint::Tests
|
27
30
|
|
28
|
-
|
31
|
+
# Should return self, not a proxy object
|
32
|
+
def test__to_model
|
29
33
|
assert_equal @m.to_model.object_id.should, @m.object_id
|
30
34
|
end
|
31
|
-
|
32
|
-
def
|
33
|
-
assert_equal
|
34
|
-
|
35
|
+
|
36
|
+
def test__to_key
|
37
|
+
assert_equal nil, @m.to_key
|
38
|
+
@o.id = 1
|
39
|
+
assert_equal [1], @o.to_key
|
40
|
+
@c.set_primary_key [:id2, :id]
|
41
|
+
@o.id2 = 2
|
42
|
+
assert_equal [2, 1], @o.to_key
|
43
|
+
@o.destroy
|
44
|
+
assert_equal nil, @o.to_key
|
45
|
+
end
|
46
|
+
|
47
|
+
def test__to_param
|
48
|
+
assert_equal nil, @m.to_param
|
49
|
+
@o.id = 1
|
50
|
+
assert_equal '1', @o.to_param
|
51
|
+
@c.set_primary_key [:id2, :id]
|
52
|
+
@o.id2 = 2
|
53
|
+
assert_equal '2-1', @o.to_param
|
54
|
+
@o.meta_def(:to_param_joiner){'|'}
|
55
|
+
assert_equal '2|1', @o.to_param
|
56
|
+
@o.destroy
|
57
|
+
assert_equal nil, @o.to_param
|
35
58
|
end
|
36
59
|
|
37
|
-
def
|
38
|
-
assert_equal false, @m.
|
39
|
-
assert_equal
|
60
|
+
def test__persisted?
|
61
|
+
assert_equal false, @m.persisted?
|
62
|
+
assert_equal true, @o.persisted?
|
40
63
|
@m.destroy
|
41
64
|
@o.destroy
|
42
|
-
assert_equal
|
43
|
-
assert_equal
|
65
|
+
assert_equal false, @m.persisted?
|
66
|
+
assert_equal false, @o.persisted?
|
44
67
|
end
|
45
68
|
end
|
46
69
|
Test::Unit::UI::Console::TestRunner.run(AMLintTest)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "spec_helper")
|
2
|
+
|
3
|
+
describe "instance_filters plugin" do
|
4
|
+
before do
|
5
|
+
@c = Class.new(Sequel::Model(:people)) do
|
6
|
+
end
|
7
|
+
@sql = sql = ''
|
8
|
+
@v = v = [1]
|
9
|
+
@c.dataset.quote_identifiers = false
|
10
|
+
@c.dataset.meta_def(:update) do |opts|
|
11
|
+
sql.replace(update_sql(opts))
|
12
|
+
return v.first
|
13
|
+
end
|
14
|
+
@c.dataset.meta_def(:delete) do
|
15
|
+
sql.replace(delete_sql)
|
16
|
+
return v.first
|
17
|
+
end
|
18
|
+
@c.columns :id, :name, :num
|
19
|
+
@c.plugin :instance_filters
|
20
|
+
@p = @c.load(:id=>1, :name=>'John', :num=>1)
|
21
|
+
end
|
22
|
+
|
23
|
+
specify "should raise an error when updating a stale record" do
|
24
|
+
@p.update(:name=>'Bob')
|
25
|
+
@sql.should == "UPDATE people SET name = 'Bob' WHERE (id = 1)"
|
26
|
+
@p.instance_filter(:name=>'Jim')
|
27
|
+
@v.replace([0])
|
28
|
+
proc{@p.update(:name=>'Joe')}.should raise_error(Sequel::Plugins::InstanceFilters::Error)
|
29
|
+
@sql.should == "UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Jim'))"
|
30
|
+
end
|
31
|
+
|
32
|
+
specify "should raise an error when destroying a stale record" do
|
33
|
+
@p.destroy
|
34
|
+
@sql.should == "DELETE FROM people WHERE (id = 1)"
|
35
|
+
@p.instance_filter(:name=>'Jim')
|
36
|
+
@v.replace([0])
|
37
|
+
proc{@p.destroy}.should raise_error(Sequel::Plugins::InstanceFilters::Error)
|
38
|
+
@sql.should == "DELETE FROM people WHERE ((id = 1) AND (name = 'Jim'))"
|
39
|
+
end
|
40
|
+
|
41
|
+
specify "should apply all instance filters" do
|
42
|
+
@p.instance_filter(:name=>'Jim')
|
43
|
+
@p.instance_filter{num > 2}
|
44
|
+
@p.update(:name=>'Bob')
|
45
|
+
@sql.should == "UPDATE people SET name = 'Bob' WHERE ((id = 1) AND (name = 'Jim') AND (num > 2))"
|
46
|
+
end
|
47
|
+
|
48
|
+
specify "should drop instance filters after updating" do
|
49
|
+
@p.instance_filter(:name=>'Joe')
|
50
|
+
@p.update(:name=>'Joe')
|
51
|
+
@sql.should == "UPDATE people SET name = 'Joe' WHERE ((id = 1) AND (name = 'Joe'))"
|
52
|
+
@p.update(:name=>'Bob')
|
53
|
+
@sql.should == "UPDATE people SET name = 'Bob' WHERE (id = 1)"
|
54
|
+
end
|
55
|
+
end
|
@@ -38,11 +38,18 @@ describe "Simple Dataset operations" do
|
|
38
38
|
@ds.filter(1=>1).delete.should == 1
|
39
39
|
@ds.count.should == 0
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
specify "should update correctly" do
|
43
43
|
@ds.update(:number=>:number+1).should == 1
|
44
44
|
@ds.all.should == [{:id=>1, :number=>11}]
|
45
45
|
end
|
46
|
+
|
47
|
+
cspecify "should have update return the number of matched rows", [:mysql, :mysql], [:do, :mysql], [:ado] do
|
48
|
+
@ds.update(:number=>:number).should == 1
|
49
|
+
@ds.filter(:id=>1).update(:number=>:number).should == 1
|
50
|
+
@ds.filter(:id=>2).update(:number=>:number).should == 0
|
51
|
+
@ds.all.should == [{:id=>1, :number=>10}]
|
52
|
+
end
|
46
53
|
|
47
54
|
specify "should fetch all results correctly" do
|
48
55
|
@ds.all.should == [{:id=>1, :number=>10}]
|
@@ -52,6 +59,10 @@ describe "Simple Dataset operations" do
|
|
52
59
|
@ds.first.should == {:id=>1, :number=>10}
|
53
60
|
end
|
54
61
|
|
62
|
+
specify "should have distinct work with limit" do
|
63
|
+
@ds.limit(1).distinct.all.should == [{:id=>1, :number=>10}]
|
64
|
+
end
|
65
|
+
|
55
66
|
specify "should fetch correctly with a limit" do
|
56
67
|
@ds.order(:id).limit(2).all.should == [{:id=>1, :number=>10}]
|
57
68
|
@ds.insert(:number=>20)
|
@@ -75,6 +75,18 @@ describe "Sequel::Model basic support" do
|
|
75
75
|
i.save(:num)
|
76
76
|
Item.all.should == [Item.load(:id=>1, :name=>'K', :num=>2)]
|
77
77
|
end
|
78
|
+
|
79
|
+
specify "#save should check that the only a single row is modified, unless require_modification is false" do
|
80
|
+
i = Item.create(:name=>'a')
|
81
|
+
i.require_modification = true
|
82
|
+
i.delete
|
83
|
+
proc{i.save}.should raise_error(Sequel::NoExistingObject)
|
84
|
+
proc{i.delete}.should raise_error(Sequel::NoExistingObject)
|
85
|
+
|
86
|
+
i.require_modification = false
|
87
|
+
i.save
|
88
|
+
i.delete
|
89
|
+
end
|
78
90
|
|
79
91
|
specify ".to_hash should return a hash keyed on primary key if no argument provided" do
|
80
92
|
i = Item.create(:name=>'J')
|
@@ -47,7 +47,7 @@ describe "Class Table Inheritance Plugin" do
|
|
47
47
|
clear_sqls
|
48
48
|
end
|
49
49
|
after do
|
50
|
-
@db.drop_table :
|
50
|
+
@db.drop_table :staff, :executives, :managers, :employees
|
51
51
|
[:Executive, :Manager, :Staff, :Employee].each{|s| Object.send(:remove_const, s)}
|
52
52
|
end
|
53
53
|
|
@@ -752,3 +752,63 @@ if INTEGRATION_DB.dataset.supports_cte?
|
|
752
752
|
end
|
753
753
|
end
|
754
754
|
end
|
755
|
+
|
756
|
+
describe "Instance Filters plugin" do
|
757
|
+
before do
|
758
|
+
@db = INTEGRATION_DB
|
759
|
+
@db.create_table!(:items) do
|
760
|
+
primary_key :id
|
761
|
+
String :name
|
762
|
+
Integer :cost
|
763
|
+
Integer :number
|
764
|
+
end
|
765
|
+
class ::Item < Sequel::Model(@db)
|
766
|
+
plugin :instance_filters
|
767
|
+
end
|
768
|
+
@i = Item.create(:name=>'J', :number=>1, :cost=>2)
|
769
|
+
@i.instance_filter(:number=>1)
|
770
|
+
@i.set(:name=>'K')
|
771
|
+
end
|
772
|
+
after do
|
773
|
+
@db.drop_table(:items)
|
774
|
+
Object.send(:remove_const, :Item)
|
775
|
+
end
|
776
|
+
|
777
|
+
specify "should not raise an error if saving only updates one row" do
|
778
|
+
@i.save
|
779
|
+
@i.refresh.name.should == 'K'
|
780
|
+
end
|
781
|
+
|
782
|
+
specify "should raise error if saving doesn't update a row" do
|
783
|
+
@i.this.update(:number=>2)
|
784
|
+
proc{@i.save}.should raise_error(Sequel::Error)
|
785
|
+
end
|
786
|
+
|
787
|
+
specify "should apply all instance filters" do
|
788
|
+
@i.instance_filter{cost <= 2}
|
789
|
+
@i.this.update(:number=>2)
|
790
|
+
proc{@i.save}.should raise_error(Sequel::Error)
|
791
|
+
@i.this.update(:number=>1, :cost=>3)
|
792
|
+
proc{@i.save}.should raise_error(Sequel::Error)
|
793
|
+
@i.this.update(:cost=>2)
|
794
|
+
@i.save
|
795
|
+
@i.refresh.name.should == 'K'
|
796
|
+
end
|
797
|
+
|
798
|
+
specify "should clear instance filters after successful save" do
|
799
|
+
@i.save
|
800
|
+
@i.this.update(:number=>2)
|
801
|
+
@i.update(:name=>'L')
|
802
|
+
@i.refresh.name.should == 'L'
|
803
|
+
end
|
804
|
+
|
805
|
+
specify "should not raise an error if deleting only deletes one row" do
|
806
|
+
@i.destroy
|
807
|
+
proc{@i.refresh}.should raise_error(Sequel::Error, 'Record not found')
|
808
|
+
end
|
809
|
+
|
810
|
+
specify "should raise error if destroying doesn't delete a row" do
|
811
|
+
@i.this.update(:number=>2)
|
812
|
+
proc{@i.destroy}.should raise_error(Sequel::Error)
|
813
|
+
end
|
814
|
+
end
|
@@ -87,10 +87,10 @@ describe "Database schema parser" do
|
|
87
87
|
INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
|
88
88
|
INTEGRATION_DB.create_table!(:items){Float :number}
|
89
89
|
INTEGRATION_DB.schema(:items).first.last[:type].should == :float
|
90
|
-
INTEGRATION_DB.create_table!(:items){BigDecimal :number}
|
91
|
-
INTEGRATION_DB.schema(:items).first.last[:type].should == :decimal
|
92
|
-
INTEGRATION_DB.create_table!(:items){Numeric :number}
|
90
|
+
INTEGRATION_DB.create_table!(:items){BigDecimal :number, :size=>[11, 2]}
|
93
91
|
INTEGRATION_DB.schema(:items).first.last[:type].should == :decimal
|
92
|
+
INTEGRATION_DB.create_table!(:items){Numeric :number, :size=>[12, 0]}
|
93
|
+
INTEGRATION_DB.schema(:items).first.last[:type].should == :integer
|
94
94
|
INTEGRATION_DB.create_table!(:items){String :number}
|
95
95
|
INTEGRATION_DB.schema(:items).first.last[:type].should == :string
|
96
96
|
INTEGRATION_DB.create_table!(:items){Date :number}
|
@@ -159,6 +159,17 @@ describe "Database schema modifiers" do
|
|
159
159
|
@ds.columns!.should == [:number]
|
160
160
|
end
|
161
161
|
|
162
|
+
specify "should rename tables correctly" do
|
163
|
+
@db.drop_table(:items) rescue nil
|
164
|
+
@db.create_table!(:items2){Integer :number}
|
165
|
+
@db.rename_table(:items2, :items)
|
166
|
+
@db.table_exists?(:items).should == true
|
167
|
+
@db.table_exists?(:items2).should == false
|
168
|
+
@db.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
|
169
|
+
@ds.insert([10])
|
170
|
+
@ds.columns!.should == [:number]
|
171
|
+
end
|
172
|
+
|
162
173
|
specify "should allow creating indexes with tables" do
|
163
174
|
@db.create_table!(:items){Integer :number; index :number}
|
164
175
|
@db.table_exists?(:items).should == true
|
data/spec/model/base_spec.rb
CHANGED
@@ -327,6 +327,33 @@ describe Sequel::Model, ".strict_param_setting" do
|
|
327
327
|
end
|
328
328
|
end
|
329
329
|
|
330
|
+
describe Sequel::Model, ".require_modification" do
|
331
|
+
before do
|
332
|
+
@ds1 = MODEL_DB[:items]
|
333
|
+
@ds1.meta_def(:provides_accurate_rows_matched?){false}
|
334
|
+
@ds2 = MODEL_DB[:items]
|
335
|
+
@ds2.meta_def(:provides_accurate_rows_matched?){true}
|
336
|
+
end
|
337
|
+
after do
|
338
|
+
Sequel::Model.require_modification = nil
|
339
|
+
end
|
340
|
+
|
341
|
+
it "should depend on whether the dataset provides an accurate number of rows matched by default" do
|
342
|
+
Class.new(Sequel::Model(@ds1)).require_modification.should == false
|
343
|
+
Class.new(Sequel::Model(@ds2)).require_modification.should == true
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should obey global setting regardless of dataset support if set" do
|
347
|
+
Sequel::Model.require_modification = true
|
348
|
+
Class.new(Sequel::Model(@ds1)).require_modification.should == true
|
349
|
+
Class.new(Sequel::Model(@ds2)).require_modification.should == true
|
350
|
+
|
351
|
+
Sequel::Model.require_modification = false
|
352
|
+
Class.new(Sequel::Model(@ds1)).require_modification.should == false
|
353
|
+
Class.new(Sequel::Model(@ds2)).require_modification.should == false
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
330
357
|
describe Sequel::Model, ".[] optimization" do
|
331
358
|
before do
|
332
359
|
@c = Class.new(Sequel::Model(:a))
|
data/spec/model/plugins_spec.rb
CHANGED
@@ -163,39 +163,17 @@ describe Sequel::Model, ".plugin" do
|
|
163
163
|
m.get_stamp.should == t
|
164
164
|
end
|
165
165
|
|
166
|
-
it "should define a plugin_opts instance method if the plugin has an InstanceMethods module" do
|
167
|
-
@c.plugin :timestamped, 1, 2=>3
|
168
|
-
@c.new.timestamped_opts.should == [1, {2=>3}]
|
169
|
-
end
|
170
|
-
|
171
166
|
it "should extend the class with a ClassMethods module if the plugin includes it" do
|
172
167
|
@c.plugin @t
|
173
168
|
@c.def.should == 234
|
174
169
|
end
|
175
170
|
|
176
|
-
it "should define a plugin_opts class method if the plugin has a ClassMethods module" do
|
177
|
-
@c.plugin :timestamped, 1, 2=>3
|
178
|
-
@c.timestamped_opts.should == [1, {2=>3}]
|
179
|
-
end
|
180
|
-
|
181
171
|
it "should extend the class's dataset with a DatasetMethods module if the plugin includes it" do
|
182
172
|
@c.plugin @t
|
183
173
|
@c.dataset.ghi.should == 345
|
184
174
|
@c.ghi.should == 345
|
185
175
|
end
|
186
176
|
|
187
|
-
it "should define a plugin_opts dataset method if the plugin has a DatasetMethods module" do
|
188
|
-
@c.plugin :timestamped, 1, 2=>3
|
189
|
-
@c.dataset.timestamped_opts.should == [1, {2=>3}]
|
190
|
-
end
|
191
|
-
|
192
|
-
it "should use a single arg for the plugin_opts method if only a single arg was given" do
|
193
|
-
@c.plugin :timestamped, 1
|
194
|
-
@c.new.timestamped_opts.should == 1
|
195
|
-
@c.timestamped_opts.should == 1
|
196
|
-
@c.dataset.timestamped_opts.should == 1
|
197
|
-
end
|
198
|
-
|
199
177
|
it "should save the DatasetMethods module and apply it later if the class doesn't have a dataset" do
|
200
178
|
c = Class.new(Sequel::Model)
|
201
179
|
c.plugin @t
|
data/spec/model/record_spec.rb
CHANGED
@@ -97,6 +97,22 @@ describe "Model#save" do
|
|
97
97
|
MODEL_DB.sqls.should == ["UPDATE items SET x = 1 WHERE (id = 3)"]
|
98
98
|
end
|
99
99
|
|
100
|
+
it "should raise a NoExistingObject exception if the dataset update call doesn't return 1, unless require_modification is false" do
|
101
|
+
o = @c.load(:id => 3, :x => 1)
|
102
|
+
o.this.meta_def(:update){|*a| 0}
|
103
|
+
proc{o.save}.should raise_error(Sequel::NoExistingObject)
|
104
|
+
o.this.meta_def(:update){|*a| 2}
|
105
|
+
proc{o.save}.should raise_error(Sequel::NoExistingObject)
|
106
|
+
o.this.meta_def(:update){|*a| 1}
|
107
|
+
proc{o.save}.should_not raise_error
|
108
|
+
|
109
|
+
o.require_modification = false
|
110
|
+
o.this.meta_def(:update){|*a| 0}
|
111
|
+
proc{o.save}.should_not raise_error
|
112
|
+
o.this.meta_def(:update){|*a| 2}
|
113
|
+
proc{o.save}.should_not raise_error
|
114
|
+
end
|
115
|
+
|
100
116
|
it "should update only the given columns if given" do
|
101
117
|
o = @c.load(:id => 3, :x => 1, :y => nil)
|
102
118
|
o.save(:y)
|
@@ -788,7 +804,7 @@ describe Sequel::Model, "#destroy" do
|
|
788
804
|
MODEL_DB.reset
|
789
805
|
@model = Class.new(Sequel::Model(:items))
|
790
806
|
@model.columns :id
|
791
|
-
@model.dataset.meta_def(:delete)
|
807
|
+
@model.dataset.meta_def(:delete){MODEL_DB.execute delete_sql;1}
|
792
808
|
|
793
809
|
@instance = @model.load(:id => 1234)
|
794
810
|
end
|
@@ -797,6 +813,21 @@ describe Sequel::Model, "#destroy" do
|
|
797
813
|
@model.send(:define_method, :after_destroy){3}
|
798
814
|
@instance.destroy.should == @instance
|
799
815
|
end
|
816
|
+
|
817
|
+
it "should raise a NoExistingObject exception if the dataset delete call doesn't return 1" do
|
818
|
+
@instance.this.meta_def(:delete){|*a| 0}
|
819
|
+
proc{@instance.delete}.should raise_error(Sequel::NoExistingObject)
|
820
|
+
@instance.this.meta_def(:delete){|*a| 2}
|
821
|
+
proc{@instance.delete}.should raise_error(Sequel::NoExistingObject)
|
822
|
+
@instance.this.meta_def(:delete){|*a| 1}
|
823
|
+
proc{@instance.delete}.should_not raise_error
|
824
|
+
|
825
|
+
@instance.require_modification = false
|
826
|
+
@instance.this.meta_def(:delete){|*a| 0}
|
827
|
+
proc{@instance.delete}.should_not raise_error
|
828
|
+
@instance.this.meta_def(:delete){|*a| 2}
|
829
|
+
proc{@instance.delete}.should_not raise_error
|
830
|
+
end
|
800
831
|
|
801
832
|
it "should run within a transaction if use_transactions is true" do
|
802
833
|
@instance.use_transactions = true
|