sequel 3.33.0 → 3.34.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 (152) hide show
  1. data/CHANGELOG +140 -0
  2. data/Rakefile +7 -0
  3. data/bin/sequel +22 -2
  4. data/doc/dataset_basics.rdoc +1 -1
  5. data/doc/mass_assignment.rdoc +3 -1
  6. data/doc/querying.rdoc +28 -4
  7. data/doc/reflection.rdoc +23 -3
  8. data/doc/release_notes/3.34.0.txt +671 -0
  9. data/doc/schema_modification.rdoc +18 -2
  10. data/doc/virtual_rows.rdoc +49 -0
  11. data/lib/sequel/adapters/do/mysql.rb +0 -5
  12. data/lib/sequel/adapters/ibmdb.rb +9 -4
  13. data/lib/sequel/adapters/jdbc.rb +9 -4
  14. data/lib/sequel/adapters/jdbc/h2.rb +8 -2
  15. data/lib/sequel/adapters/jdbc/mysql.rb +0 -5
  16. data/lib/sequel/adapters/jdbc/postgresql.rb +43 -0
  17. data/lib/sequel/adapters/jdbc/sqlite.rb +19 -0
  18. data/lib/sequel/adapters/mock.rb +24 -3
  19. data/lib/sequel/adapters/mysql.rb +29 -50
  20. data/lib/sequel/adapters/mysql2.rb +13 -28
  21. data/lib/sequel/adapters/oracle.rb +8 -2
  22. data/lib/sequel/adapters/postgres.rb +115 -20
  23. data/lib/sequel/adapters/shared/db2.rb +1 -1
  24. data/lib/sequel/adapters/shared/mssql.rb +14 -3
  25. data/lib/sequel/adapters/shared/mysql.rb +59 -11
  26. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
  27. data/lib/sequel/adapters/shared/oracle.rb +1 -1
  28. data/lib/sequel/adapters/shared/postgres.rb +127 -30
  29. data/lib/sequel/adapters/shared/sqlite.rb +55 -38
  30. data/lib/sequel/adapters/sqlite.rb +9 -3
  31. data/lib/sequel/adapters/swift.rb +2 -2
  32. data/lib/sequel/adapters/swift/mysql.rb +0 -5
  33. data/lib/sequel/adapters/swift/postgres.rb +10 -0
  34. data/lib/sequel/ast_transformer.rb +4 -0
  35. data/lib/sequel/connection_pool.rb +8 -0
  36. data/lib/sequel/connection_pool/sharded_single.rb +5 -0
  37. data/lib/sequel/connection_pool/sharded_threaded.rb +17 -0
  38. data/lib/sequel/connection_pool/single.rb +5 -0
  39. data/lib/sequel/connection_pool/threaded.rb +14 -0
  40. data/lib/sequel/core.rb +24 -3
  41. data/lib/sequel/database/connecting.rb +24 -14
  42. data/lib/sequel/database/dataset_defaults.rb +1 -0
  43. data/lib/sequel/database/misc.rb +16 -25
  44. data/lib/sequel/database/query.rb +20 -2
  45. data/lib/sequel/database/schema_generator.rb +2 -2
  46. data/lib/sequel/database/schema_methods.rb +120 -23
  47. data/lib/sequel/dataset/actions.rb +91 -18
  48. data/lib/sequel/dataset/features.rb +5 -0
  49. data/lib/sequel/dataset/prepared_statements.rb +6 -2
  50. data/lib/sequel/dataset/sql.rb +68 -51
  51. data/lib/sequel/extensions/_pretty_table.rb +79 -0
  52. data/lib/sequel/{core_sql.rb → extensions/core_extensions.rb} +18 -13
  53. data/lib/sequel/extensions/migration.rb +4 -0
  54. data/lib/sequel/extensions/null_dataset.rb +90 -0
  55. data/lib/sequel/extensions/pg_array.rb +460 -0
  56. data/lib/sequel/extensions/pg_array_ops.rb +220 -0
  57. data/lib/sequel/extensions/pg_auto_parameterize.rb +174 -0
  58. data/lib/sequel/extensions/pg_hstore.rb +296 -0
  59. data/lib/sequel/extensions/pg_hstore_ops.rb +259 -0
  60. data/lib/sequel/extensions/pg_statement_cache.rb +316 -0
  61. data/lib/sequel/extensions/pretty_table.rb +5 -71
  62. data/lib/sequel/extensions/query_literals.rb +79 -0
  63. data/lib/sequel/extensions/schema_caching.rb +76 -0
  64. data/lib/sequel/extensions/schema_dumper.rb +227 -31
  65. data/lib/sequel/extensions/select_remove.rb +35 -0
  66. data/lib/sequel/extensions/sql_expr.rb +4 -110
  67. data/lib/sequel/extensions/to_dot.rb +1 -1
  68. data/lib/sequel/model.rb +11 -2
  69. data/lib/sequel/model/associations.rb +35 -7
  70. data/lib/sequel/model/base.rb +159 -36
  71. data/lib/sequel/no_core_ext.rb +2 -0
  72. data/lib/sequel/plugins/caching.rb +25 -18
  73. data/lib/sequel/plugins/composition.rb +1 -1
  74. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  75. data/lib/sequel/plugins/identity_map.rb +11 -3
  76. data/lib/sequel/plugins/instance_filters.rb +10 -0
  77. data/lib/sequel/plugins/many_to_one_pk_lookup.rb +71 -0
  78. data/lib/sequel/plugins/nested_attributes.rb +4 -3
  79. data/lib/sequel/plugins/prepared_statements.rb +3 -1
  80. data/lib/sequel/plugins/prepared_statements_associations.rb +5 -1
  81. data/lib/sequel/plugins/schema.rb +7 -2
  82. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  83. data/lib/sequel/plugins/static_cache.rb +99 -0
  84. data/lib/sequel/plugins/validation_class_methods.rb +1 -1
  85. data/lib/sequel/sql.rb +417 -7
  86. data/lib/sequel/version.rb +1 -1
  87. data/spec/adapters/firebird_spec.rb +1 -1
  88. data/spec/adapters/mssql_spec.rb +12 -15
  89. data/spec/adapters/mysql_spec.rb +81 -23
  90. data/spec/adapters/postgres_spec.rb +444 -77
  91. data/spec/adapters/spec_helper.rb +2 -0
  92. data/spec/adapters/sqlite_spec.rb +8 -8
  93. data/spec/core/connection_pool_spec.rb +85 -0
  94. data/spec/core/database_spec.rb +29 -5
  95. data/spec/core/dataset_spec.rb +171 -3
  96. data/spec/core/expression_filters_spec.rb +364 -0
  97. data/spec/core/mock_adapter_spec.rb +17 -3
  98. data/spec/core/schema_spec.rb +133 -0
  99. data/spec/extensions/association_dependencies_spec.rb +13 -13
  100. data/spec/extensions/caching_spec.rb +26 -3
  101. data/spec/extensions/class_table_inheritance_spec.rb +2 -2
  102. data/spec/{core/core_sql_spec.rb → extensions/core_extensions_spec.rb} +23 -94
  103. data/spec/extensions/force_encoding_spec.rb +4 -2
  104. data/spec/extensions/hook_class_methods_spec.rb +5 -2
  105. data/spec/extensions/identity_map_spec.rb +17 -0
  106. data/spec/extensions/instance_filters_spec.rb +1 -1
  107. data/spec/extensions/lazy_attributes_spec.rb +2 -2
  108. data/spec/extensions/list_spec.rb +4 -4
  109. data/spec/extensions/many_to_one_pk_lookup_spec.rb +140 -0
  110. data/spec/extensions/migration_spec.rb +6 -2
  111. data/spec/extensions/nested_attributes_spec.rb +20 -0
  112. data/spec/extensions/null_dataset_spec.rb +85 -0
  113. data/spec/extensions/optimistic_locking_spec.rb +2 -2
  114. data/spec/extensions/pg_array_ops_spec.rb +105 -0
  115. data/spec/extensions/pg_array_spec.rb +196 -0
  116. data/spec/extensions/pg_auto_parameterize_spec.rb +64 -0
  117. data/spec/extensions/pg_hstore_ops_spec.rb +136 -0
  118. data/spec/extensions/pg_hstore_spec.rb +195 -0
  119. data/spec/extensions/pg_statement_cache_spec.rb +209 -0
  120. data/spec/extensions/prepared_statements_spec.rb +4 -0
  121. data/spec/extensions/pretty_table_spec.rb +6 -0
  122. data/spec/extensions/query_literals_spec.rb +168 -0
  123. data/spec/extensions/schema_caching_spec.rb +41 -0
  124. data/spec/extensions/schema_dumper_spec.rb +231 -11
  125. data/spec/extensions/schema_spec.rb +14 -2
  126. data/spec/extensions/select_remove_spec.rb +38 -0
  127. data/spec/extensions/sharding_spec.rb +6 -6
  128. data/spec/extensions/skip_create_refresh_spec.rb +1 -1
  129. data/spec/extensions/spec_helper.rb +2 -1
  130. data/spec/extensions/sql_expr_spec.rb +28 -19
  131. data/spec/extensions/static_cache_spec.rb +145 -0
  132. data/spec/extensions/touch_spec.rb +1 -1
  133. data/spec/extensions/typecast_on_load_spec.rb +9 -1
  134. data/spec/integration/associations_test.rb +6 -6
  135. data/spec/integration/database_test.rb +1 -1
  136. data/spec/integration/dataset_test.rb +89 -26
  137. data/spec/integration/migrator_test.rb +2 -3
  138. data/spec/integration/model_test.rb +3 -3
  139. data/spec/integration/plugin_test.rb +85 -22
  140. data/spec/integration/prepared_statement_test.rb +28 -8
  141. data/spec/integration/schema_test.rb +78 -7
  142. data/spec/integration/spec_helper.rb +1 -0
  143. data/spec/integration/timezone_test.rb +1 -1
  144. data/spec/integration/transaction_test.rb +4 -6
  145. data/spec/integration/type_test.rb +2 -2
  146. data/spec/model/associations_spec.rb +94 -8
  147. data/spec/model/base_spec.rb +4 -4
  148. data/spec/model/hooks_spec.rb +2 -2
  149. data/spec/model/model_spec.rb +19 -7
  150. data/spec/model/record_spec.rb +135 -58
  151. data/spec/model/spec_helper.rb +1 -0
  152. metadata +35 -7
