sequel 3.23.0 → 3.24.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/CHANGELOG +64 -0
  2. data/doc/association_basics.rdoc +43 -5
  3. data/doc/model_hooks.rdoc +64 -27
  4. data/doc/prepared_statements.rdoc +8 -4
  5. data/doc/reflection.rdoc +8 -2
  6. data/doc/release_notes/3.23.0.txt +1 -1
  7. data/doc/release_notes/3.24.0.txt +420 -0
  8. data/lib/sequel/adapters/db2.rb +8 -1
  9. data/lib/sequel/adapters/firebird.rb +25 -9
  10. data/lib/sequel/adapters/informix.rb +4 -19
  11. data/lib/sequel/adapters/jdbc.rb +34 -17
  12. data/lib/sequel/adapters/jdbc/h2.rb +5 -0
  13. data/lib/sequel/adapters/jdbc/informix.rb +31 -0
  14. data/lib/sequel/adapters/jdbc/jtds.rb +34 -0
  15. data/lib/sequel/adapters/jdbc/mssql.rb +0 -32
  16. data/lib/sequel/adapters/jdbc/mysql.rb +9 -0
  17. data/lib/sequel/adapters/jdbc/sqlserver.rb +46 -0
  18. data/lib/sequel/adapters/postgres.rb +30 -1
  19. data/lib/sequel/adapters/shared/access.rb +10 -0
  20. data/lib/sequel/adapters/shared/informix.rb +45 -0
  21. data/lib/sequel/adapters/shared/mssql.rb +82 -8
  22. data/lib/sequel/adapters/shared/mysql.rb +25 -7
  23. data/lib/sequel/adapters/shared/postgres.rb +39 -6
  24. data/lib/sequel/adapters/shared/sqlite.rb +57 -5
  25. data/lib/sequel/adapters/sqlite.rb +8 -3
  26. data/lib/sequel/adapters/swift/mysql.rb +9 -0
  27. data/lib/sequel/ast_transformer.rb +190 -0
  28. data/lib/sequel/core.rb +1 -1
  29. data/lib/sequel/database/misc.rb +6 -0
  30. data/lib/sequel/database/query.rb +33 -3
  31. data/lib/sequel/database/schema_methods.rb +6 -2
  32. data/lib/sequel/dataset/features.rb +6 -0
  33. data/lib/sequel/dataset/prepared_statements.rb +17 -2
  34. data/lib/sequel/dataset/query.rb +17 -0
  35. data/lib/sequel/dataset/sql.rb +2 -53
  36. data/lib/sequel/exceptions.rb +4 -0
  37. data/lib/sequel/extensions/to_dot.rb +95 -83
  38. data/lib/sequel/model.rb +5 -0
  39. data/lib/sequel/model/associations.rb +80 -14
  40. data/lib/sequel/model/base.rb +182 -55
  41. data/lib/sequel/model/exceptions.rb +3 -1
  42. data/lib/sequel/plugins/association_pks.rb +6 -4
  43. data/lib/sequel/plugins/defaults_setter.rb +58 -0
  44. data/lib/sequel/plugins/many_through_many.rb +8 -3
  45. data/lib/sequel/plugins/prepared_statements.rb +140 -0
  46. data/lib/sequel/plugins/prepared_statements_associations.rb +84 -0
  47. data/lib/sequel/plugins/prepared_statements_safe.rb +72 -0
  48. data/lib/sequel/plugins/prepared_statements_with_pk.rb +59 -0
  49. data/lib/sequel/sql.rb +8 -0
  50. data/lib/sequel/version.rb +1 -1
  51. data/spec/adapters/postgres_spec.rb +43 -18
  52. data/spec/core/connection_pool_spec.rb +56 -77
  53. data/spec/core/database_spec.rb +25 -0
  54. data/spec/core/dataset_spec.rb +127 -16
  55. data/spec/core/expression_filters_spec.rb +13 -0
  56. data/spec/core/schema_spec.rb +6 -1
  57. data/spec/extensions/association_pks_spec.rb +7 -0
  58. data/spec/extensions/defaults_setter_spec.rb +64 -0
  59. data/spec/extensions/many_through_many_spec.rb +60 -4
  60. data/spec/extensions/nested_attributes_spec.rb +1 -0
  61. data/spec/extensions/prepared_statements_associations_spec.rb +126 -0
  62. data/spec/extensions/prepared_statements_safe_spec.rb +69 -0
  63. data/spec/extensions/prepared_statements_spec.rb +72 -0
  64. data/spec/extensions/prepared_statements_with_pk_spec.rb +38 -0
  65. data/spec/extensions/to_dot_spec.rb +3 -5
  66. data/spec/integration/associations_test.rb +155 -1
  67. data/spec/integration/dataset_test.rb +8 -1
  68. data/spec/integration/plugin_test.rb +119 -0
  69. data/spec/integration/prepared_statement_test.rb +72 -1
  70. data/spec/integration/schema_test.rb +66 -8
  71. data/spec/integration/transaction_test.rb +40 -0
  72. data/spec/model/associations_spec.rb +349 -8
  73. data/spec/model/base_spec.rb +59 -0
  74. data/spec/model/hooks_spec.rb +161 -0
  75. data/spec/model/record_spec.rb +24 -0
  76. metadata +21 -4
