sequel 3.5.0 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/CHANGELOG +108 -0
  2. data/README.rdoc +25 -14
  3. data/Rakefile +20 -1
  4. data/doc/advanced_associations.rdoc +61 -64
  5. data/doc/cheat_sheet.rdoc +16 -7
  6. data/doc/opening_databases.rdoc +3 -3
  7. data/doc/prepared_statements.rdoc +1 -1
  8. data/doc/reflection.rdoc +2 -1
  9. data/doc/release_notes/3.6.0.txt +366 -0
  10. data/doc/schema.rdoc +19 -14
  11. data/lib/sequel/adapters/amalgalite.rb +5 -27
  12. data/lib/sequel/adapters/jdbc.rb +13 -3
  13. data/lib/sequel/adapters/jdbc/h2.rb +17 -0
  14. data/lib/sequel/adapters/jdbc/mysql.rb +20 -7
  15. data/lib/sequel/adapters/mysql.rb +4 -3
  16. data/lib/sequel/adapters/oracle.rb +1 -1
  17. data/lib/sequel/adapters/postgres.rb +87 -28
  18. data/lib/sequel/adapters/shared/mssql.rb +47 -6
  19. data/lib/sequel/adapters/shared/mysql.rb +12 -31
  20. data/lib/sequel/adapters/shared/postgres.rb +15 -12
  21. data/lib/sequel/adapters/shared/sqlite.rb +18 -0
  22. data/lib/sequel/adapters/sqlite.rb +1 -16
  23. data/lib/sequel/connection_pool.rb +1 -1
  24. data/lib/sequel/core.rb +1 -1
  25. data/lib/sequel/database.rb +1 -1
  26. data/lib/sequel/database/schema_generator.rb +2 -0
  27. data/lib/sequel/database/schema_sql.rb +1 -1
  28. data/lib/sequel/dataset.rb +5 -179
  29. data/lib/sequel/dataset/actions.rb +123 -0
  30. data/lib/sequel/dataset/convenience.rb +18 -10
  31. data/lib/sequel/dataset/features.rb +65 -0
  32. data/lib/sequel/dataset/prepared_statements.rb +29 -23
  33. data/lib/sequel/dataset/query.rb +429 -0
  34. data/lib/sequel/dataset/sql.rb +67 -435
  35. data/lib/sequel/model/associations.rb +77 -13
  36. data/lib/sequel/model/base.rb +30 -8
  37. data/lib/sequel/model/errors.rb +4 -4
  38. data/lib/sequel/plugins/caching.rb +38 -15
  39. data/lib/sequel/plugins/force_encoding.rb +18 -7
  40. data/lib/sequel/plugins/hook_class_methods.rb +4 -0
  41. data/lib/sequel/plugins/many_through_many.rb +1 -1
  42. data/lib/sequel/plugins/nested_attributes.rb +40 -11
  43. data/lib/sequel/plugins/serialization.rb +17 -3
  44. data/lib/sequel/plugins/validation_helpers.rb +65 -18
  45. data/lib/sequel/sql.rb +23 -1
  46. data/lib/sequel/version.rb +1 -1
  47. data/spec/adapters/mssql_spec.rb +96 -10
  48. data/spec/adapters/mysql_spec.rb +19 -0
  49. data/spec/adapters/postgres_spec.rb +65 -2
  50. data/spec/adapters/sqlite_spec.rb +10 -0
  51. data/spec/core/core_sql_spec.rb +9 -0
  52. data/spec/core/database_spec.rb +8 -4
  53. data/spec/core/dataset_spec.rb +122 -29
  54. data/spec/core/expression_filters_spec.rb +17 -0
  55. data/spec/extensions/caching_spec.rb +43 -3
  56. data/spec/extensions/force_encoding_spec.rb +43 -1
  57. data/spec/extensions/nested_attributes_spec.rb +55 -2
  58. data/spec/extensions/validation_helpers_spec.rb +71 -0
  59. data/spec/integration/associations_test.rb +281 -0
  60. data/spec/integration/dataset_test.rb +383 -9
  61. data/spec/integration/eager_loader_test.rb +0 -65
  62. data/spec/integration/model_test.rb +110 -0
  63. data/spec/integration/plugin_test.rb +306 -0
  64. data/spec/integration/prepared_statement_test.rb +32 -0
  65. data/spec/integration/schema_test.rb +8 -3
  66. data/spec/integration/spec_helper.rb +1 -25
  67. data/spec/model/association_reflection_spec.rb +38 -0
  68. data/spec/model/associations_spec.rb +184 -8
  69. data/spec/model/eager_loading_spec.rb +23 -0
  70. data/spec/model/model_spec.rb +8 -0
  71. data/spec/model/record_spec.rb +84 -1
  72. metadata +9 -2
@@ -610,6 +610,29 @@ describe Sequel::Model, "#eager" do
610
610
  a.al_tracks.should == [EagerTrack.load(:id=>6, :album_id=>1)]