@@ -407,7 +407,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
407
407
  i.set(:x => 4, :y => 5, :z => 6)
408
408
  i.values.should == {:x => 4, :y => 5}
409
409
 
410
- @c.dataset._fetch = {:x => 7}
410
+ @c.instance_dataset._fetch = @c.dataset._fetch = {:x => 7}
411
411
  i = @c.new
412
412
  i.update(:x => 7, :z => 9)
413
413
  i.values.should == {:x => 7}
@@ -421,7 +421,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
421
421
  i.set(:x => 4, :y => 5, :z => 6)
422
422
  i.values.should == {:x => 4, :y => 5}
423
423
 
424
- @c.dataset._fetch = {:x => 7}
424
+ @c.instance_dataset._fetch = @c.dataset._fetch = {:x => 7}
425
425
  i = @c.new
426
426
  i.update(:x => 7, :z => 9)
427
427
  i.values.should == {:x => 7}
@@ -436,7 +436,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
436
436
  i.set(:x => 4, :y => 5, :z => 6)
437
437
  i.values.should == {:x => 4, :y => 5}
438
438
 
439
- @c.dataset._fetch = {:y => 7}
439
+ @c.instance_dataset._fetch = @c.dataset._fetch = {:y => 7}
440
440
  i = @c.new
441
441
  i.update(:y => 7, :z => 9)