@@ -485,3 +485,62 @@ describe Sequel::Model, ".[] optimization" do
485
485
  @c[1]
486
486
  end
487
487
  end
488
+
489
+ describe "Model datasets #with_pk" do
490
+ before do
491
+ @c = Class.new(Sequel::Model(:a))
492
+ @ds = @c.dataset
493
+ def @ds.fetch_rows(sql)
494
+ db << sql
495
+ yield(:id=>1)
496
+ end
497
+ @sqls = MODEL_DB.sqls
498
+ @sqls.clear
499
+ end
500
+
501
+ it "should return the first record where the primary key matches" do
502
+ @ds.with_pk(1).should == @c.load(:id=>1)
503
+ @sqls.should == ["SELECT * FROM a WHERE (id = 1) LIMIT 1"]
504
+ end
505
+
506
+ it "should handle existing filters" do
507
+ @ds.filter(:a=>2).with_pk(1)
508
+ @sqls.should == ["SELECT * FROM a WHERE ((a = 2) AND (id = 1)) LIMIT 1"]
509
+ end
510
+
511
+ it "should work with string values" do
512
+ @ds.with_pk("foo")
513
+ @sqls.should == ["SELECT * FROM a WHERE (id = 'foo') LIMIT 1"]
514
+ end
515
+
516
+ it "should handle an array for composite primary keys" do
517
+ @c.set_primary_key :id1, :id2
518
+ @ds.with_pk([1, 2])
519
+ @sqls.should == ["SELECT * FROM a WHERE ((id1 = 1) AND (id2 = 2)) LIMIT 1"]
520
+ end
521
+
522
+ it "should raise an error if a single primary key is given when a composite primary key should be used" do
523
+ @c.set_primary_key :id1, :id2
524
+ proc{@ds.with_pk(1)}.should raise_error(Sequel::Error)
525
+ end
526
+
527
+ it "should raise an error if a composite primary key is given when a single primary key should be used" do
528
+ proc{@ds.with_pk([1, 2])}.should raise_error(Sequel::Error)
529
+ end
530
+
531
+ it "should raise an error if the wrong number of composite keys is given" do
532
+ @c.set_primary_key :id1, :id2
533
+ proc{@ds.with_pk([1, 2, 3])}.should raise_error(Sequel::Error)
534
+ end
535
+
536
+ it "should have #[] consider an integer as a primary key lookup" do
537
+ @ds[1].should == @c.load(:id=>1)
538
+ @sqls.should == ["SELECT * FROM a WHERE (id = 1) LIMIT 1"]
539
+ end
540
+
541
+ it "should not have #[] consider a string as a primary key lookup" do
542
+ @ds['foo'].should == @c.load(:id=>1)
543
+ @sqls.should == ["SELECT * FROM a WHERE (foo) LIMIT 1"]
544
+ end
545
+
546
+ end
@@ -268,4 +268,165 @@ describe "Model#before_validation && Model#after_validation" do
268
268
  @c.load(:id => 2233).save.should == nil