611
611
  a.al_genres.should == [EagerGenre.load(:id=>8)]
612
612
  end
613
+
614
+ it "should respect :uniq option when eagerly loading many_to_many associations" do
615
+ EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :uniq=>true
616
+ EagerGenre.dataset.extend(Module.new {
617
+ def fetch_rows(sql)
618
+ MODEL_DB.sqls << sql
619
+ yield({:x_foreign_key_x=>1, :id=>8})
620
+ yield({:x_foreign_key_x=>1, :id=>8})
621
+ end
622
+ })
623
+ a = EagerAlbum.eager(:al_genres).all.first
624
+ MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
625
+ a.should == EagerAlbum.load(:id => 1, :band_id => 2)
626
+ a.al_genres.should == [EagerGenre.load(:id=>8)]
627
+ end
628
+
629
+ it "should respect :distinct option when eagerly loading many_to_many associations" do
630
+ EagerAlbum.many_to_many :al_genres, :class=>'EagerGenre', :left_key=>:album_id, :right_key=>:genre_id, :join_table=>:ag, :distinct=>true
631
+ a = EagerAlbum.eager(:al_genres).all.first
632
+ MODEL_DB.sqls.should == ['SELECT * FROM albums', "SELECT DISTINCT genres.*, ag.album_id AS x_foreign_key_x FROM genres INNER JOIN ag ON ((ag.genre_id = genres.id) AND (ag.album_id IN (1)))"]
633
+ a.should == EagerAlbum.load(:id => 1, :band_id => 2)
634
+ a.al_genres.should == [EagerGenre.load(:id=>4)]
635
+ end
613
636
  end
614
637
 
615
638
  describe Sequel::Model, "#eager_graph" do
@@ -4,18 +4,21 @@ describe "Sequel::Model()" do
4
4
  before do
5
5
  @db = Sequel::Model.db
6
6
  end
7
+
7
8
  it "should return a model subclass with the given dataset if given a dataset" do
8
9
  ds = @db[:blah]
9
10
  c = Sequel::Model(ds)
10
11
  c.superclass.should == Sequel::Model
11
12
  c.dataset.should == ds
12
13
  end
14
+
13
15
  it "should return a model subclass with a dataset with the default database and given table name if given a symbol" do
14
16
  c = Sequel::Model(:blah)
15
17
  c.superclass.should == Sequel::Model
16
18
  c.db.should == @db
17
19
  c.table_name.should == :blah
18
20
  end
21
+
19
22
  it "should return a model subclass associated to the given database if given a database" do
20
23
  db = Sequel::Database.new
21
24
  c = Sequel::Model(db)
@@ -82,6 +85,11 @@ describe Sequel::Model, "dataset & schema" do
82
85
  @model.table_name.should == :foo
83
86
  end
84
87
 
88
+ it "table_name should respect table aliases" do
89
+ @model.set_dataset(:foo___x)
90
+ @model.table_name.should == :x
91
+ end
92
+
85
93
  it "set_dataset should raise an error unless given a Symbol or Dataset" do
86
94
  proc{@model.set_dataset(Object.new)}.should raise_error(Sequel::Error)
87
95
  end
@@ -112,6 +112,23 @@ describe "Model#save" do
112
112
  o.save(:y)
113
113
  o.changed_columns.should == []
114
114
  end
115
+
116
+ it "should mark all columns as not changed if this is a new record" do
117
+ o = @c.new(:x => 1, :y => nil)
118
+ o.x = 4
119
+ o.changed_columns.should == [:x]
120
+ o.save
121
+ o.changed_columns.should == []
122
+ end
123
+
124
+ it "should mark all columns as not changed if this is a new record and insert_select was used" do
125
+ @c.dataset.meta_def(:insert_select){|h| h.merge(:id=>1)}
126
+ o = @c.new(:x => 1, :y => nil)
127
+ o.x = 4
128
+ o.changed_columns.should == [:x]
129
+ o.save
130
+ o.changed_columns.should == []
131
+ end
115
132
 
116
133
  it "should store previous value of @new in @was_new and as well as the hash used for updating in @columns_updated until after hooks finish running" do
117
134
  res = nil
@@ -192,7 +209,41 @@ describe "Model#save" do
192
209
  end
193
210
  end
194
211
 
