sequel 2.4.0 → 2.5.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 +34 -0
- data/Rakefile +1 -1
- data/lib/sequel_core.rb +16 -7
- data/lib/sequel_core/adapters/ado.rb +6 -2
- data/lib/sequel_core/adapters/db2.rb +1 -1
- data/lib/sequel_core/adapters/jdbc.rb +2 -2
- data/lib/sequel_core/adapters/jdbc/postgresql.rb +22 -10
- data/lib/sequel_core/adapters/mysql.rb +2 -2
- data/lib/sequel_core/adapters/odbc.rb +6 -2
- data/lib/sequel_core/adapters/postgres.rb +25 -14
- data/lib/sequel_core/adapters/shared/mysql.rb +15 -35
- data/lib/sequel_core/adapters/shared/postgres.rb +137 -77
- data/lib/sequel_core/adapters/sqlite.rb +2 -2
- data/lib/sequel_core/core_ext.rb +11 -7
- data/lib/sequel_core/database.rb +18 -1
- data/lib/sequel_core/dataset.rb +23 -7
- data/lib/sequel_core/dataset/convenience.rb +1 -1
- data/lib/sequel_core/dataset/sql.rb +46 -31
- data/lib/sequel_core/exceptions.rb +4 -0
- data/lib/sequel_core/schema/generator.rb +43 -3
- data/lib/sequel_core/schema/sql.rb +52 -26
- data/lib/sequel_model.rb +2 -5
- data/lib/sequel_model/associations.rb +3 -3
- data/lib/sequel_model/base.rb +19 -13
- data/lib/sequel_model/record.rb +19 -11
- data/lib/sequel_model/schema.rb +10 -4
- data/lib/sequel_model/validations.rb +20 -7
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/postgres_spec.rb +64 -9
- data/spec/integration/dataset_test.rb +32 -0
- data/spec/sequel_core/core_sql_spec.rb +38 -0
- data/spec/sequel_core/database_spec.rb +16 -1
- data/spec/sequel_core/dataset_spec.rb +66 -1
- data/spec/sequel_core/schema_generator_spec.rb +23 -3
- data/spec/sequel_core/schema_spec.rb +175 -4
- data/spec/sequel_model/record_spec.rb +47 -0
- data/spec/sequel_model/validations_spec.rb +70 -0
- metadata +2 -2
@@ -999,4 +999,19 @@ context "Database#server_opts" do
|
|
999
999
|
opts = {:host=>1, :database=>2, :servers=>{:server1=>2}}
|
1000
1000
|
proc{MockDatabase.new(opts).send(:server_opts, :server1)}.should raise_error(Sequel::Error)
|
1001
1001
|
end
|
1002
|
-
end
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
context "Database#raise_error" do
|
1005
|
+
specify "should reraise if the exception class is not in opts[:classes]" do
|
1006
|
+
e = Class.new(StandardError)
|
1007
|
+
proc{MockDatabase.new.send(:raise_error, e.new(''), :classes=>[])}.should raise_error(e)
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
specify "should convert the exception to a DatabaseError if the exception class is not in opts[:classes]" do
|
1011
|
+
proc{MockDatabase.new.send(:raise_error, Interrupt.new(''), :classes=>[Interrupt])}.should raise_error(Sequel::DatabaseError)
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
specify "should convert the exception to a DatabaseError if opts[:classes] if not present" do
|
1015
|
+
proc{MockDatabase.new.send(:raise_error, Interrupt.new(''))}.should raise_error(Sequel::DatabaseError)
|
1016
|
+
end
|
1017
|
+
end
|
@@ -161,6 +161,16 @@ context "A simple dataset" do
|
|
161
161
|
@dataset.select_sql(:sql => 'xxx yyy zzz').should ==
|
162
162
|
"xxx yyy zzz"
|
163
163
|
end
|
164
|
+
|
165
|
+
specify "should use the :sql option for all sql methods" do
|
166
|
+
sql = "X"
|
167
|
+
ds = Sequel::Dataset.new(nil, :sql=>sql)
|
168
|
+
ds.sql.should == sql
|
169
|
+
ds.select_sql.should == sql
|
170
|
+
ds.insert_sql.should == sql
|
171
|
+
ds.delete_sql.should == sql
|
172
|
+
ds.update_sql.should == sql
|
173
|
+
end
|
164
174
|
end
|
165
175
|
|
166
176
|
context "A dataset with multiple tables in its FROM clause" do
|
@@ -1135,6 +1145,12 @@ context "Dataset#count" do
|
|
1135
1145
|
@dataset.limit(5).count.should == 1
|
1136
1146
|
@c.sql.should == "SELECT COUNT(*) FROM (SELECT * FROM test LIMIT 5) t1 LIMIT 1"
|
1137
1147
|
end
|
1148
|
+
|
1149
|
+
it "should work on a graphed_dataset" do
|
1150
|
+
@dataset.should_receive(:columns).twice.and_return([:a])
|
1151
|
+
@dataset.graph(@dataset, [:a], :table_alias=>:test2).count.should == 1
|
1152
|
+
@c.sql.should == 'SELECT COUNT(*) FROM test LEFT OUTER JOIN test AS test2 USING (a) LIMIT 1'
|
1153
|
+
end
|
1138
1154
|
end
|
1139
1155
|
|
1140
1156
|
|
@@ -1754,6 +1770,11 @@ context "Dataset#single_value" do
|
|
1754
1770
|
specify "should return nil if no records" do
|
1755
1771
|
@e.single_value.should be_nil
|
1756
1772
|
end
|
1773
|
+
|
1774
|
+
it "should work on a graphed_dataset" do
|
1775
|
+
@d.should_receive(:columns).twice.and_return([:a])
|
1776
|
+
@d.graph(@d, [:a], :table_alias=>:test2).single_value.should == 'SELECT test.a, test2.a AS test2_a FROM test LEFT OUTER JOIN test AS test2 USING (a) LIMIT 1'
|
1777
|
+
end
|
1757
1778
|
end
|
1758
1779
|
|
1759
1780
|
context "Dataset#get" do
|
@@ -3084,4 +3105,48 @@ context "Sequel::Dataset#server" do
|
|
3084
3105
|
['DELETE FROM items', :d],
|
3085
3106
|
['UPDATE items SET a = (a + 1)', :u]]
|
3086
3107
|
end
|
3087
|
-
end
|
3108
|
+
end
|
3109
|
+
|
3110
|
+
context "Sequel::Dataset #set_defaults" do
|
3111
|
+
before do
|
3112
|
+
@ds = Sequel::Dataset.new(nil).from(:items).set_defaults(:x=>1)
|
3113
|
+
end
|
3114
|
+
|
3115
|
+
specify "should set the default values for inserts" do
|
3116
|
+
@ds.insert_sql.should == "INSERT INTO items (x) VALUES (1)"
|
3117
|
+
@ds.insert_sql(:x=>2).should == "INSERT INTO items (x) VALUES (2)"
|
3118
|
+
@ds.insert_sql(:y=>2).should =~ /INSERT INTO items \([xy], [xy]\) VALUES \([21], [21]\)/
|
3119
|
+
@ds.set_defaults(:y=>2).insert_sql.should =~ /INSERT INTO items \([xy], [xy]\) VALUES \([21], [21]\)/
|
3120
|
+
@ds.set_defaults(:x=>2).insert_sql.should == "INSERT INTO items (x) VALUES (2)"
|
3121
|
+
end
|
3122
|
+
|
3123
|
+
specify "should set the default values for updates" do
|
3124
|
+
@ds.update_sql.should == "UPDATE items SET x = 1"
|
3125
|
+
@ds.update_sql(:x=>2).should == "UPDATE items SET x = 2"
|
3126
|
+
@ds.update_sql(:y=>2).should =~ /UPDATE items SET (x = 1|y = 2), (x = 1|y = 2)/
|
3127
|
+
@ds.set_defaults(:y=>2).update_sql.should =~ /UPDATE items SET (x = 1|y = 2), (x = 1|y = 2)/
|
3128
|
+
@ds.set_defaults(:x=>2).update_sql.should == "UPDATE items SET x = 2"
|
3129
|
+
end
|
3130
|
+
end
|
3131
|
+
|
3132
|
+
context "Sequel::Dataset #set_overrides" do
|
3133
|
+
before do
|
3134
|
+
@ds = Sequel::Dataset.new(nil).from(:items).set_overrides(:x=>1)
|
3135
|
+
end
|
3136
|
+
|
3137
|
+
specify "should override the given values for inserts" do
|
3138
|
+
@ds.insert_sql.should == "INSERT INTO items (x) VALUES (1)"
|
3139
|
+
@ds.insert_sql(:x=>2).should == "INSERT INTO items (x) VALUES (1)"
|
3140
|
+
@ds.insert_sql(:y=>2).should =~ /INSERT INTO items \([xy], [xy]\) VALUES \([21], [21]\)/
|
3141
|
+
@ds.set_overrides(:y=>2).insert_sql.should =~ /INSERT INTO items \([xy], [xy]\) VALUES \([21], [21]\)/
|
3142
|
+
@ds.set_overrides(:x=>2).insert_sql.should == "INSERT INTO items (x) VALUES (1)"
|
3143
|
+
end
|
3144
|
+
|
3145
|
+
specify "should override the given values for updates" do
|
3146
|
+
@ds.update_sql.should == "UPDATE items SET x = 1"
|
3147
|
+
@ds.update_sql(:x=>2).should == "UPDATE items SET x = 1"
|
3148
|
+
@ds.update_sql(:y=>2).should =~ /UPDATE items SET (x = 1|y = 2), (x = 1|y = 2)/
|
3149
|
+
@ds.set_overrides(:y=>2).update_sql.should =~ /UPDATE items SET (x = 1|y = 2), (x = 1|y = 2)/
|
3150
|
+
@ds.set_overrides(:x=>2).update_sql.should == "UPDATE items SET x = 1"
|
3151
|
+
end
|
3152
|
+
end
|
@@ -12,6 +12,8 @@ describe Sequel::Schema::Generator do
|
|
12
12
|
index :title
|
13
13
|
index [:title, :body]
|
14
14
|
foreign_key :node_id, :nodes
|
15
|
+
primary_key [:title, :parent_id], :name => :cpk
|
16
|
+
foreign_key [:node_id, :prop_id], :nodes_props, :name => :cfk
|
15
17
|
end
|
16
18
|
@columns, @indexes = @generator.create_info
|
17
19
|
end
|
@@ -23,7 +25,7 @@ describe Sequel::Schema::Generator do
|
|
23
25
|
end
|
24
26
|
|
25
27
|
it "counts primary key, column and constraint definitions as columns" do
|
26
|
-
@columns.size.should ==
|
28
|
+
@columns.size.should == 9
|
27
29
|
end
|
28
30
|
|
29
31
|
it "places primary key first" do
|
@@ -53,6 +55,7 @@ describe Sequel::Schema::Generator do
|
|
53
55
|
it "uses table for foreign key columns, if specified" do
|
54
56
|
@columns[6][:table].should == :nodes
|
55
57
|
@columns[3][:table].should == nil
|
58
|
+
@columns[8][:table].should == :nodes_props
|
56
59
|
end
|
57
60
|
|
58
61
|
it "finds columns" do
|
@@ -70,6 +73,17 @@ describe Sequel::Schema::Generator do
|
|
70
73
|
@columns[5][:name].should == :xxx
|
71
74
|
@columns[5][:type].should == :check
|
72
75
|
@columns[5][:check].should be_a_kind_of(Proc)
|
76
|
+
|
77
|
+
@columns[7][:name].should == :cpk
|
78
|
+
@columns[7][:type].should == :check
|
79
|
+
@columns[7][:constraint_type].should == :primary_key
|
80
|
+
@columns[7][:columns].should == [ :title, :parent_id ]
|
81
|
+
|
82
|
+
@columns[8][:name].should == :cfk
|
83
|
+
@columns[8][:type].should == :check
|
84
|
+
@columns[8][:constraint_type].should == :foreign_key
|
85
|
+
@columns[8][:columns].should == [ :node_id, :prop_id ]
|
86
|
+
@columns[8][:table].should == :nodes_props
|
73
87
|
end
|
74
88
|
|
75
89
|
it "creates indexes" do
|
@@ -95,8 +109,11 @@ describe Sequel::Schema::AlterTableGenerator do
|
|
95
109
|
add_index :blah, :where => {:something => true}
|
96
110
|
add_constraint :con1, ':fred > 100'
|
97
111
|
drop_constraint :con2
|
112
|
+
add_unique_constraint [:aaa, :bbb, :ccc], :name => :con3
|
98
113
|
add_primary_key :id
|
99
114
|
add_foreign_key :node_id, :nodes
|
115
|
+
add_primary_key [:aaa, :bbb]
|
116
|
+
add_foreign_key [:node_id, :prop_id], :nodes_props
|
100
117
|
end
|
101
118
|
end
|
102
119
|
|
@@ -113,10 +130,13 @@ describe Sequel::Schema::AlterTableGenerator do
|
|
113
130
|
{:op => :add_index, :columns => [:geom], :type => :spatial},
|
114
131
|
{:op => :add_index, :columns => [:blah], :type => :hash},
|
115
132
|
{:op => :add_index, :columns => [:blah], :where => {:something => true}},
|
116
|
-
{:op => :add_constraint, :type => :check, :name => :con1, :check => [':fred > 100']},
|
133
|
+
{:op => :add_constraint, :type => :check, :constraint_type => :check, :name => :con1, :check => [':fred > 100']},
|
117
134
|
{:op => :drop_constraint, :name => :con2},
|
135
|
+
{:op => :add_constraint, :type => :check, :constraint_type => :unique, :name => :con3, :columns => [:aaa, :bbb, :ccc]},
|
118
136
|
{:op => :add_column, :name => :id, :type => :integer, :primary_key=>true, :auto_increment=>true},
|
119
|
-
{:op => :add_column, :name => :node_id, :type => :integer, :table=>:nodes}
|
137
|
+
{:op => :add_column, :name => :node_id, :type => :integer, :table=>:nodes},
|
138
|
+
{:op => :add_constraint, :type => :check, :constraint_type => :primary_key, :columns => [:aaa, :bbb]},
|
139
|
+
{:op => :add_constraint, :type => :check, :constraint_type => :foreign_key, :columns => [:node_id, :prop_id], :table => :nodes_props}
|
120
140
|
]
|
121
141
|
end
|
122
142
|
end
|
@@ -103,11 +103,11 @@ context "DB#create_table" do
|
|
103
103
|
@db.sqls.should == ["CREATE TABLE cats (name varchar(51))"]
|
104
104
|
end
|
105
105
|
|
106
|
-
specify "should
|
106
|
+
specify "should use double precision for double type" do
|
107
107
|
@db.create_table(:cats) do
|
108
|
-
|
108
|
+
double :name
|
109
109
|
end
|
110
|
-
@db.sqls.should == ["CREATE TABLE cats (name
|
110
|
+
@db.sqls.should == ["CREATE TABLE cats (name double precision)"]
|
111
111
|
end
|
112
112
|
|
113
113
|
specify "should accept foreign keys without options" do
|
@@ -181,6 +181,40 @@ context "DB#create_table" do
|
|
181
181
|
@db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON DELETE SET DEFAULT)"]
|
182
182
|
@db.sqls.clear
|
183
183
|
end
|
184
|
+
|
185
|
+
specify "should accept foreign keys with ON UPDATE clause" do
|
186
|
+
@db.create_table(:cats) do
|
187
|
+
foreign_key :project_id, :table => :projects, :on_update => :restrict
|
188
|
+
end
|
189
|
+
@db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE RESTRICT)"]
|
190
|
+
|
191
|
+
@db.sqls.clear
|
192
|
+
@db.create_table(:cats) do
|
193
|
+
foreign_key :project_id, :table => :projects, :on_update => :cascade
|
194
|
+
end
|
195
|
+
@db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE CASCADE)"]
|
196
|
+
|
197
|
+
@db.sqls.clear
|
198
|
+
@db.create_table(:cats) do
|
199
|
+
foreign_key :project_id, :table => :projects, :on_update => :no_action
|
200
|
+
end
|
201
|
+
@db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE NO ACTION)"]
|
202
|
+
@db.sqls.clear
|
203
|
+
|
204
|
+
@db.sqls.clear
|
205
|
+
@db.create_table(:cats) do
|
206
|
+
foreign_key :project_id, :table => :projects, :on_update => :set_null
|
207
|
+
end
|
208
|
+
@db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE SET NULL)"]
|
209
|
+
@db.sqls.clear
|
210
|
+
|
211
|
+
@db.sqls.clear
|
212
|
+
@db.create_table(:cats) do
|
213
|
+
foreign_key :project_id, :table => :projects, :on_update => :set_default
|
214
|
+
end
|
215
|
+
@db.sqls.should == ["CREATE TABLE cats (project_id integer REFERENCES projects ON UPDATE SET DEFAULT)"]
|
216
|
+
@db.sqls.clear
|
217
|
+
end
|
184
218
|
|
185
219
|
specify "should accept inline index definition" do
|
186
220
|
@db.create_table(:cats) do
|
@@ -210,7 +244,7 @@ context "DB#create_table" do
|
|
210
244
|
text :name
|
211
245
|
unique :name
|
212
246
|
end
|
213
|
-
@db.sqls.should == ["CREATE TABLE cats (name text)", "CREATE UNIQUE INDEX cats_name_index ON cats (name)"]
|
247
|
+
@db.sqls.should == ["CREATE TABLE cats (name text, UNIQUE (name))", "CREATE UNIQUE INDEX cats_name_index ON cats (name)"]
|
214
248
|
end
|
215
249
|
|
216
250
|
specify "should raise on full-text index definitions" do
|
@@ -311,6 +345,92 @@ context "DB#create_table" do
|
|
311
345
|
end
|
312
346
|
@db.sqls.should == ["CREATE TABLE cats (CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1)))"]
|
313
347
|
end
|
348
|
+
|
349
|
+
specify "should accept composite primary keys" do
|
350
|
+
@db.create_table(:cats) do
|
351
|
+
integer :a
|
352
|
+
integer :b
|
353
|
+
primary_key [:a, :b]
|
354
|
+
end
|
355
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, PRIMARY KEY (a, b))"]
|
356
|
+
end
|
357
|
+
|
358
|
+
specify "should accept named composite primary keys" do
|
359
|
+
@db.create_table(:cats) do
|
360
|
+
integer :a
|
361
|
+
integer :b
|
362
|
+
primary_key [:a, :b], :name => :cpk
|
363
|
+
end
|
364
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, CONSTRAINT cpk PRIMARY KEY (a, b))"]
|
365
|
+
end
|
366
|
+
|
367
|
+
specify "should accept composite foreign keys" do
|
368
|
+
@db.create_table(:cats) do
|
369
|
+
integer :a
|
370
|
+
integer :b
|
371
|
+
foreign_key [:a, :b], :abc
|
372
|
+
end
|
373
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc)"]
|
374
|
+
end
|
375
|
+
|
376
|
+
specify "should accept named composite foreign keys" do
|
377
|
+
@db.create_table(:cats) do
|
378
|
+
integer :a
|
379
|
+
integer :b
|
380
|
+
foreign_key [:a, :b], :abc, :name => :cfk
|
381
|
+
end
|
382
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, CONSTRAINT cfk FOREIGN KEY (a, b) REFERENCES abc)"]
|
383
|
+
end
|
384
|
+
|
385
|
+
specify "should accept composite foreign keys with arbitrary keys" do
|
386
|
+
@db.create_table(:cats) do
|
387
|
+
integer :a
|
388
|
+
integer :b
|
389
|
+
foreign_key [:a, :b], :abc, :key => [:real_a, :real_b]
|
390
|
+
end
|
391
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc(real_a, real_b))"]
|
392
|
+
@db.sqls.clear
|
393
|
+
|
394
|
+
@db.create_table(:cats) do
|
395
|
+
integer :a
|
396
|
+
integer :b
|
397
|
+
foreign_key [:a, :b], :abc, :key => [:z, :x]
|
398
|
+
end
|
399
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc(z, x))"]
|
400
|
+
end
|
401
|
+
|
402
|
+
specify "should accept composite foreign keys with on delete and on update clauses" do
|
403
|
+
@db.create_table(:cats) do
|
404
|
+
integer :a
|
405
|
+
integer :b
|
406
|
+
foreign_key [:a, :b], :abc, :on_delete => :cascade
|
407
|
+
end
|
408
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc ON DELETE CASCADE)"]
|
409
|
+
|
410
|
+
@db.sqls.clear
|
411
|
+
@db.create_table(:cats) do
|
412
|
+
integer :a
|
413
|
+
integer :b
|
414
|
+
foreign_key [:a, :b], :abc, :on_update => :no_action
|
415
|
+
end
|
416
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc ON UPDATE NO ACTION)"]
|
417
|
+
|
418
|
+
@db.sqls.clear
|
419
|
+
@db.create_table(:cats) do
|
420
|
+
integer :a
|
421
|
+
integer :b
|
422
|
+
foreign_key [:a, :b], :abc, :on_delete => :restrict, :on_update => :set_default
|
423
|
+
end
|
424
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc ON DELETE RESTRICT ON UPDATE SET DEFAULT)"]
|
425
|
+
|
426
|
+
@db.sqls.clear
|
427
|
+
@db.create_table(:cats) do
|
428
|
+
integer :a
|
429
|
+
integer :b
|
430
|
+
foreign_key [:a, :b], :abc, :key => [:x, :y], :on_delete => :set_null, :on_update => :set_null
|
431
|
+
end
|
432
|
+
@db.sqls.should == ["CREATE TABLE cats (a integer, b integer, FOREIGN KEY (a, b) REFERENCES abc(x, y) ON DELETE SET NULL ON UPDATE SET NULL)"]
|
433
|
+
end
|
314
434
|
end
|
315
435
|
|
316
436
|
context "DB#create_table!" do
|
@@ -361,6 +481,19 @@ context "DB#alter_table" do
|
|
361
481
|
@db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT blah_blah CHECK ((x > 0) AND (y < 1))"]
|
362
482
|
end
|
363
483
|
|
484
|
+
specify "should support add_unique_constraint" do
|
485
|
+
@db.alter_table(:cats) do
|
486
|
+
add_unique_constraint [:a, :b]
|
487
|
+
end
|
488
|
+
@db.sqls.should == ["ALTER TABLE cats ADD UNIQUE (a, b)"]
|
489
|
+
|
490
|
+
@db.sqls.clear
|
491
|
+
@db.alter_table(:cats) do
|
492
|
+
add_unique_constraint [:a, :b], :name => :ab_uniq
|
493
|
+
end
|
494
|
+
@db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT ab_uniq UNIQUE (a, b)"]
|
495
|
+
end
|
496
|
+
|
364
497
|
specify "should support add_foreign_key" do
|
365
498
|
@db.alter_table(:cats) do
|
366
499
|
add_foreign_key :node_id, :nodes
|
@@ -368,6 +501,31 @@ context "DB#alter_table" do
|
|
368
501
|
@db.sqls.should == ["ALTER TABLE cats ADD COLUMN node_id integer REFERENCES nodes"]
|
369
502
|
end
|
370
503
|
|
504
|
+
specify "should support add_foreign_key with composite foreign keys" do
|
505
|
+
@db.alter_table(:cats) do
|
506
|
+
add_foreign_key [:node_id, :prop_id], :nodes_props
|
507
|
+
end
|
508
|
+
@db.sqls.should == ["ALTER TABLE cats ADD FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props"]
|
509
|
+
|
510
|
+
@db.sqls.clear
|
511
|
+
@db.alter_table(:cats) do
|
512
|
+
add_foreign_key [:node_id, :prop_id], :nodes_props, :name => :cfk
|
513
|
+
end
|
514
|
+
@db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT cfk FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props"]
|
515
|
+
|
516
|
+
@db.sqls.clear
|
517
|
+
@db.alter_table(:cats) do
|
518
|
+
add_foreign_key [:node_id, :prop_id], :nodes_props, :key => [:nid, :pid]
|
519
|
+
end
|
520
|
+
@db.sqls.should == ["ALTER TABLE cats ADD FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props(nid, pid)"]
|
521
|
+
|
522
|
+
@db.sqls.clear
|
523
|
+
@db.alter_table(:cats) do
|
524
|
+
add_foreign_key [:node_id, :prop_id], :nodes_props, :on_delete => :restrict, :on_update => :cascade
|
525
|
+
end
|
526
|
+
@db.sqls.should == ["ALTER TABLE cats ADD FOREIGN KEY (node_id, prop_id) REFERENCES nodes_props ON DELETE RESTRICT ON UPDATE CASCADE"]
|
527
|
+
end
|
528
|
+
|
371
529
|
specify "should support add_index" do
|
372
530
|
@db.alter_table(:cats) do
|
373
531
|
add_index :name
|
@@ -382,6 +540,19 @@ context "DB#alter_table" do
|
|
382
540
|
@db.sqls.should == ["ALTER TABLE cats ADD COLUMN id integer PRIMARY KEY AUTOINCREMENT"]
|
383
541
|
end
|
384
542
|
|
543
|
+
specify "should support add_primary_key with composite primary keys" do
|
544
|
+
@db.alter_table(:cats) do
|
545
|
+
add_primary_key [:id, :type]
|
546
|
+
end
|
547
|
+
@db.sqls.should == ["ALTER TABLE cats ADD PRIMARY KEY (id, type)"]
|
548
|
+
|
549
|
+
@db.sqls.clear
|
550
|
+
@db.alter_table(:cats) do
|
551
|
+
add_primary_key [:id, :type], :name => :cpk
|
552
|
+
end
|
553
|
+
@db.sqls.should == ["ALTER TABLE cats ADD CONSTRAINT cpk PRIMARY KEY (id, type)"]
|
554
|
+
end
|
555
|
+
|
385
556
|
specify "should support drop_column" do
|
386
557
|
@db.alter_table(:cats) do
|
387
558
|
drop_column :score
|
@@ -17,6 +17,19 @@ describe "Model#save" do
|
|
17
17
|
MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (1)"
|
18
18
|
end
|
19
19
|
|
20
|
+
it "should use dataset's insert_select method if present" do
|
21
|
+
ds = @c.dataset = @c.dataset.clone
|
22
|
+
def ds.insert_select(hash)
|
23
|
+
execute("INSERT INTO items (y) VALUES (2)")
|
24
|
+
{:y=>2}
|
25
|
+
end
|
26
|
+
o = @c.new(:x => 1)
|
27
|
+
o.save
|
28
|
+
|
29
|
+
o.values.should == {:y=>2}
|
30
|
+
MODEL_DB.sqls.first.should == "INSERT INTO items (y) VALUES (2)"
|
31
|
+
end
|
32
|
+
|
20
33
|
it "should update a record for an existing model instance" do
|
21
34
|
o = @c.load(:id => 3, :x => 1)
|
22
35
|
o.save
|
@@ -104,6 +117,40 @@ describe "Model#save_changes" do
|
|
104
117
|
o.save_changes
|
105
118
|
MODEL_DB.sqls.should == ["UPDATE items SET y = 4 WHERE (id = 3)"]
|
106
119
|
end
|
120
|
+
|
121
|
+
it "should update columns changed in a before_update hook" do
|
122
|
+
o = @c.load(:id => 3, :x => 1, :y => nil)
|
123
|
+
@c.before_update{self.x += 1}
|
124
|
+
o.save_changes
|
125
|
+
MODEL_DB.sqls.should == []
|
126
|
+
o.x = 2
|
127
|
+
o.save_changes
|
128
|
+
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
129
|
+
MODEL_DB.reset
|
130
|
+
o.save_changes
|
131
|
+
MODEL_DB.sqls.should == []
|
132
|
+
o.x = 4
|
133
|
+
o.save_changes
|
134
|
+
MODEL_DB.sqls.should == ["UPDATE items SET x = 5 WHERE (id = 3)"]
|
135
|
+
MODEL_DB.reset
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should update columns changed in a before_save hook" do
|
139
|
+
o = @c.load(:id => 3, :x => 1, :y => nil)
|
140
|
+
@c.before_save{self.x += 1}
|
141
|
+
o.save_changes
|
142
|
+
MODEL_DB.sqls.should == []
|
143
|
+
o.x = 2
|
144
|
+
o.save_changes
|
145
|
+
MODEL_DB.sqls.should == ["UPDATE items SET x = 3 WHERE (id = 3)"]
|
146
|
+
MODEL_DB.reset
|
147
|
+
o.save_changes
|
148
|
+
MODEL_DB.sqls.should == []
|
149
|
+
o.x = 4
|
150
|
+
o.save_changes
|
151
|
+
MODEL_DB.sqls.should == ["UPDATE items SET x = 5 WHERE (id = 3)"]
|
152
|
+
MODEL_DB.reset
|
153
|
+
end
|
107
154
|
end
|
108
155
|
|
109
156
|
describe "Model#update_values" do
|