sequel 3.14.0 → 3.15.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.
Files changed (45) hide show
  1. data/CHANGELOG +30 -0
  2. data/README.rdoc +2 -2
  3. data/doc/cheat_sheet.rdoc +1 -1
  4. data/doc/release_notes/3.15.0.txt +78 -0
  5. data/lib/sequel/adapters/do/postgres.rb +1 -1
  6. data/lib/sequel/adapters/jdbc.rb +15 -7
  7. data/lib/sequel/adapters/jdbc/mssql.rb +22 -0
  8. data/lib/sequel/adapters/mysql.rb +2 -6
  9. data/lib/sequel/adapters/mysql2.rb +176 -0
  10. data/lib/sequel/adapters/odbc.rb +1 -1
  11. data/lib/sequel/adapters/postgres.rb +13 -0
  12. data/lib/sequel/adapters/shared/mysql.rb +9 -1
  13. data/lib/sequel/adapters/shared/postgres.rb +1 -1
  14. data/lib/sequel/adapters/shared/sqlite.rb +41 -13
  15. data/lib/sequel/core.rb +8 -0
  16. data/lib/sequel/database/connecting.rb +1 -1
  17. data/lib/sequel/dataset/actions.rb +1 -1
  18. data/lib/sequel/dataset/misc.rb +32 -0
  19. data/lib/sequel/dataset/query.rb +3 -1
  20. data/lib/sequel/extensions/named_timezones.rb +1 -2
  21. data/lib/sequel/model.rb +2 -1
  22. data/lib/sequel/model/associations.rb +3 -1
  23. data/lib/sequel/model/base.rb +44 -4
  24. data/lib/sequel/plugins/active_model.rb +5 -3
  25. data/lib/sequel/plugins/class_table_inheritance.rb +3 -3
  26. data/lib/sequel/version.rb +1 -1
  27. data/spec/adapters/mysql_spec.rb +12 -2
  28. data/spec/adapters/sqlite_spec.rb +31 -1
  29. data/spec/core/dataset_spec.rb +61 -1
  30. data/spec/core/spec_helper.rb +1 -0
  31. data/spec/extensions/active_model_spec.rb +10 -0
  32. data/spec/extensions/lazy_attributes_spec.rb +19 -11
  33. data/spec/extensions/named_timezones_spec.rb +13 -11
  34. data/spec/extensions/spec_helper.rb +1 -5
  35. data/spec/integration/associations_test.rb +23 -0
  36. data/spec/integration/dataset_test.rb +3 -3
  37. data/spec/integration/plugin_test.rb +6 -0
  38. data/spec/integration/schema_test.rb +7 -0
  39. data/spec/integration/timezone_test.rb +2 -2
  40. data/spec/integration/type_test.rb +1 -1
  41. data/spec/model/associations_spec.rb +7 -0
  42. data/spec/model/base_spec.rb +6 -6
  43. data/spec/model/model_spec.rb +38 -3
  44. data/spec/model/record_spec.rb +24 -0
  45. metadata +7 -4
@@ -9,8 +9,10 @@ INTEGRATION_DB = SQLITE_DB unless defined?(INTEGRATION_DB)
9
9
  context "An SQLite database" do
10
10
  before do
11
11
  @db = SQLITE_DB
12
+ @fk = @db.foreign_keys
12
13
  end
13
14
  after do
15
+ @db.foreign_keys = @fk
14
16
  Sequel.datetime_class = Time
15
17
  end
16
18
 
@@ -325,13 +327,41 @@ context "A SQLite database" do
325
327
  @db[:test3] << { :name => "foo", :value => 2}
326
328
  @db[:test3] << { :name => "foo", :value => 3}
327
329
  @db[:test3].filter(:id => 2).delete
328
-
330
+
329
331
  @db.drop_column :test3, :value
330
332
 
331
333
  @db['PRAGMA table_info(?)', :test3][:id][:pk].to_i.should == 1
