sequel 3.5.0 → 3.6.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 (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