442
442
  i.values.should == {:y => 7}
@@ -610,7 +610,7 @@ describe Sequel::Model, ".[] optimization" do
610
610
 
611
611
  it "should use Dataset#with_sql if simple_table and simple_pk are true" do
612
612
  @c.set_dataset :a
613
- @c.dataset._fetch = {:id => 1}
613
+ @c.instance_dataset._fetch = @c.dataset._fetch = {:id => 1}
614
614
  @c[1].should == @c.load(:id=>1)
615
615
  @db.sqls.should == ['SELECT * FROM "a" WHERE "id" = 1']
616
616
  end
@@ -156,7 +156,7 @@ describe "Model#before_destroy && Model#after_destroy" do
156
156
  @c.send(:define_method, :before_destroy){MODEL_DB << "BLAH before"}
157
157
  m = @c.load(:id => 2233)
158
158
  m.destroy
159
- MODEL_DB.sqls.should == ['BLAH before', 'DELETE FROM items WHERE (id = 2233)', 'BLAH after']
159
+ MODEL_DB.sqls.should == ['BLAH before', 'DELETE FROM items WHERE id = 2233', 'BLAH after']
160
160
  end
161
161
 
162
162
  specify "#destroy should cancel the destroy and raise an error if before_destroy returns false and raise_on_save_failure is true" do
@@ -274,7 +274,7 @@ describe "Model around filters" do
274
274
  end
275
275
  end
276
276
  @c.load(:id=>1, :x => 2).destroy
277
- MODEL_DB.sqls.should == ['ad_before', 'DELETE FROM items WHERE (id = 1)', 'ad_after']
277
+ MODEL_DB.sqls.should == ['ad_before', 'DELETE FROM items WHERE id = 1', 'ad_after']
278
278
  end
279
279
 
280
280
  specify "around_update should be called around updating existing records" do
@@ -67,7 +67,11 @@ describe "Sequel::Model()" do
67
67
  end
68
68
 
69
69
  describe "reloading" do
70
+ before do
71
+ Sequel::Model.cache_anonymous_models = true
72
+ end
70
73
  after do
74
+ Sequel::Model.cache_anonymous_models = false
71
75
  Object.send(:remove_const, :Album) if defined?(::Album)
72
76
  end
73
77
 
@@ -126,6 +130,14 @@ describe "Sequel::Model()" do
126
130
  class ::Album < Sequel::Model(@db[:table.identifier]); end
127
131
  end.should_not raise_error
128
132
  end
133
+
134
+ it "should raise an exception if anonymous model caching is disabled" do
135
+ Sequel::Model.cache_anonymous_models = false
136
+ proc do
137
+ class ::Album < Sequel::Model(@db[:table.identifier]); end
138
+ class ::Album < Sequel::Model(@db[:table.identifier]); end
139
+ end.should raise_error
140
+ end
129
141
  end
130
142
  end
131
143
 
@@ -222,7 +234,7 @@ describe Sequel::Model, "dataset & schema" do
222
234
  MODEL_DB.sqls
223
235
  ds._fetch = [{:id=>1}, {:id=>2}]
224
236
  ds.destroy.should == 2
225
- MODEL_DB.sqls.should == ["SELECT * FROM foo", "DELETE FROM foo WHERE (id = 1)", "DELETE FROM foo WHERE (id = 2)"]
237
+ MODEL_DB.sqls.should == ["SELECT * FROM foo", "DELETE FROM foo WHERE id = 1", "DELETE FROM foo WHERE id = 2"]
226
238
  end