332
334
  @db[:test3].select(:id).all.should == [{:id => 1}, {:id => 3}]
333
335
  end
334
336
 
337
+ if SQLITE_DB.foreign_keys
338
+ specify "should keep foreign keys when dropping a column" do
339
+ @db.create_table! :test do
340
+ primary_key :id
341
+ String :name
342
+ Integer :value
343
+ end
344
+ @db.create_table! :test3 do
345
+ String :name
346
+ Integer :value
347
+ foreign_key :test_id, :test, :on_delete => :set_null, :on_update => :cascade
348
+ end
349
+
350
+ @db[:test3].insert(:name => "abc", :test_id => @db[:test].insert(:name => "foo", :value => 3))
351
+ @db[:test3].insert(:name => "def", :test_id => @db[:test].insert(:name => "bar", :value => 4))
352
+
353
+ @db.drop_column :test3, :value
354
+
355
+ @db[:test].filter(:name => 'bar').delete
356
+ @db[:test3][:name => 'def'][:test_id].should be_nil
357
+
358
+ @db[:test].filter(:name => 'foo').update(:id=>100)
359
+ @db[:test3][:name => 'abc'][:test_id].should == 100
360
+
361
+ @db.drop_table :test, :test3
362
+ end
363
+ end
364
+
335
365
  specify "should support rename_column operations" do
336
366
  @db[:test2].delete
337
367
  @db.add_column :test2, :xyz, :text
@@ -113,7 +113,7 @@ context "Dataset#clone" do
113
113
  @dataset.row_proc = Proc.new{|r| r}
114
114
  @clone = @dataset.clone
115
115
 
116
- @clone.should_not === @dataset
116
+ @clone.object_id.should_not === @dataset.object_id
117
117
  @clone.class.should == @dataset.class
118
118
  @clone.opts.should == @dataset.opts
119
119
  @clone.row_proc.should == @dataset.row_proc
@@ -159,6 +159,58 @@ context "Dataset#clone" do
159
159
  end
160
160
  end
161
161
 
162
+ context "Dataset#==" do
163
+ before do
164
+ @db = MockDatabase.new
165
+ @h = {}
166
+ end
167
+
168
+ specify "should be the true for dataset with the same db, opts, and SQL" do
169
+ @db[:t].should == @db[:t]
170
+ end
171
+
172
+ specify "should be different for datasets with different dbs" do
173
+ @db[:t].should_not == MockDatabase.new[:t]
174
+ end
175
+
176
+ specify "should be different for datasets with different opts" do
177
+ @db[:t].should_not == @db[:t].clone(:blah=>1)
178
+ end
179
+
180
+ specify "should be different for datasets with different SQL" do
181
+ ds = @db[:t]
182
+ ds.quote_identifiers = true
183
+ ds.should_not == @db[:t]
184
+ end
185
+ end
186
+
187
+ context "Dataset#hash" do
188
+ before do
189
+ @db = MockDatabase.new
190
+ @h = {}
191
+ end
192
+
193
+ specify "should be the same for dataset with the same db, opts, and SQL" do
194
+ @db[:t].hash.should == @db[:t].hash
195
+ @h[@db[:t]] = 1
196
+ @h[@db[:t]].should == 1
197
+ end
198
+
199
+ specify "should be different for datasets with different dbs" do
200
+ @db[:t].hash.should_not == MockDatabase.new[:t].hash
201
+ end
202
+
203
+ specify "should be different for datasets with different opts" do
204
+ @db[:t].hash.should_not == @db[:t].clone(:blah=>1).hash
205
+ end
206
+
207
+ specify "should be different for datasets with different SQL" do
208
+ ds = @db[:t]
209
+ ds.quote_identifiers = true
210
+ ds.hash.should_not == @db[:t].hash
211
+ end
212
+ end
213
+
162
214
  context "A simple dataset" do
163
215
  before do
164
216
  @dataset = Sequel::Dataset.new(nil).from(:test)