269
269
  MODEL_DB.sqls.should == []
270
270
  end
271
+
272
+ specify "#valid? should return false if before_validation returns false" do
273
+ @c.send(:define_method, :before_validation){false}
274
+ @c.load(:id => 2233).valid?.should == false
275
+ end
276
+ end
277
+
278
+ describe "Model around filters" do
279
+ before do
280
+ MODEL_DB.reset
281
+
282
+ @c = Class.new(Sequel::Model(:items))
283
+ @c.class_eval do
284
+ columns :id, :x
285
+ def _save_refresh(*a) end
286
+ end
287
+ end
288
+
289
+ specify "around_create should be called around new record creation" do
290
+ @c.class_eval do
291
+ def around_create
292
+ MODEL_DB << 'ac_before'
293
+ super
294
+ MODEL_DB << 'ac_after'
295
+ end
296
+ end
297
+ @c.create(:x => 2)
298
+ MODEL_DB.sqls.should == [ 'ac_before', 'INSERT INTO items (x) VALUES (2)', 'ac_after' ]
299
+ end
300
+
301
+ specify "around_delete should be called around record destruction" do
302
+ @c.class_eval do
303
+ def around_destroy
304
+ MODEL_DB << 'ad_before'
305
+ super
306
+ MODEL_DB << 'ad_after'
307
+ end
308
+ end
309
+ @c.load(:id=>1, :x => 2).destroy
310
+ MODEL_DB.sqls.should == [ 'ad_before', 'DELETE FROM items WHERE (id = 1)', 'ad_after' ]
311
+ end
312
+
313
+ specify "around_update should be called around updating existing records" do
314
+ @c.class_eval do
315
+ def around_update
316
+ MODEL_DB << 'au_before'
317
+ super
318
+ MODEL_DB << 'au_after'
319
+ end
320
+ end
321
+ @c.load(:id=>1, :x => 2).save
322
+ MODEL_DB.sqls.should == [ 'au_before', 'UPDATE items SET x = 2 WHERE (id = 1)', 'au_after' ]
323
+ end
324
+
325
+ specify "around_update should be called around saving both new and existing records, around either after_create and after_update" do
326
+ @c.class_eval do
327
+ def around_update
328
+ MODEL_DB << 'au_before'
329
+ super
330
+ MODEL_DB << 'au_after'
331
+ end
332
+ def around_create
333
+ MODEL_DB << 'ac_before'
334
+ super
335
+ MODEL_DB << 'ac_after'
336
+ end
337
+ def around_save
338
+ MODEL_DB << 'as_before'
339
+ super
340
+ MODEL_DB << 'as_after'
341
+ end
342
+ end
343
+ @c.create(:x => 2)
344
+ MODEL_DB.sqls.should == [ 'as_before', 'ac_before', 'INSERT INTO items (x) VALUES (2)', 'ac_after', 'as_after' ]
345
+ MODEL_DB.sqls.clear
346
+ @c.load(:id=>1, :x => 2).save
347
+ MODEL_DB.sqls.should == [ 'as_before', 'au_before', 'UPDATE items SET x = 2 WHERE (id = 1)', 'au_after', 'as_after' ]
348
+ end
349
+
350
+ specify "around_validation should be called around validating records" do
351
+ @c.class_eval do
352
+ def around_validation
353
+ MODEL_DB << 'av_before'
354
+ super
355
+ MODEL_DB << 'av_after'
356
+ end
357
+ def validate
358
+ MODEL_DB << 'validate'
359
+ end
360
+ end
361
+ @c.new(:x => 2).valid?.should == true
362
+ MODEL_DB.sqls.should == [ 'av_before', 'validate', 'av_after' ]
363
+ end
364
+
365
+ specify "around_validation should be able to catch validation errors and modify them" do
366
+ @c.class_eval do
367
+ def validate
368
+ errors.add(:x, 'foo')
369
+ end
370
+ end
371
+ @c.new(:x => 2).valid?.should == false
372
+ @c.class_eval do
373
+ def around_validation
374
+ super
375
+ errors.clear
376
+ end
377
+ end
378
+ @c.new(:x => 2).valid?.should == true
379
+ end
380
+
381
+ specify "around_create that doesn't call super should raise a HookFailed" do
382
+ @c.send(:define_method, :around_create){}
383
+ proc{@c.create(:x => 2)}.should raise_error(Sequel::HookFailed)
384
+ end
385
+
386
+ specify "around_update that doesn't call super should raise a HookFailed" do
387
+ @c.send(:define_method, :around_update){}
388
+ proc{@c.load(:x => 2).save}.should raise_error(Sequel::HookFailed)
389
+ end
390
+
391
+ specify "around_save that doesn't call super should raise a HookFailed" do
392
+ @c.send(:define_method, :around_save){}
393
+ proc{@c.create(:x => 2)}.should raise_error(Sequel::HookFailed)
394
+ proc{@c.load(:x => 2).save}.should raise_error(Sequel::HookFailed)
395
+ end
396
+
397
+ specify "around_destroy that doesn't call super should raise a HookFailed" do
398
+ @c.send(:define_method, :around_destroy){}
399
+ proc{@c.load(:x => 2).destroy}.should raise_error(Sequel::HookFailed)
400
+ end
401
+
402
+ specify "around_validation that doesn't call super should raise a HookFailed" do
403
+ @c.send(:define_method, :around_validation){}
404
+ proc{@c.new.save}.should raise_error(Sequel::HookFailed)
405
+ end
406
+
407
+ specify "around_validation that doesn't call super should have valid? return false" do
408
+ @c.send(:define_method, :around_validation){}
409
+ @c.new.valid?.should == false
410
+ end
411
+
412
+ specify "around_* that doesn't call super should return nil if raise_on_save_failure is false" do
413
+ @c.raise_on_save_failure = false
414
+
415
+ o = @c.load(:id => 1)
416
+ o.meta_def(:around_save){}
417
+ o.save.should == nil
418
+
419
+ o = @c.load(:id => 1)
420
+ o.meta_def(:around_update){}
421
+ o.save.should == nil
422
+
423
+ o = @c.new
424
+ o.meta_def(:around_create){}
425
+ o.save.should == nil
426
+
427
+ o = @c.new
428
+ o.meta_def(:around_validation){}
429
+ o.save.should == nil
430
+ end
431
+
271
432
  end