227
239
 
228
240
  it "set_dataset should add the destroy method that respects sharding with transactions" do
@@ -327,8 +339,8 @@ describe Sequel::Model, "new" do
327
339
  end
328
340
 
329
341
  it "should use the last inserted id as primary key if not in values" do
330
- @m.dataset._fetch = {:x => 1, :id => 1234}
331
- @m.dataset.autoid = 1234
342
+ @m.instance_dataset._fetch = @m.dataset._fetch = {:x => 1, :id => 1234}
343
+ @m.instance_dataset.autoid = @m.dataset.autoid = 1234
332
344
 
333
345
  o = @m.new(:x => 1)
334
346
  o.save
@@ -426,8 +438,8 @@ describe Sequel::Model, ".find_or_create" do
426
438
  end
427
439
 
428
440
  it "should create the record if not found" do
429
- @c.dataset._fetch = [[], {:x=>1, :id=>1}]
430
- @c.dataset.autoid = 1
441
+ @c.instance_dataset._fetch = @c.dataset._fetch = [[], {:x=>1, :id=>1}]
442
+ @c.instance_dataset.autoid = @c.dataset.autoid = 1
431
443
  @c.find_or_create(:x => 1).should == @c.load(:x=>1, :id=>1)
432
444
  MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (x = 1) LIMIT 1",
433
445
  "INSERT INTO items (x) VALUES (1)",
@@ -435,8 +447,8 @@ describe Sequel::Model, ".find_or_create" do
435
447
  end
436
448
 
437
449
  it "should pass the new record to be created to the block if no record is found" do
438
- @c.dataset._fetch = [[], {:x=>1, :id=>1}]
439
- @c.dataset.autoid = 1
450
+ @c.instance_dataset._fetch = @c.dataset._fetch = [[], {:x=>1, :id=>1}]
451
+ @c.instance_dataset.autoid = @c.dataset.autoid = 1
440
452
  @c.find_or_create(:x => 1){|x| x[:y] = 2}.should == @c.load(:x=>1, :id=>1)
441
453
  sqls = MODEL_DB.sqls
442
454
  sqls.first.should == "SELECT * FROM items WHERE (x = 1) LIMIT 1"
@@ -26,7 +26,7 @@ describe "Model#save" do
26
26
  @c = Class.new(Sequel::Model(:items)) do
27
27
  columns :id, :x, :y
28
28
  end
29
- @c.dataset.autoid = 13
29
+ @c.instance_dataset.autoid = @c.dataset.autoid = 13
30
30
  MODEL_DB.reset
31
31
  end
32
32
 
@@ -37,7 +37,7 @@ describe "Model#save" do
37
37
  end
38
38
 
39
39
  it "should use dataset's insert_select method if present" do
40
- ds = @c.dataset = @c.dataset.clone
40
+ ds = @c.instance_dataset
41
41
  ds._fetch = {:y=>2}
42
42
  def ds.supports_insert_select?() true end
43
43
  def ds.insert_select(hash)
@@ -332,6 +332,58 @@ describe "Model#set_server" do
332
332
  end
333
333
  end
334
334
 
335
+ describe "Model#freeze" do
336
+ before do
337
+ class ::Album < Sequel::Model
338
+ columns :id
339
+ class B < Sequel::Model
340
+ columns :id, :album_id
341
+ end
342
+ end
343
+ @o = Album.load(:id=>1).freeze
344
+ MODEL_DB.sqls
345
+ end
346
+ after do
347
+ Object.send(:remove_const, :Album)
348
+ end
349
+
350
+ it "should freeze the object" do
351
+ @o.frozen?.should be_true
352
+ end
353
+
354
+ it "should freeze the object's values, associations, changed_columns, errors, and this" do
355
+ @o.values.frozen?.should be_true
356
+ @o.changed_columns.frozen?.should be_true
357
+ @o.errors.frozen?.should be_true
358
+ @o.this.frozen?.should be_true
359
+ end
360
+
361
+ it "should still have working class attr overriddable methods" do
362
+ Sequel::Model::BOOLEAN_SETTINGS.each{|m| @o.send(m) == Album.send(m)}
363
+ end
364
+
365
+ it "should have working new? method" do
366
+ @o.new?.should be_false
367
+ Album.new.freeze.new?.should be_true
368
+ end
369
+
370
+ it "should have working valid? method" do
371
+ @o.valid?.should be_true
372
+ o = Album.new
373
+ def o.validate() errors.add(:foo, '') end
374
+ o.freeze
375
+ o.valid?.should be_false
376
+ end
377
+
378
+ it "should raise an Error if trying to save/destroy/delete/refresh" do
379
+ proc{@o.save}.should raise_error(Sequel::Error)
380
+ proc{@o.destroy}.should raise_error(Sequel::Error)
381
+ proc{@o.delete}.should raise_error(Sequel::Error)
382
+ proc{@o.refresh}.should raise_error(Sequel::Error)
383
+ @o.db.sqls.should == []
384
+ end
385
+ end
386
+
335
387
  describe "Model#marshallable" do