@@ -2073,6 +2125,14 @@ context "Dataset#join_table" do
2073
2125
  @d.join(:categories, :a=>:d){|j,lj,js| :b.qualify(j) > :c.qualify(lj)}.sql.should ==
2074
2126
  'SELECT * FROM "items" INNER JOIN "categories" ON (("categories"."a" = "items"."d") AND ("categories"."b" > "items"."c"))'
2075
2127
  end
2128
+
2129
+ specify "should prefer explicit aliases over implicit" do
2130
+ @d.from(:items___i).join(:categories___c, {:category_id => :id}, {:table_alias=>:c2, :implicit_qualifier=>:i2}).sql.should ==
2131
+ 'SELECT * FROM "items" AS "i" INNER JOIN "categories" AS "c2" ON ("c2"."category_id" = "i2"."id")'
2132
+ @d.from(:items.as(:i)).join(:categories.as(:c), {:category_id => :id}, {:table_alias=>:c2, :implicit_qualifier=>:i2}).sql.should ==
2133
+ 'SELECT * FROM "items" AS "i" INNER JOIN "categories" AS "c2" ON ("c2"."category_id" = "i2"."id")'
2134
+ end
2135
+
2076
2136
 
2077
2137
  specify "should not allow insert, update, delete, or truncate" do
2078
2138
  proc{@d.join(:categories, :a=>:d).insert_sql}.should raise_error(Sequel::InvalidOperation)
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+
2
3
  unless Object.const_defined?('Sequel')
3
4
  $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), "../../lib/"))
4
5
  require 'sequel/core'
@@ -45,10 +45,17 @@ describe "ActiveModel plugin" do
45
45
  assert_equal nil, @m.to_key
46
46
  @o.id = 1
47
47
  assert_equal [1], @o.to_key
48
+ @o.id = nil
49
+ assert_equal nil, @o.to_key
50
+
48
51
  @c.set_primary_key [:id2, :id]
52
+ assert_equal nil, @o.to_key
53
+ @o.id = 1
49
54
  @o.id2 = 2
50
55
  assert_equal [2, 1], @o.to_key
51
56
  @o.destroy
57
+ assert_equal [2, 1], @o.to_key
58
+ @o.id = nil
52
59
  assert_equal nil, @o.to_key
53
60
  end
54
61
 
@@ -84,6 +91,9 @@ describe "ActiveModel plugin" do
84
91
  else
85
92
  res = ::Test::Unit::TestResult.new
86
93
  tc.suite.run(res){}
94
+ if res.failure_count > 0
95
+ puts res.instance_variable_get(:@failures)
96
+ end
87
97
  res.failure_count.should == 0
88
98
  end
89
99
  end
@@ -2,7 +2,9 @@ require File.join(File.dirname(File.expand_path(__FILE__)), "spec_helper")
2
2
 
3
3
  describe "Sequel::Plugins::LazyAttributes" do
4
4
  before do
5
- class ::LazyAttributesModel < Sequel::Model(:la)
5
+ @db = MockDatabase.new
6
+ @db.meta_def(:schema){|*a| [[:id, {:type=>:integer}], [:name,{:type=>:string}]]}
7
+ class ::LazyAttributesModel < Sequel::Model(@db[:la])
6
8
  plugin :lazy_attributes
7
9
  set_columns([:id, :name])
8
10
  meta_def(:columns){[:id, :name]}
@@ -36,7 +38,7 @@ describe "Sequel::Plugins::LazyAttributes" do
36
38
  end
37
39
  @c = ::LazyAttributesModel
38
40
  @ds = LazyAttributesModel.dataset
39
- MODEL_DB.reset
41
+ @db.reset
40
42
  end
41
43
  after do
42
44
  Object.send(:remove_const, :LazyAttributesModel)
@@ -63,13 +65,19 @@ describe "Sequel::Plugins::LazyAttributes" do
63
65
  @ds.sql.should == 'SELECT id FROM la'
