sequel 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +76 -0
- data/Rakefile +2 -2
- data/bin/sequel +9 -4
- data/doc/opening_databases.rdoc +279 -0
- data/doc/release_notes/3.2.0.txt +268 -0
- data/doc/virtual_rows.rdoc +42 -51
- data/lib/sequel/adapters/ado.rb +2 -5
- data/lib/sequel/adapters/db2.rb +5 -0
- data/lib/sequel/adapters/do.rb +3 -0
- data/lib/sequel/adapters/firebird.rb +6 -4
- data/lib/sequel/adapters/informix.rb +5 -3
- data/lib/sequel/adapters/jdbc.rb +10 -8
- data/lib/sequel/adapters/jdbc/h2.rb +17 -4
- data/lib/sequel/adapters/mysql.rb +6 -19
- data/lib/sequel/adapters/odbc.rb +14 -18
- data/lib/sequel/adapters/openbase.rb +8 -0
- data/lib/sequel/adapters/shared/mssql.rb +14 -8
- data/lib/sequel/adapters/shared/mysql.rb +53 -28
- data/lib/sequel/adapters/shared/oracle.rb +21 -12
- data/lib/sequel/adapters/shared/postgres.rb +46 -26
- data/lib/sequel/adapters/shared/progress.rb +10 -5
- data/lib/sequel/adapters/shared/sqlite.rb +28 -12
- data/lib/sequel/adapters/sqlite.rb +4 -3
- data/lib/sequel/adapters/utils/stored_procedures.rb +18 -9
- data/lib/sequel/connection_pool.rb +4 -3
- data/lib/sequel/database.rb +110 -10
- data/lib/sequel/database/schema_sql.rb +12 -3
- data/lib/sequel/dataset.rb +40 -3
- data/lib/sequel/dataset/convenience.rb +0 -11
- data/lib/sequel/dataset/graph.rb +25 -11
- data/lib/sequel/dataset/sql.rb +176 -68
- data/lib/sequel/extensions/migration.rb +37 -21
- data/lib/sequel/extensions/schema_dumper.rb +8 -61
- data/lib/sequel/model.rb +3 -3
- data/lib/sequel/model/associations.rb +9 -1
- data/lib/sequel/model/base.rb +8 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/sql.rb +125 -18
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/ado_spec.rb +1 -0
- data/spec/adapters/firebird_spec.rb +1 -0
- data/spec/adapters/informix_spec.rb +1 -0
- data/spec/adapters/mysql_spec.rb +23 -8
- data/spec/adapters/oracle_spec.rb +1 -0
- data/spec/adapters/postgres_spec.rb +52 -4
- data/spec/adapters/spec_helper.rb +2 -2
- data/spec/adapters/sqlite_spec.rb +2 -1
- data/spec/core/connection_pool_spec.rb +16 -0
- data/spec/core/database_spec.rb +174 -0
- data/spec/core/dataset_spec.rb +121 -26
- data/spec/core/expression_filters_spec.rb +156 -0
- data/spec/core/object_graph_spec.rb +20 -1
- data/spec/core/schema_spec.rb +5 -5
- data/spec/extensions/migration_spec.rb +140 -74
- data/spec/extensions/schema_dumper_spec.rb +3 -69
- data/spec/extensions/single_table_inheritance_spec.rb +6 -0
- data/spec/integration/dataset_test.rb +84 -2
- data/spec/integration/schema_test.rb +24 -5
- data/spec/integration/spec_helper.rb +8 -6
- data/spec/model/eager_loading_spec.rb +9 -0
- data/spec/model/record_spec.rb +35 -8
- metadata +8 -7
- data/lib/sequel/adapters/utils/date_format.rb +0 -21
- data/lib/sequel/adapters/utils/savepoint_transactions.rb +0 -80
- data/lib/sequel/adapters/utils/unsupported.rb +0 -50
@@ -228,41 +228,9 @@ END_MIG
|
|
228
228
|
@d.dump_table_schema(:t3).should == "create_table(:t3) do\n Date :c1\n DateTime :c2, :null=>false\nend"
|
229
229
|
end
|
230
230
|
|
231
|
-
it "should handle converting many default formats" do
|
232
|
-
m = @d.method(:column_schema_to_ruby_default)
|
233
|
-
m.call("adf", :string, :same_db=>true).inspect.should == '"adf".lit'
|
234
|
-
p = lambda{|d,t| m.call(d,t,{})}
|
235
|
-
p[nil, :integer].should == nil
|
236
|
-
p['1', :integer].should == 1
|
237
|
-
p['-1', :integer].should == -1
|
238
|
-
p['1.0', :float].should == 1.0
|
239
|
-
p['-1.0', :float].should == -1.0
|
240
|
-
p['1.0', :decimal].should == BigDecimal.new('1.0')
|
241
|
-
p['-1.0', :decimal].should == BigDecimal.new('-1.0')
|
242
|
-
p['1', :boolean].should == true
|
243
|
-
p['0', :boolean].should == false
|
244
|
-
p['true', :boolean].should == true
|
245
|
-
p['false', :boolean].should == false
|
246
|
-
p["'t'", :boolean].should == true
|
247
|
-
p["'f'", :boolean].should == false
|
248
|
-
p["'a'", :string].should == 'a'
|
249
|
-
p["'a'", :blob].should == 'a'.to_sequel_blob
|
250
|
-
p["'a'", :blob].should be_a_kind_of(Sequel::SQL::Blob)
|
251
|
-
p["''", :string].should == ''
|
252
|
-
p["'\\a''b'", :string].should == "\\a'b"
|
253
|
-
p["'NULL'", :string].should == "NULL"
|
254
|
-
p["'2009-10-29'", :date].should == Date.new(2009,10,29)
|
255
|
-
p["CURRENT_TIMESTAMP", :date].should == nil
|
256
|
-
p["today()", :date].should == nil
|
257
|
-
p["'2009-10-29T10:20:30-07:00'", :datetime].should == DateTime.parse('2009-10-29T10:20:30-07:00')
|
258
|
-
p["'2009-10-29 10:20:30'", :datetime].should == DateTime.parse('2009-10-29 10:20:30')
|
259
|
-
p["'10:20:30'", :time].should == Time.parse('10:20:30')
|
260
|
-
p["NaN", :float].should == nil
|
261
|
-
end
|
262
|
-
|
263
231
|
it "should handle converting common defaults" do
|
264
232
|
@d.meta_def(:schema) do |t, *os|
|
265
|
-
[[:c1, {:db_type=>'boolean', :default=>"false", :type=>:boolean, :allow_null=>true}],
|
233
|
+
s = [[:c1, {:db_type=>'boolean', :default=>"false", :type=>:boolean, :allow_null=>true}],
|
266
234
|
[:c2, {:db_type=>'varchar', :default=>"'blah'", :type=>:string, :allow_null=>true}],
|
267
235
|
[:c3, {:db_type=>'integer', :default=>"-1", :type=>:integer, :allow_null=>true}],
|
268
236
|
[:c4, {:db_type=>'float', :default=>"1.0", :type=>:float, :allow_null=>true}],
|
@@ -272,46 +240,12 @@ END_MIG
|
|
272
240
|
[:c8, {:db_type=>'datetime', :default=>"'2008-10-29 10:20:30'", :type=>:datetime, :allow_null=>true}],
|
273
241
|
[:c9, {:db_type=>'time', :default=>"'10:20:30'", :type=>:time, :allow_null=>true}],
|
274
242
|
[:c10, {:db_type=>'interval', :default=>"'6 weeks'", :type=>:interval, :allow_null=>true}]]
|
243
|
+
s.each{|_, c| c[:ruby_default] = column_schema_to_ruby_default(c[:default], c[:type])}
|
244
|
+
s
|
275
245
|
end
|
276
246
|
@d.dump_table_schema(:t4).gsub(/[+-]\d\d:\d\d"\)/, '")').should == "create_table(:t4) do\n TrueClass :c1, :default=>false\n String :c2, :default=>\"blah\"\n Integer :c3, :default=>-1\n Float :c4, :default=>1.0\n BigDecimal :c5, :default=>BigDecimal.new(\"0.1005E3\")\n File :c6, :default=>Sequel::SQL::Blob.new(\"blah\")\n Date :c7, :default=>Date.parse(\"2008-10-29\")\n DateTime :c8, :default=>DateTime.parse(\"2008-10-29T10:20:30\")\n Time :c9, :default=>Time.parse(\"10:20:30\"), :only_time=>true\n String :c10\nend"
|
277
247
|
@d.dump_table_schema(:t4, :same_db=>true).gsub(/[+-]\d\d:\d\d"\)/, '")').should == "create_table(:t4) do\n column :c1, \"boolean\", :default=>false\n column :c2, \"varchar\", :default=>\"blah\"\n column :c3, \"integer\", :default=>-1\n column :c4, \"float\", :default=>1.0\n column :c5, \"decimal\", :default=>BigDecimal.new(\"0.1005E3\")\n column :c6, \"blob\", :default=>Sequel::SQL::Blob.new(\"blah\")\n column :c7, \"date\", :default=>Date.parse(\"2008-10-29\")\n column :c8, \"datetime\", :default=>DateTime.parse(\"2008-10-29T10:20:30\")\n column :c9, \"time\", :default=>Time.parse(\"10:20:30\")\n column :c10, \"interval\", :default=>\"'6 weeks'\".lit\nend"
|
278
248
|
end
|
279
|
-
|
280
|
-
it "should handle converting PostgreSQL specific default formats" do
|
281
|
-
m = @d.method(:column_schema_to_ruby_default)
|
282
|
-
@d.meta_def(:database_type){:postgres}
|
283
|
-
p = lambda{|d,t| m.call(d,t,{})}
|
284
|
-
p["''::text", :string].should == ""
|
285
|
-
p["'\\a''b'::character varying", :string].should == "\\a'b"
|
286
|
-
p["'a'::bpchar", :string].should == "a"
|
287
|
-
p["(-1)", :integer].should == -1
|
288
|
-
p["(-1.0)", :float].should == -1.0
|
289
|
-
p['(-1.0)', :decimal].should == BigDecimal.new('-1.0')
|
290
|
-
p["'a'::bytea", :blob].should == 'a'.to_sequel_blob
|
291
|
-
p["'a'::bytea", :blob].should be_a_kind_of(Sequel::SQL::Blob)
|
292
|
-
p["'2009-10-29'::date", :date].should == Date.new(2009,10,29)
|
293
|
-
p["'2009-10-29 10:20:30.241343'::timestamp without time zone", :datetime].should == DateTime.parse('2009-10-29 10:20:30.241343')
|
294
|
-
p["'10:20:30'::time without time zone", :time].should == Time.parse('10:20:30')
|
295
|
-
end
|
296
|
-
|
297
|
-
it "should handle converting MySQL specific default formats" do
|
298
|
-
m = @d.method(:column_schema_to_ruby_default)
|
299
|
-
@d.meta_def(:database_type){:mysql}
|
300
|
-
p = lambda{|d,t| m.call(d,t,{})}
|
301
|
-
s = lambda{|d,t| m.call(d,t,{:same_db=>true})}
|
302
|
-
p["\\a'b", :string].should == "\\a'b"
|
303
|
-
p["a", :string].should == "a"
|
304
|
-
p["NULL", :string].should == "NULL"
|
305
|
-
p["-1", :float].should == -1.0
|
306
|
-
p['-1', :decimal].should == BigDecimal.new('-1.0')
|
307
|
-
p["2009-10-29", :date].should == Date.new(2009,10,29)
|
308
|
-
p["2009-10-29 10:20:30", :datetime].should == DateTime.parse('2009-10-29 10:20:30')
|
309
|
-
p["10:20:30", :time].should == Time.parse('10:20:30')
|
310
|
-
p["CURRENT_DATE", :date].should == nil
|
311
|
-
p["CURRENT_TIMESTAMP", :datetime].should == nil
|
312
|
-
s["CURRENT_DATE", :date].inspect.should == "\"CURRENT_DATE\".lit"
|
313
|
-
s["CURRENT_TIMESTAMP", :datetime].inspect.should == "\"CURRENT_TIMESTAMP\".lit"
|
314
|
-
end
|
315
249
|
|
316
250
|
it "should convert unknown database types to strings" do
|
317
251
|
@d.dump_table_schema(:t5).should == "create_table(:t5) do\n String :c1\nend"
|
@@ -3,6 +3,7 @@ require File.join(File.dirname(__FILE__), "spec_helper")
|
|
3
3
|
describe Sequel::Model, "#sti_key" do
|
4
4
|
before do
|
5
5
|
class ::StiTest < Sequel::Model
|
6
|
+
def kind; self[:kind]; end
|
6
7
|
def kind=(x); self[:kind] = x; end
|
7
8
|
def _refresh(x); end
|
8
9
|
plugin :single_table_inheritance, :kind
|
@@ -74,6 +75,11 @@ describe Sequel::Model, "#sti_key" do
|
|
74
75
|
MODEL_DB.sqls.should == ["INSERT INTO sti_tests (kind) VALUES ('StiTest')", "INSERT INTO sti_tests (kind) VALUES ('StiTestSub1')", "INSERT INTO sti_tests (kind) VALUES ('StiTestSub2')"]
|
75
76
|
end
|
76
77
|
|
78
|
+
it "should have the before_create hook not override an existing value" do
|
79
|
+
StiTest.create(:kind=>'StiTestSub1')
|
80
|
+
MODEL_DB.sqls.should == ["INSERT INTO sti_tests (kind) VALUES ('StiTestSub1')"]
|
81
|
+
end
|
82
|
+
|
77
83
|
it "should add a filter to model datasets inside subclasses hook to only retreive objects with the matching key" do
|
78
84
|
StiTest.dataset.sql.should == "SELECT * FROM sti_tests"
|
79
85
|
StiTestSub1.dataset.sql.should == "SELECT * FROM sti_tests WHERE (kind = 'StiTestSub1')"
|
@@ -249,7 +249,7 @@ describe "Dataset UNION, EXCEPT, and INTERSECT" do
|
|
249
249
|
|
250
250
|
specify "should give the correct results for simple UNION, EXCEPT, and INTERSECT" do
|
251
251
|
@ds1.union(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30'
|
252
|
-
|
252
|
+
if @ds1.supports_intersect_except?
|
253
253
|
@ds1.except(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'20'
|
254
254
|
@ds1.intersect(@ds2).order(:number).map{|x| x[:number].to_s}.should == %w'10'
|
255
255
|
end
|
@@ -285,7 +285,7 @@ describe "Dataset UNION, EXCEPT, and INTERSECT" do
|
|
285
285
|
|
286
286
|
@ds1.union(@ds2).union(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30 40'
|
287
287
|
@ds1.union(@ds2.union(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30 40'
|
288
|
-
|
288
|
+
if @ds1.supports_intersect_except?
|
289
289
|
@ds1.union(@ds2).except(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'20 30'
|
290
290
|
@ds1.union(@ds2.except(@ds3)).order(:number).map{|x| x[:number].to_s}.should == %w'10 20 30'
|
291
291
|
@ds1.union(@ds2).intersect(@ds3).order(:number).map{|x| x[:number].to_s}.should == %w'10 '
|
@@ -307,3 +307,85 @@ describe "Dataset UNION, EXCEPT, and INTERSECT" do
|
|
307
307
|
end
|
308
308
|
end
|
309
309
|
end
|
310
|
+
|
311
|
+
if INTEGRATION_DB.dataset.supports_cte?
|
312
|
+
describe "Common Table Expressions" do
|
313
|
+
before do
|
314
|
+
@db = INTEGRATION_DB
|
315
|
+
@db.create_table!(:i1){Integer :id; Integer :parent_id}
|
316
|
+
@ds = @db[:i1]
|
317
|
+
@ds.insert(:id=>1)
|
318
|
+
@ds.insert(:id=>2)
|
319
|
+
@ds.insert(:id=>3, :parent_id=>1)
|
320
|
+
@ds.insert(:id=>4, :parent_id=>1)
|
321
|
+
@ds.insert(:id=>5, :parent_id=>3)
|
322
|
+
@ds.insert(:id=>6, :parent_id=>5)
|
323
|
+
end
|
324
|
+
after do
|
325
|
+
@db.drop_table(:i1)
|
326
|
+
end
|
327
|
+
|
328
|
+
specify "should give correct results for WITH" do
|
329
|
+
@db[:t].with(:t, @ds.order(:id).filter(:parent_id=>nil).select(:id)).map(:id).should == [1, 2]
|
330
|
+
end
|
331
|
+
|
332
|
+
specify "should give correct results for recursive WITH" do
|
333
|
+
ds = @db[:t].select(:i___id, :pi___parent_id).with_recursive(:t, @ds.filter(:parent_id=>nil), @ds.join(:t, :i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi])
|
334
|
+
ds.all.should == [{:parent_id=>nil, :id=>1}, {:parent_id=>nil, :id=>2}, {:parent_id=>1, :id=>3}, {:parent_id=>1, :id=>4}, {:parent_id=>3, :id=>5}, {:parent_id=>5, :id=>6}]
|
335
|
+
ps = @db[:t].select(:i___id, :pi___parent_id).with_recursive(:t, @ds.filter(:parent_id=>:$n), @ds.join(:t, :i=>:parent_id).filter(:t__i=>:parent_id).select(:i1__id, :i1__parent_id), :args=>[:i, :pi]).prepare(:select, :cte_sel)
|
336
|
+
ps.call(:n=>1).should == [{:id=>3, :parent_id=>1}, {:id=>4, :parent_id=>1}, {:id=>5, :parent_id=>3}, {:id=>6, :parent_id=>5}]
|
337
|
+
ps.call(:n=>3).should == [{:id=>5, :parent_id=>3}, {:id=>6, :parent_id=>5}]
|
338
|
+
ps.call(:n=>5).should == [{:id=>6, :parent_id=>5}]
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
if INTEGRATION_DB.dataset.supports_window_functions?
|
344
|
+
describe "Window Functions" do
|
345
|
+
before do
|
346
|
+
@db = INTEGRATION_DB
|
347
|
+
@db.create_table!(:i1){Integer :id; Integer :group_id; Integer :amount}
|
348
|
+
@ds = @db[:i1].order(:id)
|
349
|
+
@ds.insert(:id=>1, :group_id=>1, :amount=>1)
|
350
|
+
@ds.insert(:id=>2, :group_id=>1, :amount=>10)
|
351
|
+
@ds.insert(:id=>3, :group_id=>1, :amount=>100)
|
352
|
+
@ds.insert(:id=>4, :group_id=>2, :amount=>1000)
|
353
|
+
@ds.insert(:id=>5, :group_id=>2, :amount=>10000)
|
354
|
+
@ds.insert(:id=>6, :group_id=>2, :amount=>100000)
|
355
|
+
end
|
356
|
+
after do
|
357
|
+
@db.drop_table(:i1)
|
358
|
+
end
|
359
|
+
|
360
|
+
specify "should give correct results for window functions" do
|
361
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id){}}.all.should ==
|
362
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
363
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id){}}.all.should ==
|
364
|
+
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
365
|
+
@ds.select(:id){sum(:over, :args=>amount, :order=>id){}}.all.should ==
|
366
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
367
|
+
@ds.select(:id){sum(:over, :args=>amount){}}.all.should ==
|
368
|
+
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
369
|
+
end
|
370
|
+
|
371
|
+
specify "should give correct results for window functions with frames" do
|
372
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:all){}}.all.should ==
|
373
|
+
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
374
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:all){}}.all.should ==
|
375
|
+
[{:sum=>111, :id=>1}, {:sum=>111, :id=>2}, {:sum=>111, :id=>3}, {:sum=>111000, :id=>4}, {:sum=>111000, :id=>5}, {:sum=>111000, :id=>6}]
|
376
|
+
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:all){}}.all.should ==
|
377
|
+
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
378
|
+
@ds.select(:id){sum(:over, :args=>amount, :frame=>:all){}}.all.should ==
|
379
|
+
[{:sum=>111111, :id=>1}, {:sum=>111111, :id=>2}, {:sum=>111111, :id=>3}, {:sum=>111111, :id=>4}, {:sum=>111111, :id=>5}, {:sum=>111111, :id=>6}]
|
380
|
+
|
381
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :order=>id, :frame=>:rows){}}.all.should ==
|
382
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
383
|
+
@ds.select(:id){sum(:over, :args=>amount, :partition=>group_id, :frame=>:rows){}}.all.should ==
|
384
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1000, :id=>4}, {:sum=>11000, :id=>5}, {:sum=>111000, :id=>6}]
|
385
|
+
@ds.select(:id){sum(:over, :args=>amount, :order=>id, :frame=>:rows){}}.all.should ==
|
386
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
387
|
+
@ds.select(:id){sum(:over, :args=>amount, :frame=>:rows){}}.all.should ==
|
388
|
+
[{:sum=>1, :id=>1}, {:sum=>11, :id=>2}, {:sum=>111, :id=>3}, {:sum=>1111, :id=>4}, {:sum=>11111, :id=>5}, {:sum=>111111, :id=>6}]
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
@@ -74,11 +74,11 @@ describe "Database schema parser" do
|
|
74
74
|
|
75
75
|
specify "should parse defaults from the schema properly" do
|
76
76
|
INTEGRATION_DB.create_table!(:items){Integer :number}
|
77
|
-
INTEGRATION_DB.schema(:items).first.last[:
|
77
|
+
INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == nil
|
78
78
|
INTEGRATION_DB.create_table!(:items){Integer :number, :default=>0}
|
79
|
-
INTEGRATION_DB.schema(:items).first.last[:
|
79
|
+
INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 0
|
80
80
|
INTEGRATION_DB.create_table!(:items){String :a, :default=>"blah"}
|
81
|
-
INTEGRATION_DB.schema(:items).first.last[:
|
81
|
+
INTEGRATION_DB.schema(:items).first.last[:ruby_default].should == 'blah'
|
82
82
|
end
|
83
83
|
|
84
84
|
specify "should parse types from the schema properly" do
|
@@ -146,9 +146,7 @@ end
|
|
146
146
|
|
147
147
|
describe "Database schema modifiers" do
|
148
148
|
before do
|
149
|
-
INTEGRATION_DB.create_table!(:items){Integer :number}
|
150
149
|
@ds = INTEGRATION_DB[:items]
|
151
|
-
@ds.insert([10])
|
152
150
|
clear_sqls
|
153
151
|
end
|
154
152
|
after do
|
@@ -156,12 +154,27 @@ describe "Database schema modifiers" do
|
|
156
154
|
end
|
157
155
|
|
158
156
|
specify "should create tables correctly" do
|
157
|
+
INTEGRATION_DB.create_table!(:items){Integer :number}
|
159
158
|
INTEGRATION_DB.table_exists?(:items).should == true
|
160
159
|
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
|
160
|
+
@ds.insert([10])
|
161
161
|
@ds.columns!.should == [:number]
|
162
162
|
end
|
163
163
|
|
164
|
+
specify "should handle foreign keys correctly when creating tables" do
|
165
|
+
INTEGRATION_DB.create_table!(:items) do
|
166
|
+
primary_key :id
|
167
|
+
foreign_key :item_id, :items
|
168
|
+
unique [:item_id, :id]
|
169
|
+
foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
|
170
|
+
end
|
171
|
+
INTEGRATION_DB.table_exists?(:items).should == true
|
172
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:id, :item_id]
|
173
|
+
@ds.columns!.should == [:id, :item_id]
|
174
|
+
end
|
175
|
+
|
164
176
|
specify "should add columns to tables correctly" do
|
177
|
+
INTEGRATION_DB.create_table!(:items){Integer :number}
|
165
178
|
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number]
|
166
179
|
@ds.columns!.should == [:number]
|
167
180
|
INTEGRATION_DB.alter_table(:items){add_column :name, :text}
|
@@ -174,6 +187,12 @@ describe "Database schema modifiers" do
|
|
174
187
|
INTEGRATION_DB.alter_table(:items){add_foreign_key :item_id, :items}
|
175
188
|
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name, :id, :item_id]
|
176
189
|
@ds.columns!.should == [:number, :name, :id, :item_id]
|
190
|
+
INTEGRATION_DB.alter_table(:items) do
|
191
|
+
add_unique_constraint [:item_id, :id]
|
192
|
+
add_foreign_key [:id, :item_id], :items, :key=>[:item_id, :id]
|
193
|
+
end
|
194
|
+
INTEGRATION_DB.schema(:items, :reload=>true).map{|x| x.first}.should == [:number, :name, :id, :item_id]
|
195
|
+
@ds.columns!.should == [:number, :name, :id, :item_id]
|
177
196
|
end
|
178
197
|
end
|
179
198
|
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'rubygems'
|
2
|
+
require 'logger'
|
2
3
|
unless Object.const_defined?('Sequel')
|
3
4
|
$:.unshift(File.join(File.dirname(__FILE__), "../../lib/"))
|
4
5
|
require 'sequel'
|
5
6
|
end
|
6
7
|
begin
|
7
|
-
require File.join(File.dirname(__FILE__), '
|
8
|
+
require File.join(File.dirname(File.dirname(__FILE__)), 'spec_config.rb') unless defined?(INTEGRATION_DB)
|
8
9
|
rescue LoadError
|
9
10
|
end
|
10
11
|
|
@@ -16,12 +17,13 @@ def clear_sqls
|
|
16
17
|
end
|
17
18
|
|
18
19
|
class Spec::Example::ExampleGroup
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def log
|
21
|
+
begin
|
22
|
+
INTEGRATION_DB.loggers << Logger.new(STDOUT)
|
23
|
+
yield
|
24
|
+
ensure
|
24
25
|
INTEGRATION_DB.loggers.clear
|
26
|
+
end
|
25
27
|
end
|
26
28
|
end
|
27
29
|
|
@@ -628,6 +628,15 @@ describe Sequel::Model, "#eager_graph" do
|
|
628
628
|
proc{GraphAlbum.eager_graph(Object.new)}.should raise_error(Sequel::Error)
|
629
629
|
end
|
630
630
|
|
631
|
+
it "should not split results and assign associations if ungraphed is called" do
|
632
|
+
ds = GraphAlbum.eager_graph(:band).ungraphed
|
633
|
+
ds.sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
634
|
+
def ds.fetch_rows(sql, &block)
|
635
|
+
yield({:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3})
|
636
|
+
end
|
637
|
+
ds.all.should == [GraphAlbum.load(:id=>1, :band_id=>2, :band_id_0=>2, :vocalist_id=>3)]
|
638
|
+
end
|
639
|
+
|
631
640
|
it "should eagerly load a single many_to_one association" do
|
632
641
|
ds = GraphAlbum.eager_graph(:band)
|
633
642
|
ds.sql.should == 'SELECT albums.id, albums.band_id, band.id AS band_id_0, band.vocalist_id FROM albums LEFT OUTER JOIN bands AS band ON (band.id = albums.band_id)'
|
data/spec/model/record_spec.rb
CHANGED
@@ -35,19 +35,19 @@ describe "Model#save server use" do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
describe "Model#save" do
|
38
|
-
|
39
|
-
before(:each) do
|
38
|
+
before do
|
40
39
|
@c = Class.new(Sequel::Model(:items)) do
|
41
40
|
columns :id, :x, :y
|
42
41
|
end
|
42
|
+
@c.dataset.meta_def(:insert){|h| super(h); 1}
|
43
43
|
MODEL_DB.reset
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should insert a record for a new model instance" do
|
47
47
|
o = @c.new(:x => 1)
|
48
48
|
o.save
|
49
|
-
|
50
|
-
|
49
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (1)",
|
50
|
+
"SELECT * FROM items WHERE (id = 1) LIMIT 1"]
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should use dataset's insert_select method if present" do
|
@@ -60,15 +60,42 @@ describe "Model#save" do
|
|
60
60
|
o.save
|
61
61
|
|
62
62
|
o.values.should == {:y=>2}
|
63
|
-
MODEL_DB.sqls.
|
63
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (y) VALUES (2)"]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should use value returned by insert as the primary key" do
|
67
|
+
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
68
|
+
o = @c.new(:x => 11)
|
69
|
+
o.save
|
70
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (11)",
|
71
|
+
"SELECT * FROM items WHERE (id = 13) LIMIT 1"]
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should work correctly for inserting a record without a primary key" do
|
75
|
+
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
76
|
+
@c.no_primary_key
|
77
|
+
o = @c.new(:x => 11)
|
78
|
+
o.save
|
79
|
+
MODEL_DB.sqls.should == ["INSERT INTO items (x) VALUES (11)"]
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should set the autoincrementing_primary_key value to the value returned by insert" do
|
83
|
+
@c.dataset.meta_def(:insert){|h| super(h); 13}
|
84
|
+
@c.unrestrict_primary_key
|
85
|
+
@c.set_primary_key [:x, :y]
|
86
|
+
o = @c.new(:x => 11)
|
87
|
+
o.meta_def(:autoincrementing_primary_key){:y}
|
88
|
+
o.save
|
89
|
+
MODEL_DB.sqls.length.should == 2
|
90
|
+
MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (11)"
|
91
|
+
MODEL_DB.sqls.last.should =~ %r{SELECT \* FROM items WHERE \(\([xy] = 1[13]\) AND \([xy] = 1[13]\)\) LIMIT 1}
|
64
92
|
end
|
65
93
|
|
66
94
|
it "should update a record for an existing model instance" do
|
67
95
|
o = @c.load(:id => 3, :x => 1)
|
68
96
|
o.save
|
69
|
-
|
70
|
-
MODEL_DB.sqls.first.should =~
|
71
|
-
/UPDATE items SET (id = 3, x = 1|x = 1, id = 3) WHERE \(id = 3\)/
|
97
|
+
MODEL_DB.sqls.length.should == 1
|
98
|
+
MODEL_DB.sqls.first.should =~ /UPDATE items SET (id = 3, x = 1|x = 1, id = 3) WHERE \(id = 3\)/
|
72
99
|
end
|
73
100
|
|
74
101
|
it "should update only the given columns if given" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-07-02 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -31,6 +31,7 @@ extra_rdoc_files:
|
|
31
31
|
- doc/sharding.rdoc
|
32
32
|
- doc/virtual_rows.rdoc
|
33
33
|
- doc/reflection.rdoc
|
34
|
+
- doc/opening_databases.rdoc
|
34
35
|
- doc/release_notes/2.10.0.txt
|
35
36
|
- doc/release_notes/2.9.0.txt
|
36
37
|
- doc/release_notes/2.8.0.txt
|
@@ -51,6 +52,7 @@ extra_rdoc_files:
|
|
51
52
|
- doc/release_notes/2.12.0.txt
|
52
53
|
- doc/release_notes/3.0.0.txt
|
53
54
|
- doc/release_notes/3.1.0.txt
|
55
|
+
- doc/release_notes/3.2.0.txt
|
54
56
|
files:
|
55
57
|
- COPYING
|
56
58
|
- CHANGELOG
|
@@ -84,8 +86,10 @@ files:
|
|
84
86
|
- doc/release_notes/2.12.0.txt
|
85
87
|
- doc/release_notes/3.0.0.txt
|
86
88
|
- doc/release_notes/3.1.0.txt
|
89
|
+
- doc/release_notes/3.2.0.txt
|
87
90
|
- doc/virtual_rows.rdoc
|
88
91
|
- doc/reflection.rdoc
|
92
|
+
- doc/opening_databases.rdoc
|
89
93
|
- spec/adapters
|
90
94
|
- spec/adapters/ado_spec.rb
|
91
95
|
- spec/adapters/informix_spec.rb
|
@@ -111,9 +115,9 @@ files:
|
|
111
115
|
- spec/core/core_sql_spec.rb
|
112
116
|
- spec/core/dataset_spec.rb
|
113
117
|
- spec/core/expression_filters_spec.rb
|
118
|
+
- spec/core/schema_spec.rb
|
114
119
|
- spec/core/object_graph_spec.rb
|
115
120
|
- spec/core/schema_generator_spec.rb
|
116
|
-
- spec/core/schema_spec.rb
|
117
121
|
- spec/core/spec_helper.rb
|
118
122
|
- spec/core/version_spec.rb
|
119
123
|
- spec/model
|
@@ -210,10 +214,7 @@ files:
|
|
210
214
|
- lib/sequel/adapters/shared/sqlite.rb
|
211
215
|
- lib/sequel/adapters/sqlite.rb
|
212
216
|
- lib/sequel/adapters/utils
|
213
|
-
- lib/sequel/adapters/utils/date_format.rb
|
214
217
|
- lib/sequel/adapters/utils/stored_procedures.rb
|
215
|
-
- lib/sequel/adapters/utils/unsupported.rb
|
216
|
-
- lib/sequel/adapters/utils/savepoint_transactions.rb
|
217
218
|
- lib/sequel/adapters/amalgalite.rb
|
218
219
|
- lib/sequel/connection_pool.rb
|
219
220
|
- lib/sequel/core.rb
|
@@ -232,6 +233,7 @@ files:
|
|
232
233
|
- lib/sequel/model.rb
|
233
234
|
- lib/sequel/exceptions.rb
|
234
235
|
- lib/sequel/metaprogramming.rb
|
236
|
+
- lib/sequel/sql.rb
|
235
237
|
- lib/sequel/model
|
236
238
|
- lib/sequel/model/associations.rb
|
237
239
|
- lib/sequel/model/base.rb
|
@@ -239,7 +241,6 @@ files:
|
|
239
241
|
- lib/sequel/model/errors.rb
|
240
242
|
- lib/sequel/model/exceptions.rb
|
241
243
|
- lib/sequel/model/inflections.rb
|
242
|
-
- lib/sequel/sql.rb
|
243
244
|
- lib/sequel/version.rb
|
244
245
|
has_rdoc: true
|
245
246
|
homepage: http://sequel.rubyforge.org
|