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