64
66
  end
65
67
 
68
+ it "should still typecast correctly in lazy loaded column setters" do
69
+ m = @c.new
70
+ m.name = 1
71
+ m.name.should == '1'
72
+ end
73
+
66
74
  it "should lazily load the attribute for a single model object if there is an active identity map" do
67
75
  @c.with_identity_map do
68
76
  m = @c.first
69
77
  m.values.should == {:id=>1}
70
78
  m.name.should == '1'
71
79
  m.values.should == {:id=>1, :name=>'1'}
72
- MODEL_DB.sqls.should == ['SELECT id FROM la LIMIT 1', 'SELECT name FROM la WHERE (id = 1) LIMIT 1']
80
+ @db.sqls.should == ['SELECT id FROM la LIMIT 1', 'SELECT name FROM la WHERE (id = 1) LIMIT 1']
73
81
  end
74
82
  end
75
83
 
@@ -78,7 +86,7 @@ describe "Sequel::Plugins::LazyAttributes" do
78
86
  m.values.should == {:id=>1}
79
87
  m.name.should == '1'
80
88
  m.values.should == {:id=>1, :name=>'1'}
81
- MODEL_DB.sqls.should == ['SELECT id FROM la LIMIT 1', 'SELECT name FROM la WHERE (id = 1) LIMIT 1']
89
+ @db.sqls.should == ['SELECT id FROM la LIMIT 1', 'SELECT name FROM la WHERE (id = 1) LIMIT 1']
82
90
  end
83
91
 
84
92
  it "should not lazily load the attribute for a single model object if the value already exists" do
@@ -88,7 +96,7 @@ describe "Sequel::Plugins::LazyAttributes" do
88
96
  m[:name] = '1'
89
97
  m.name.should == '1'
90
98
  m.values.should == {:id=>1, :name=>'1'}
91
- MODEL_DB.sqls.should == ['SELECT id FROM la LIMIT 1']
99
+ @db.sqls.should == ['SELECT id FROM la LIMIT 1']
92
100
  end
93
101
  end
94
102
 
@@ -97,7 +105,7 @@ describe "Sequel::Plugins::LazyAttributes" do
97
105
  m = @c.new
98
106
  m.values.should == {}
99
107
  m.name.should == nil
100
- MODEL_DB.sqls.should == []
108
+ @db.sqls.should == []
101
109
  end
102
110
  end
103
111
 
@@ -107,7 +115,7 @@ describe "Sequel::Plugins::LazyAttributes" do
107
115
  ms.map{|m| m.values}.should == [{:id=>1}, {:id=>2}]
108
116
  ms.map{|m| m.name}.should == %w'1 2'
109
117
  ms.map{|m| m.values}.should == [{:id=>1, :name=>'1'}, {:id=>2, :name=>'2'}]
110
- MODEL_DB.sqls.should == ['SELECT id FROM la', 'SELECT id, name FROM la WHERE (id IN (1, 2))']
118
+ @db.sqls.should == ['SELECT id FROM la', 'SELECT id, name FROM la WHERE (id IN (1, 2))']
111
119
  end
112
120
  end
113
121
 
@@ -122,7 +130,7 @@ describe "Sequel::Plugins::LazyAttributes" do
122
130
  ms.map{|m| m.values}.should == [{:id=>1}, {:id=>2}]
123
131
  ms.map{|m| m.name}.should == %w'1-blah 2-blah'
124
132
  ms.map{|m| m.values}.should == [{:id=>1, :name=>'1'}, {:id=>2, :name=>'2'}]
125
- MODEL_DB.sqls.should == ['SELECT id FROM la', 'SELECT id, name FROM la WHERE (id IN (1, 2))']
133
+ @db.sqls.should == ['SELECT id FROM la', 'SELECT id, name FROM la WHERE (id IN (1, 2))']
126
134
  end
127
135
  end
128
136
 