336
388
  before do
337
389
  class ::Album < Sequel::Model
@@ -642,40 +694,6 @@ describe "Model#pk" do
642
694
  end
643
695
  end
644
696
 
645
- describe "Model#pk_or_nil" do
646
- before do
647
- @m = Class.new(Sequel::Model)
648
- @m.columns :id, :x, :y
649
- end
650
-
651
- it "should be default return the value of the :id column" do
652
- m = @m.load(:id => 111, :x => 2, :y => 3)
653
- m.pk_or_nil.should == 111
654
- end
655
-
656
- it "should be return the primary key value for custom primary key" do
657
- @m.set_primary_key :x
658
- m = @m.load(:id => 111, :x => 2, :y => 3)
659
- m.pk_or_nil.should == 2
660
- end
661
-
662
- it "should be return the primary key value for composite primary key" do
663
- @m.set_primary_key [:y, :x]
664
- m = @m.load(:id => 111, :x => 2, :y => 3)
665
- m.pk_or_nil.should == [3, 2]
666
- end
667
-
668
- it "should raise if no primary key" do
669
- @m.set_primary_key nil
670
- m = @m.new(:id => 111, :x => 2, :y => 3)
671
- m.pk_or_nil.should be_nil
672
-
673
- @m.no_primary_key
674
- m = @m.new(:id => 111, :x => 2, :y => 3)
675
- m.pk_or_nil.should be_nil
676
- end
677
- end
678
-
679
697
  describe "Model#pk_hash" do
680
698
  before do
681
699
  @m = Class.new(Sequel::Model)
@@ -896,6 +914,34 @@ describe Sequel::Model, "#set_fields" do
896
914
  @o1.values.should == {:x => 9, :y => 8, :id=>7}
897
915
  MODEL_DB.sqls.should == []
898
916
  end
917
+
918
+ it "should lookup into the hash without checking if the entry exists" do
919
+ @o1.set_fields({:x => 1}, [:x, :y])
920
+ @o1.values.should == {:x => 1, :y => nil}
921
+ @o1.set_fields(Hash.new(2), [:x, :y])
922
+ @o1.values.should == {:x => 2, :y => 2}
923
+ end
924
+
925
+ it "should skip missing fields if :missing=>:skip option is used" do
926
+ @o1.set_fields({:x => 3}, [:x, :y], :missing=>:skip)
927
+ @o1.values.should == {:x => 3}
928
+ @o1.set_fields({"x" => 4}, [:x, :y], :missing=>:skip)
929
+ @o1.values.should == {:x => 4}
930
+ @o1.set_fields(Hash.new(2).merge(:x=>2), [:x, :y], :missing=>:skip)
931
+ @o1.values.should == {:x => 2}
932
+ @o1.set_fields({:x => 1, :y => 2, :z=>3, :id=>4}, [:x, :y], :missing=>:skip)
933
+ @o1.values.should == {:x => 1, :y => 2}
934
+ end
935
+
936
+ it "should raise for missing fields if :missing=>:raise option is used" do
937
+ proc{@o1.set_fields({:x => 1}, [:x, :y], :missing=>:raise)}.should raise_error(Sequel::Error)
938
+ proc{@o1.set_fields(Hash.new(2).merge(:x=>2), [:x, :y], :missing=>:raise)}.should raise_error(Sequel::Error)
939
+ proc{@o1.set_fields({"x" => 1}, [:x, :y], :missing=>:raise)}.should raise_error(Sequel::Error)
940
+ @o1.set_fields({:x => 5, "y"=>2}, [:x, :y], :missing=>:raise)
941
+ @o1.values.should == {:x => 5, :y => 2}
942
+ @o1.set_fields({:x => 1, :y => 3, :z=>3, :id=>4}, [:x, :y], :missing=>:raise)
943
+ @o1.values.should == {:x => 1, :y => 3}
944
+ end
899
945
  end
900
946
 
901
947
  describe Sequel::Model, "#update_fields" do
@@ -920,6 +966,16 @@ describe Sequel::Model, "#update_fields" do
920
966
  @o1.values.should == {:x => 1, :y => 5, :id=>1}
921
967
  MODEL_DB.sqls.should == ["UPDATE items SET y = 5 WHERE (id = 1)"]
922
968
  end
969
+
970
+ it "should support :missing=>:skip option" do
971
+ @o1.update_fields({:x => 1, :z=>3, :id=>4}, [:x, :y], :missing=>:skip)
972
+ @o1.values.should == {:x => 1, :id=>1}
973
+ MODEL_DB.sqls.should == ["UPDATE items SET x = 1 WHERE (id = 1)"]
974
+ end
975
+
976
+ it "should support :missing=>:raise option" do
977
+ proc{@o1.update_fields({:x => 1}, [:x, :y], :missing=>:raise)}.should raise_error(Sequel::Error)
978
+ end
923
979
  end
924
980
 
925
981
  describe Sequel::Model, "#(set|update)_(all|except|only)" do