@@ -52,6 +52,7 @@ describe "Model#save" do
52
52
 
53
53
  it "should use dataset's insert_select method if present" do
54
54
  ds = @c.dataset = @c.dataset.clone
55
+ def ds.supports_insert_select?() true end
55
56
  def ds.insert_select(hash)
56
57
  execute("INSERT INTO items (y) VALUES (2)")
57
58
  {:y=>2}
@@ -1167,6 +1168,29 @@ describe Sequel::Model, "#initialize" do
1167
1168
  m.values.should == {:x => 2}
1168
1169
  end
1169
1170
  end
1171
+
1172
+ describe Sequel::Model, "#initialize_set" do
1173
+ before do
1174
+ @c = Class.new(Sequel::Model){columns :id, :x, :y}
1175
+ end
1176
+
1177
+ specify "should be called by initialize to set the column values" do
1178
+ @c.send(:define_method, :initialize_set){|h| set(:y => 3)}
1179
+ @c.new(:x => 2).values.should == {:y => 3}
1180
+ end
1181
+
1182
+ specify "should be called with the hash given to initialize " do
1183
+ x = nil
1184
+ @c.send(:define_method, :initialize_set){|y| x = y}
1185
+ @c.new(:x => 2)
1186
+ x.should == {:x => 2}
1187
+ end
1188
+
1189
+ specify "should not cause columns modified by the method to be considered as changed" do
1190
+ @c.send(:define_method, :initialize_set){|h| set(:y => 3)}
1191
+ @c.new(:x => 2).changed_columns.should == []
1192
+ end
1193
+ end
1170
1194
 
1171
1195
  describe Sequel::Model, ".create" do