@@ -136,9 +144,9 @@ describe "Sequel::Plugins::LazyAttributes" do
136
144
  ms.map{|m| m.values}.should == [{:id=>1, :name=>"--- 3\n"}, {:id=>2, :name=>"--- 6\n"}]
137
145
  ms.map{|m| m.deserialized_values}.should == [{:name=>3}, {:name=>6}]
138
146
  ms.map{|m| m.name}.should == [3,6]
139
- MODEL_DB.sqls.should == ['SELECT id FROM la', 'SELECT id, name FROM la WHERE (id IN (1, 2))']
147
+ @db.sqls.should == ['SELECT id FROM la', 'SELECT id, name FROM la WHERE (id IN (1, 2))']
140
148
  end
141
- MODEL_DB.reset
149
+ @db.reset
142
150
  @c.with_identity_map do
143
151
  m = @ds.first
144
152
  m.values.should == {:id=>1}
@@ -146,7 +154,7 @@ describe "Sequel::Plugins::LazyAttributes" do
146
154
  m.values.should == {:id=>1, :name=>"--- 3\n"}
147
155
  m.deserialized_values.should == {:name=>3}
148
156
  m.name.should == 3
149
- MODEL_DB.sqls.should == ["SELECT id FROM la LIMIT 1", "SELECT name FROM la WHERE (id = 1) LIMIT 1"]
157
+ @db.sqls.should == ["SELECT id FROM la LIMIT 1", "SELECT name FROM la WHERE (id = 1) LIMIT 1"]
150
158
  end
151
159
  end
152
160
  end
@@ -35,32 +35,34 @@ describe "Sequel named_timezones extension" do
35
35
  Sequel.database_timezone.should == @tz_out
36
36
  end
37
37
 
38
- it "should convert datetimes going into the database to named database_timezone" do
39
- ds = @db[:a]
40
- def ds.supports_timestamp_timezones?; true; end
41
- def ds.supports_timestamp_usecs?; false; end
42
- ds.insert([@dt, DateTime.civil(2009,6,1,3,20,30,Rational(-7, 24)), DateTime.civil(2009,6,1,6,20,30,Rational(-1, 6))])
43
- @db.sqls.should == ["INSERT INTO a VALUES ('2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400')"]
38
+ unless RUBY_VERSION == '1.8.6' && RUBY_PLATFORM =~ /win/
39
+ it "should convert datetimes going into the database to named database_timezone" do
40
+ ds = @db[:a]
41
+ def ds.supports_timestamp_timezones?; true; end
42
+ def ds.supports_timestamp_usecs?; false; end
43
+ ds.insert([@dt, DateTime.civil(2009,6,1,3,20,30,-7/24.0), DateTime.civil(2009,6,1,6,20,30,-1/6.0)])
44
+ @db.sqls.should == ["INSERT INTO a VALUES ('2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400', '2009-06-01 06:20:30-0400')"]
45
+ end
44
46
  end
45
47
 
46
48
  it "should convert datetimes coming out of the database from database_timezone to application_timezone" do
47
49
  dt = Sequel.database_to_application_timestamp('2009-06-01 06:20:30-0400')
48
50
  dt.should == @dt
49
- dt.offset.should == Rational(-7, 24)
51
+ dt.offset.should == -7/24.0
50
52
 
51
53
  dt = Sequel.database_to_application_timestamp('2009-06-01 10:20:30+0000')
52
54
  dt.should == @dt
53
- dt.offset.should == Rational(-7, 24)
55
+ dt.offset.should == -7/24.0
54
56
  end
55
57
 
56
58
  it "should assume datetimes coming out of the database that don't have an offset as coming from database_timezone" do
57
59
  dt = Sequel.database_to_application_timestamp('2009-06-01 06:20:30')
58
60
  dt.should == @dt
59
- dt.offset.should == Rational(-7, 24)
61
+ dt.offset.should == -7/24.0
60
62
 
61
63
  dt = Sequel.database_to_application_timestamp('2009-06-01 10:20:30')