@@ -998,6 +1054,35 @@ describe Sequel::Model, "#(set|update)_(all|except|only)" do
998
1054
  end
999
1055
  end
1000
1056
 
1057
+ describe Sequel::Model, "#destroy with filtered dataset" do
1058
+ before do
1059
+ @model = Class.new(Sequel::Model(MODEL_DB[:items].where(:a=>1)))
1060
+ @model.columns :id, :a
1061
+ @instance = @model.load(:id => 1234)
1062
+ MODEL_DB.reset
1063
+ end
1064
+
1065
+ it "should raise a NoExistingObject exception if the dataset delete call doesn't return 1" do
1066
+ @instance.this.meta_def(:execute_dui){|*a| 0}
1067
+ proc{@instance.delete}.should raise_error(Sequel::NoExistingObject)
1068
+ @instance.this.meta_def(:execute_dui){|*a| 2}
1069
+ proc{@instance.delete}.should raise_error(Sequel::NoExistingObject)
1070
+ @instance.this.meta_def(:execute_dui){|*a| 1}
1071
+ proc{@instance.delete}.should_not raise_error
1072
+
1073
+ @instance.require_modification = false
1074
+ @instance.this.meta_def(:execute_dui){|*a| 0}
1075
+ proc{@instance.delete}.should_not raise_error
1076
+ @instance.this.meta_def(:execute_dui){|*a| 2}
1077
+ proc{@instance.delete}.should_not raise_error
1078
+ end
1079
+
1080
+ it "should include WHERE clause when deleting" do
1081
+ @instance.destroy
1082
+ MODEL_DB.sqls.should == ["DELETE FROM items WHERE ((a = 1) AND (id = 1234))"]
1083
+ end
1084
+ end
1085
+
1001
1086
  describe Sequel::Model, "#destroy" do
1002
1087
  before do
1003
1088
  @model = Class.new(Sequel::Model(:items))
@@ -1012,56 +1097,56 @@ describe Sequel::Model, "#destroy" do
1012
1097
  end
1013
1098
 
1014
1099
  it "should raise a NoExistingObject exception if the dataset delete call doesn't return 1" do
1015
- @instance.this.meta_def(:delete){|*a| 0}
1100
+ @model.dataset.meta_def(:execute_dui){|*a| 0}
1016
1101
  proc{@instance.delete}.should raise_error(Sequel::NoExistingObject)
1017
- @instance.this.meta_def(:delete){|*a| 2}
1102
+ @model.dataset.meta_def(:execute_dui){|*a| 2}
1018
1103
  proc{@instance.delete}.should raise_error(Sequel::NoExistingObject)
1019
- @instance.this.meta_def(:delete){|*a| 1}
1104
+ @model.dataset.meta_def(:execute_dui){|*a| 1}
1020
1105
  proc{@instance.delete}.should_not raise_error
1021
1106
 
1022
1107
  @instance.require_modification = false
1023
- @instance.this.meta_def(:delete){|*a| 0}
1108
+ @model.dataset.meta_def(:execute_dui){|*a| 0}
1024
1109
  proc{@instance.delete}.should_not raise_error
1025
- @instance.this.meta_def(:delete){|*a| 2}
1110
+ @model.dataset.meta_def(:execute_dui){|*a| 2}
1026
1111
  proc{@instance.delete}.should_not raise_error
1027
1112
  end
1028
1113
 
1029
1114
  it "should run within a transaction if use_transactions is true" do
1030
1115
  @instance.use_transactions = true
1031
1116
  @instance.destroy
1032
- MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE (id = 1234)", "COMMIT"]
1117
+ MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE id = 1234", "COMMIT"]
1033
1118
  end
1034
1119
 
1035
1120
  it "should not run within a transaction if use_transactions is false" do
1036
1121
  @instance.use_transactions = false
1037
1122
  @instance.destroy
1038
- MODEL_DB.sqls.should == ["DELETE FROM items WHERE (id = 1234)"]
1123
+ MODEL_DB.sqls.should == ["DELETE FROM items WHERE id = 1234"]
1039
1124
  end
1040
1125
 
1041
1126
  it "should run within a transaction if :transaction option is true" do
1042
1127
  @instance.use_transactions = false
1043
1128
  @instance.destroy(:transaction => true)
1044
- MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE (id = 1234)", "COMMIT"]
1129
+ MODEL_DB.sqls.should == ["BEGIN", "DELETE FROM items WHERE id = 1234", "COMMIT"]
1045
1130
  end
1046
1131
 
1047
1132
  it "should not run within a transaction if :transaction option is false" do
1048
1133
  @instance.use_transactions = true
1049
1134
  @instance.destroy(:transaction => false)
1050
- MODEL_DB.sqls.should == ["DELETE FROM items WHERE (id = 1234)"]
1135
+ MODEL_DB.sqls.should == ["DELETE FROM items WHERE id = 1234"]
1051
1136
  end
1052
1137
 
1053
1138
  it "should run before_destroy and after_destroy hooks" do
1054
1139
  @model.send(:define_method, :before_destroy){MODEL_DB.execute('before blah')}
1055
1140
  @model.send(:define_method, :after_destroy){MODEL_DB.execute('after blah')}