195
- describe "Model#modified?" do
212
+ describe "Model#marshallable" do
213
+ before do
214
+ class ::Album < Sequel::Model
215
+ columns :id, :x
216
+ end
217
+ Album.dataset.meta_def(:insert){|h| super(h); 1}
218
+ end
219
+ after do
220
+ Object.send(:remove_const, :Album)
221
+ end
222
+
223
+ it "should make an object marshallable" do
224
+ i = Album.new(:x=>2)
225
+ s = nil
226
+ i2 = nil
227
+ i.marshallable!
228
+ proc{s = Marshal.dump(i)}.should_not raise_error
229
+ proc{i2 = Marshal.load(s)}.should_not raise_error
230
+ i2.should == i
231
+
232
+ i.save
233
+ i.marshallable!
234
+ proc{s = Marshal.dump(i)}.should_not raise_error
235
+ proc{i2 = Marshal.load(s)}.should_not raise_error
236
+ i2.should == i
237
+
238
+ i.save
239
+ i.marshallable!
240
+ proc{s = Marshal.dump(i)}.should_not raise_error
241
+ proc{i2 = Marshal.load(s)}.should_not raise_error
242
+ i2.should == i
243
+ end
244
+ end
245
+
246
+ describe "Model#modified[!?]" do
196
247
  before do
197
248
  @c = Class.new(Sequel::Model(:items))
198
249
  @c.class_eval do
@@ -216,6 +267,21 @@ describe "Model#modified?" do
216
267
  o.modified?.should == true
217
268
  end
218
269
 
270
+ it "should be true if the object is marked modified!" do
271
+ o = @c.load(:id=>1, :x=>2)
272
+ o.modified!
273
+ o.modified?.should == true
274
+ end
275
+
276
+ it "should be false if the object is marked modified! after saving until modified! again" do
277
+ o = @c.load(:id=>1, :x=>2)
278
+ o.modified!
279
+ o.save
280
+ o.modified?.should == false
281
+ o.modified!
282
+ o.modified?.should == true
283
+ end
284
+
219
285
  it "should be false if a column value is set that is the same as the current value after typecasting" do
220
286
  o = @c.load(:id=>1, :x=>2)
221
287
  o.x = '2'
@@ -245,6 +311,15 @@ describe "Model#save_changes" do
245
311
  MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (1)"
246
312
  end
247
313
 
314
+ it "should take options passed to save" do
315
+ o = @c.new(:x => 1)
316
+ def o.valid?; false; end
317
+ proc{o.save_changes}.should raise_error(Sequel::Error)
318
+ MODEL_DB.sqls.should == []
319
+ o.save_changes(:validate=>false)
320
+ MODEL_DB.sqls.first.should == "INSERT INTO items (x) VALUES (1)"
321
+ end
322
+
248
323
  it "should do nothing if no changed columns" do
249
324
  o = @c.load(:id => 3, :x => 1, :y => nil)
250
325
  o.save_changes
@@ -295,6 +370,14 @@ describe "Model#save_changes" do
295
370
  o.save_changes
296
371
  MODEL_DB.sqls.should == ["UPDATE items SET y = 4 WHERE (id = 3)"]
297
372
  end
373
+
374
+ it "should clear changed_columns" do
375
+ o = @c.load(:id => 3, :x => 1, :y => nil)
376
+ o.x = 4
377
+ o.changed_columns.should == [:x]
378
+ o.save_changes
379
+ o.changed_columns.should == []
380
+ end
298
381
 
299
382
  it "should update columns changed in a before_update hook" do
300
383
  o = @c.load(:id => 3, :x => 1, :y => nil)
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.5.0
4
+ version: 3.6.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-10-01 00:00:00 -07:00
12
+ date: 2009-11-02 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -56,6 +56,7 @@ extra_rdoc_files:
56
56
  - doc/release_notes/3.3.0.txt
57
57
  - doc/release_notes/3.4.0.txt
58
58
  - doc/release_notes/3.5.0.txt
59
+ - doc/release_notes/3.6.0.txt
59
60
  files:
60
61
  - COPYING
61
62
  - CHANGELOG
@@ -92,6 +93,7 @@ files:
92
93
  - doc/release_notes/3.3.0.txt
93
94
  - doc/release_notes/3.4.0.txt
94
95
  - doc/release_notes/3.5.0.txt
96
+ - doc/release_notes/3.6.0.txt
95
97
  - doc/schema.rdoc
96
98
  - doc/sharding.rdoc
97
99
  - doc/virtual_rows.rdoc
@@ -159,6 +161,8 @@ files:
159
161
  - spec/integration/type_test.rb
160
162
  - spec/integration/timezone_test.rb
161
163
  - spec/integration/plugin_test.rb
164
+ - spec/integration/associations_test.rb
165
+ - spec/integration/model_test.rb
162
166
  - spec/model/association_reflection_spec.rb
163
167
  - spec/model/associations_spec.rb
164
168
  - spec/model/base_spec.rb
@@ -220,6 +224,9 @@ files:
220
224
  - lib/sequel/dataset/graph.rb
221
225
  - lib/sequel/dataset/prepared_statements.rb
222
226
  - lib/sequel/dataset/sql.rb
227
+ - lib/sequel/dataset/actions.rb
228
+ - lib/sequel/dataset/features.rb
229
+ - lib/sequel/dataset/query.rb
223
230
  - lib/sequel/exceptions.rb
224
231
  - lib/sequel/extensions/blank.rb
225
232
  - lib/sequel/extensions/inflector.rb