62
- dt.should == @dt + Rational(1, 6)
63
- dt.offset.should == Rational(-7, 24)
64
+ dt.should == @dt + 1/6.0
65
+ dt.offset.should == -7/24.0
64
66
  end
65
67
 
66
68
  it "should work with the thread_local_timezones extension" do
@@ -63,11 +63,7 @@ class MockDatabase < Sequel::Database
63
63
  end
64
64
 
65
65
  def schema(table_name, opts)
66
- if table_name
67
- [[:id, {:primary_key=>true}]]
68
- else
69
- {table_name=>[[:id, {:primary_key=>true}]]}
70
- end
66
+ [[:id, {:primary_key=>true}]]
71
67
  end
72
68
 
73
69
  def transaction(opts={}); yield; end
@@ -157,6 +157,29 @@ describe "Sequel::Model Simple Associations" do
157
157
  [:Tag, :Album, :Artist].each{|x| Object.send(:remove_const, x)}
158
158
  end
159
159
 
160
+ specify "should handle aliased tables when eager_graphing" do
161
+ @album.update(:artist => @artist)
162
+ @album.add_tag(@tag)
163
+
164
+ Artist.set_dataset(:artists___ar)
165
+ Album.set_dataset(:albums___a)
166
+ Tag.set_dataset(:tags___t)
167
+ Artist.one_to_many :balbums, :class=>Album, :key=>:artist_id
168
+ Album.many_to_many :btags, :class=>Tag, :join_table=>:albums_tags, :right_key=>:tag_id
169
+ Album.many_to_one :bartist, :class=>Artist, :key=>:artist_id
170
+ Tag.many_to_many :balbums, :class=>Album, :join_table=>:albums_tags, :right_key=>:album_id
171
+
172
+ a = Artist.eager_graph(:balbums=>:btags).all
173
+ a.should == [@artist]
174
+ a.first.balbums.should == [@album]
175
+ a.first.balbums.first.btags.should == [@tag]
176
+
177
+ a = Tag.eager_graph(:balbums=>:bartist).all
178
+ a.should == [@tag]
179
+ a.first.balbums.should == [@album]
180
+ a.first.balbums.first.bartist.should == @artist
181
+ end
182
+
160
183
  it_should_behave_like "regular and composite key associations"
161
184
 
162
185
  specify "should have add method accept hashes and create new records" do
@@ -44,7 +44,7 @@ describe "Simple Dataset operations" do
44
44
  @ds.all.should == [{:id=>1, :number=>11}]
45
45
  end
46
46
 
47
- cspecify "should have update return the number of matched rows", [:mysql, :mysql], [:do, :mysql], [:ado] do
47
+ cspecify "should have update return the number of matched rows", [:mysql, :mysql], [:do, :mysql], [:mysql2], [:ado] do
48
48
  @ds.update(:number=>:number).should == 1
49
49
  @ds.filter(:id=>1).update(:number=>:number).should == 1
50
50
  @ds.filter(:id=>2).update(:number=>:number).should == 0
@@ -475,7 +475,7 @@ describe Sequel::SQL::Constants do
475
475
  Date.today.should == @c2[@ds.get(:d)]
476
476
  end
477
477
 
478
- cspecify "should have working CURRENT_TIME", [:do, :mysql], [:jdbc, :sqlite] do
478
+ cspecify "should have working CURRENT_TIME", [:do, :mysql], [:jdbc, :sqlite], [:mysql2] do
479
479
  @db.create_table!(:constants){Time :t, :only_time=>true}
480
480
  @ds.insert(:t=>Sequel::CURRENT_TIME)
481
481
  (Time.now - @c[@ds.get(:t)]).should be_close(0, 1)
@@ -925,7 +925,7 @@ describe "Dataset identifier methods" do
925
925
  @db.drop_table(:a)
926
926
  end
927
927
 