1056
1141
  @instance.destroy
1057
- MODEL_DB.sqls.should == ["before blah", "DELETE FROM items WHERE (id = 1234)", "after blah"]
1142
+ MODEL_DB.sqls.should == ["before blah", "DELETE FROM items WHERE id = 1234", "after blah"]
1058
1143
  end
1059
1144
  end
1060
1145
 
1061
1146
  describe Sequel::Model, "#exists?" do
1062
1147
  before do
1063
1148
  @model = Class.new(Sequel::Model(:items))
1064
- @model.dataset._fetch = proc{|sql| {:x=>1} if sql =~ /id = 1/}
1149
+ @model.instance_dataset._fetch = @model.dataset._fetch = proc{|sql| {:x=>1} if sql =~ /id = 1/}
1065
1150
  MODEL_DB.reset
1066
1151
  end
1067
1152
 
@@ -1369,7 +1454,7 @@ describe Sequel::Model, "#refresh" do
1369
1454
  specify "should reload the instance values from the database" do
1370
1455
  @m = @c.new(:id => 555)
1371
1456
  @m[:x] = 'blah'
1372
- @c.dataset._fetch = {:x => 'kaboom', :id => 555}
1457
+ @c.instance_dataset._fetch = @c.dataset._fetch = {:x => 'kaboom', :id => 555}
1373
1458
  @m.refresh
1374
1459
  @m[:x].should == 'kaboom'
1375
1460
  MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
@@ -1377,26 +1462,18 @@ describe Sequel::Model, "#refresh" do
1377
1462
 
1378
1463
  specify "should raise if the instance is not found" do
1379
1464
  @m = @c.new(:id => 555)
1380
- @c.dataset._fetch = []
1465
+ @c.instance_dataset._fetch =@c.dataset._fetch = []
1381
1466
  proc {@m.refresh}.should raise_error(Sequel::Error)
1382
1467
  MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
1383
1468
  end
1384
1469
 
1385
1470
  specify "should be aliased by #reload" do
1386
1471
  @m = @c.new(:id => 555)
1387
- @c.dataset._fetch = {:x => 'kaboom', :id => 555}
1472
+ @c.instance_dataset._fetch =@c.dataset._fetch = {:x => 'kaboom', :id => 555}
1388
1473
  @m.reload
1389
1474
  @m[:x].should == 'kaboom'
1390
1475
  MODEL_DB.sqls.should == ["SELECT * FROM items WHERE (id = 555) LIMIT 1"]
1391
1476
  end
1392
-
1393
- specify "should remove cached associations" do
1394
- @c.many_to_one :node, :class=>@c
1395
- @m = @c.new(:id => 555)
1396
- @m.associations[:node] = 15
1397
- @m.reload
1398
- @m.associations.should == {}
1399
- end
1400
1477
  end
1401
1478
 
1402
1479
  describe Sequel::Model, "typecasting" do
@@ -32,6 +32,7 @@ class << Sequel::Model
32
32
  end
33
33
 
34
34
  Sequel::Model.use_transactions = false
35
+ Sequel::Model.cache_anonymous_models = false
35
36
 
36
37
  db = Sequel.mock(:fetch=>{:id => 1, :x => 1}, :numrows=>1, :autoid=>proc{|sql| 10})
37
38
  def db.schema(*) [[:id, {:primary_key=>true}]] end
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.33.0
4
+ version: 3.34.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-01 00:00:00.000000000 Z
12
+ date: 2012-04-02 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: The Database Toolkit for Ruby
15
15
  email: code@jeremyevans.net
@@ -92,6 +92,7 @@ extra_rdoc_files:
92
92
  - doc/release_notes/3.31.0.txt
93
93
  - doc/release_notes/3.32.0.txt
94
94
  - doc/release_notes/3.33.0.txt
95
+ - doc/release_notes/3.34.0.txt
95
96
  files:
96
97
  - MIT-LICENSE
97
98
  - CHANGELOG
@@ -162,6 +163,7 @@ files:
162
163
  - doc/release_notes/3.31.0.txt
163
164
  - doc/release_notes/3.32.0.txt
164
165
  - doc/release_notes/3.33.0.txt
166
+ - doc/release_notes/3.34.0.txt
165
167
  - doc/sharding.rdoc
166
168
  - doc/sql.rdoc
167
169
  - doc/validations.rdoc
@@ -180,9 +182,8 @@ files:
180
182
  - spec/adapters/sqlite_spec.rb
181
183
  - spec/adapters/db2_spec.rb
182
184
  - spec/core/connection_pool_spec.rb
183
- - spec/core/core_sql_spec.rb
184
- - spec/core/database_spec.rb
185
185
  - spec/core/dataset_spec.rb
186
+ - spec/core/database_spec.rb
186
187
  - spec/core/expression_filters_spec.rb
187
188
  - spec/core/object_graph_spec.rb
188
189
  - spec/core/schema_generator_spec.rb
@@ -223,7 +224,6 @@ files:
223
224
  - spec/extensions/tactical_eager_loading_spec.rb
