sequel 3.1.0 → 3.2.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 +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
|