928
- it "#identifier_output_method should change how identifiers are output" do
928
+ cspecify "#identifier_output_method should change how identifiers are output", [:mysql2] do
929
929
  @ds.identifier_output_method = :upcase
930
930
  @ds.first.should == {:AB=>1}
931
931
  @ds.identifier_output_method = :uprev
@@ -275,6 +275,12 @@ describe "Lazy Attributes plugin" do
275
275
  Item.first.num.should == 1
276
276
  end
277
277
 
278
+ specify "should typecast lazy attribute in setter" do
279
+ i = Item.new
280
+ i.num = '1'
281
+ i.num.should == 1
282
+ end
283
+
278
284
  specify "should load lazy attribute for all items returned when accessing any item if using identity map " do
279
285
  Item.create(:name=>'K', :num=>2)
280
286
  Item.with_identity_map do
@@ -33,6 +33,13 @@ describe "Database schema parser" do
33
33
  INTEGRATION_DB.schema(:items, :reload=>true)
34
34
  end
35
35
 
36
+ specify "Model schema should include columns in the table, even if they aren't selected" do
37
+ INTEGRATION_DB.create_table!(:items){String :a; Integer :number}
38
+ m = Sequel::Model(INTEGRATION_DB[:items].select(:a))
39
+ m.columns.should == [:a]
40
+ m.db_schema[:number][:type].should == :integer
41
+ end
42
+
36
43
  specify "should raise an error when the table doesn't exist" do
37
44
  proc{INTEGRATION_DB.schema(:no_table)}.should raise_error(Sequel::Error)
38
45
  end
@@ -14,8 +14,8 @@ describe "Sequel timezone support" do
14
14
  end
15
15
 
16
16
  Sequel.datetime_class = DateTime
17
- local_dst_offset = Rational(Time.local(2010, 6).utc_offset, 60*60*24)
18
- local_std_offset = Rational(Time.local(2010, 1).utc_offset, 60*60*24)
17
+ local_dst_offset = Time.local(2010, 6).utc_offset/86400.0
18
+ local_std_offset = Time.local(2010, 1).utc_offset/86400.0
19
19
  [DateTime.now, DateTime.civil(2010,1,1,12,0,0,local_std_offset), DateTime.civil(2010,6,1,12,0,0,local_dst_offset)].each do |dt|
20
20
  @db[:t].insert(dt)
21
21
  dt2 = @db[:t].single_value
@@ -78,7 +78,7 @@ describe "Supported types" do
78
78
  ds.first[:tim].strftime('%Y%m%d%H%M%S').should == t.strftime('%Y%m%d%H%M%S')
79
79
  end
80
80
 
81
- cspecify "should support generic file type", [:do], [:odbc, :mssql] do
81
+ cspecify "should support generic file type", [:do], [:odbc, :mssql], [:mysql2] do
82
82
  ds = create_items_table_with_column(:name, File)
83
83
  ds.insert(:name => ("a\0"*300).to_sequel_blob)
84
84
  ds.all.should == [{:name=>("a\0"*300).to_sequel_blob}]
@@ -1903,6 +1903,13 @@ describe Sequel::Model, "many_to_many" do
1903
1903
  a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attribute2node ON ((attribute2node.attributeid = attributes.id) AND (attribute2node.nodeid = 1234))'
1904
1904
  end
1905
1905
 
1906
+ it "should handle an aliased join table when eager loading" do
1907
+ r = @c2.many_to_many(:attributes, :class => @c1, :join_table => :attribute2node___attributes_nodes)
1908
+
1909
+ a = @c2.eager_loading_dataset(r, @c2.dataset, [:id], nil)
1910
+ a.sql.should == 'SELECT id, attributes_nodes.node_id AS x_foreign_key_x FROM nodes'
1911
+ end
1912
+
1906
1913
  it "should support a conditions option" do
1907
1914
  @c2.many_to_many :attributes, :class => @c1, :conditions => {:a=>32}
1908
1915
  n = @c2.new(:id => 1234)