1172
1196
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sequel
3
3
  version: !ruby/object:Gem::Version
4
- hash: 91
4
+ hash: 103
5
5
  prerelease: false
6
6
  segments:
7
7
  - 3
8
- - 23
8
+ - 24
9
9
  - 0
10
- version: 3.23.0
10
+ version: 3.24.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeremy Evans
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-02 00:00:00 -07:00
18
+ date: 2011-06-01 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -87,6 +87,7 @@ extra_rdoc_files:
87
87
  - doc/release_notes/3.21.0.txt
88
88
  - doc/release_notes/3.22.0.txt
89
89
  - doc/release_notes/3.23.0.txt
90
+ - doc/release_notes/3.24.0.txt
90
91
  files:
91
92
  - MIT-LICENSE
92
93
  - CHANGELOG
@@ -141,6 +142,7 @@ files:
141
142
  - doc/release_notes/3.21.0.txt
142
143
  - doc/release_notes/3.22.0.txt
143
144
  - doc/release_notes/3.23.0.txt
145
+ - doc/release_notes/3.24.0.txt
144
146
  - doc/sharding.rdoc
145
147
  - doc/sql.rdoc
146
148
  - doc/virtual_rows.rdoc
@@ -221,6 +223,11 @@ files:
221
223
  - spec/extensions/to_dot_spec.rb
222
224
  - spec/extensions/association_autoreloading_spec.rb
223
225
  - spec/extensions/serialization_modification_detection_spec.rb
226
+ - spec/extensions/defaults_setter_spec.rb
227
+ - spec/extensions/prepared_statements_spec.rb
228
+ - spec/extensions/prepared_statements_safe_spec.rb
229
+ - spec/extensions/prepared_statements_with_pk_spec.rb
230
+ - spec/extensions/prepared_statements_associations_spec.rb
224
231
  - spec/extensions/columns_introspection_spec.rb
225
232
  - spec/integration/associations_test.rb
226
233
  - spec/integration/database_test.rb
@@ -310,6 +317,9 @@ files:
310
317
  - lib/sequel/adapters/jdbc/postgresql.rb
311
318
  - lib/sequel/adapters/jdbc/sqlite.rb
312
319
  - lib/sequel/adapters/jdbc/as400.rb
320
+ - lib/sequel/adapters/jdbc/informix.rb
321
+ - lib/sequel/adapters/jdbc/jtds.rb
322
+ - lib/sequel/adapters/jdbc/sqlserver.rb
313
323
  - lib/sequel/adapters/mysql.rb
314
324
  - lib/sequel/adapters/odbc.rb
315
325
  - lib/sequel/adapters/odbc/mssql.rb
@@ -323,6 +333,7 @@ files:
323
333
  - lib/sequel/adapters/shared/progress.rb
324
334
  - lib/sequel/adapters/shared/sqlite.rb
325
335
  - lib/sequel/adapters/shared/access.rb
336
+ - lib/sequel/adapters/shared/informix.rb
326
337
  - lib/sequel/adapters/sqlite.rb
327
338
  - lib/sequel/adapters/utils/stored_procedures.rb
328
339
  - lib/sequel/adapters/mysql2.rb
@@ -418,9 +429,15 @@ files:
418
429
  - lib/sequel/plugins/xml_serializer.rb
419
430
  - lib/sequel/plugins/association_autoreloading.rb
420
431
  - lib/sequel/plugins/serialization_modification_detection.rb
432
+ - lib/sequel/plugins/defaults_setter.rb
433
+ - lib/sequel/plugins/prepared_statements.rb
434
+ - lib/sequel/plugins/prepared_statements_safe.rb
435
+ - lib/sequel/plugins/prepared_statements_with_pk.rb
436
+ - lib/sequel/plugins/prepared_statements_associations.rb
421
437
  - lib/sequel/sql.rb
422
438
  - lib/sequel/timezones.rb
423
439
  - lib/sequel/version.rb
440
+ - lib/sequel/ast_transformer.rb
424
441
  - lib/sequel_core.rb
425
442
  - lib/sequel_model.rb
426
443
  has_rdoc: true