224
225
  - spec/extensions/thread_local_timezones_spec.rb
225
226
  - spec/extensions/timestamps_spec.rb
226
- - spec/extensions/touch_spec.rb
227
227
  - spec/extensions/typecast_on_load_spec.rb
228
228
  - spec/extensions/validation_class_methods_spec.rb
229
229
  - spec/extensions/validation_helpers_spec.rb
@@ -236,6 +236,7 @@ files:
236
236
  - spec/extensions/update_primary_key_spec.rb
237
237
  - spec/extensions/association_pks_spec.rb
238
238
  - spec/extensions/json_serializer_spec.rb
239
+ - spec/extensions/core_extensions_spec.rb
239
240
  - spec/extensions/list_spec.rb
240
241
  - spec/extensions/tree_spec.rb
241
242
  - spec/extensions/xml_serializer_spec.rb
@@ -249,7 +250,20 @@ files:
249
250
  - spec/extensions/prepared_statements_associations_spec.rb
250
251
  - spec/extensions/dataset_associations_spec.rb
251
252
  - spec/extensions/arbitrary_servers_spec.rb
253
+ - spec/extensions/touch_spec.rb
252
254
  - spec/extensions/server_block_spec.rb
255
+ - spec/extensions/pg_auto_parameterize_spec.rb
256
+ - spec/extensions/pg_statement_cache_spec.rb
257
+ - spec/extensions/pg_array_spec.rb
258
+ - spec/extensions/pg_array_ops_spec.rb
259
+ - spec/extensions/pg_hstore_spec.rb
260
+ - spec/extensions/pg_hstore_ops_spec.rb
261
+ - spec/extensions/schema_caching_spec.rb
262
+ - spec/extensions/null_dataset_spec.rb
263
+ - spec/extensions/many_to_one_pk_lookup_spec.rb
264
+ - spec/extensions/select_remove_spec.rb
265
+ - spec/extensions/static_cache_spec.rb
266
+ - spec/extensions/query_literals_spec.rb
253
267
  - spec/extensions/columns_introspection_spec.rb
254
268
  - spec/integration/associations_test.rb
255
269
  - spec/integration/database_test.rb
@@ -386,7 +400,7 @@ files:
386
400
  - lib/sequel/connection_pool/single.rb
387
401
  - lib/sequel/connection_pool/threaded.rb
388
402
  - lib/sequel/core.rb
389
- - lib/sequel/core_sql.rb
403
+ - lib/sequel/sql.rb
390
404
  - lib/sequel/database.rb
391
405
  - lib/sequel/database/schema_generator.rb
392
406
  - lib/sequel/database/schema_methods.rb
@@ -421,7 +435,19 @@ files:
421
435
  - lib/sequel/extensions/to_dot.rb
422
436
  - lib/sequel/extensions/arbitrary_servers.rb
423
437
  - lib/sequel/extensions/server_block.rb
438
+ - lib/sequel/extensions/pg_auto_parameterize.rb
439
+ - lib/sequel/extensions/pg_statement_cache.rb
440
+ - lib/sequel/extensions/pg_array.rb
441
+ - lib/sequel/extensions/pg_array_ops.rb
442
+ - lib/sequel/extensions/pg_hstore.rb
443
+ - lib/sequel/extensions/pg_hstore_ops.rb
444
+ - lib/sequel/extensions/schema_caching.rb
445
+ - lib/sequel/extensions/null_dataset.rb
446
+ - lib/sequel/extensions/_pretty_table.rb
424
447
  - lib/sequel/extensions/columns_introspection.rb
448
+ - lib/sequel/extensions/select_remove.rb
449
+ - lib/sequel/extensions/core_extensions.rb
450
+ - lib/sequel/extensions/query_literals.rb
425
451
  - lib/sequel/metaprogramming.rb
426
452
  - lib/sequel/model.rb
427
453
  - lib/sequel/model/associations.rb
@@ -466,6 +492,7 @@ files:
466
492
  - lib/sequel/plugins/json_serializer.rb
467
493
  - lib/sequel/plugins/list.rb
468
494
  - lib/sequel/plugins/tree.rb
495
+ - lib/sequel/plugins/static_cache.rb
469
496
  - lib/sequel/plugins/xml_serializer.rb
470
497
  - lib/sequel/plugins/association_autoreloading.rb
471
498
  - lib/sequel/plugins/serialization_modification_detection.rb
@@ -475,10 +502,11 @@ files:
475
502
  - lib/sequel/plugins/prepared_statements_with_pk.rb
476
503
  - lib/sequel/plugins/prepared_statements_associations.rb
477
504
  - lib/sequel/plugins/dataset_associations.rb
478
- - lib/sequel/sql.rb
505
+ - lib/sequel/plugins/many_to_one_pk_lookup.rb
479
506
  - lib/sequel/timezones.rb
480
507
  - lib/sequel/version.rb
481
508
  - lib/sequel/ast_transformer.rb
509
+ - lib/sequel/no_core_ext.rb
482
510
  - lib/sequel_core.rb
483
511
  - lib/sequel_model.rb
484
512
  homepage: http://sequel.rubyforge.org