sequel 2.12.0 → 3.0.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 (91) hide show
  1. data/CHANGELOG +62 -0
  2. data/README.rdoc +3 -3
  3. data/Rakefile +7 -0
  4. data/doc/advanced_associations.rdoc +44 -0
  5. data/doc/release_notes/3.0.0.txt +221 -0
  6. data/lib/sequel/adapters/amalgalite.rb +208 -0
  7. data/lib/sequel/adapters/db2.rb +3 -0
  8. data/lib/sequel/adapters/dbi.rb +9 -0
  9. data/lib/sequel/adapters/do.rb +0 -4
  10. data/lib/sequel/adapters/firebird.rb +16 -18
  11. data/lib/sequel/adapters/informix.rb +5 -3
  12. data/lib/sequel/adapters/jdbc.rb +24 -20
  13. data/lib/sequel/adapters/jdbc/h2.rb +15 -4
  14. data/lib/sequel/adapters/mysql.rb +4 -8
  15. data/lib/sequel/adapters/odbc.rb +0 -4
  16. data/lib/sequel/adapters/oracle.rb +0 -4
  17. data/lib/sequel/adapters/shared/mssql.rb +16 -5
  18. data/lib/sequel/adapters/shared/mysql.rb +87 -86
  19. data/lib/sequel/adapters/shared/oracle.rb +92 -3
  20. data/lib/sequel/adapters/shared/postgres.rb +85 -29
  21. data/lib/sequel/adapters/shared/progress.rb +8 -3
  22. data/lib/sequel/adapters/shared/sqlite.rb +53 -23
  23. data/lib/sequel/adapters/sqlite.rb +4 -7
  24. data/lib/sequel/adapters/utils/unsupported.rb +3 -3
  25. data/lib/sequel/connection_pool.rb +18 -25
  26. data/lib/sequel/core.rb +2 -21
  27. data/lib/sequel/database.rb +60 -44
  28. data/lib/sequel/database/schema_generator.rb +26 -31
  29. data/lib/sequel/database/schema_methods.rb +8 -3
  30. data/lib/sequel/database/schema_sql.rb +114 -28
  31. data/lib/sequel/dataset.rb +14 -41
  32. data/lib/sequel/dataset/convenience.rb +31 -54
  33. data/lib/sequel/dataset/graph.rb +7 -13
  34. data/lib/sequel/dataset/sql.rb +43 -54
  35. data/lib/sequel/extensions/inflector.rb +0 -5
  36. data/lib/sequel/extensions/schema_dumper.rb +238 -0
  37. data/lib/sequel/metaprogramming.rb +0 -20
  38. data/lib/sequel/model.rb +1 -2
  39. data/lib/sequel/model/base.rb +18 -16
  40. data/lib/sequel/model/inflections.rb +6 -9
  41. data/lib/sequel/plugins/caching.rb +0 -6
  42. data/lib/sequel/plugins/hook_class_methods.rb +1 -1
  43. data/lib/sequel/sql.rb +2 -0
  44. data/lib/sequel/version.rb +2 -2
  45. data/spec/adapters/firebird_spec.rb +35 -8
  46. data/spec/adapters/mysql_spec.rb +173 -266
  47. data/spec/adapters/oracle_spec.rb +13 -0
  48. data/spec/adapters/postgres_spec.rb +127 -227
  49. data/spec/adapters/sqlite_spec.rb +13 -171
  50. data/spec/core/connection_pool_spec.rb +15 -4
  51. data/spec/core/core_sql_spec.rb +14 -170
  52. data/spec/core/database_spec.rb +50 -132
  53. data/spec/core/dataset_spec.rb +47 -930
  54. data/spec/core/expression_filters_spec.rb +12 -0
  55. data/spec/core/schema_generator_spec.rb +37 -45
  56. data/spec/core/schema_spec.rb +26 -16
  57. data/spec/core/spec_helper.rb +0 -25
  58. data/spec/extensions/inflector_spec.rb +0 -3
  59. data/spec/extensions/schema_dumper_spec.rb +292 -0
  60. data/spec/extensions/serialization_spec.rb +9 -0
  61. data/spec/extensions/single_table_inheritance_spec.rb +6 -1
  62. data/spec/extensions/spec_helper.rb +1 -3
  63. data/spec/extensions/validation_helpers_spec.rb +4 -4
  64. data/spec/integration/database_test.rb +18 -0
  65. data/spec/integration/dataset_test.rb +112 -1
  66. data/spec/integration/eager_loader_test.rb +70 -9
  67. data/spec/integration/prepared_statement_test.rb +2 -2
  68. data/spec/integration/schema_test.rb +76 -27
  69. data/spec/integration/spec_helper.rb +0 -14
  70. data/spec/integration/transaction_test.rb +27 -0
  71. data/spec/model/associations_spec.rb +0 -36
  72. data/spec/model/base_spec.rb +18 -123
  73. data/spec/model/hooks_spec.rb +2 -235
  74. data/spec/model/inflector_spec.rb +15 -115
  75. data/spec/model/model_spec.rb +0 -120
  76. data/spec/model/plugins_spec.rb +0 -70
  77. data/spec/model/record_spec.rb +35 -93
  78. data/spec/model/spec_helper.rb +0 -27
  79. data/spec/model/validations_spec.rb +0 -931
  80. metadata +9 -14
  81. data/lib/sequel/deprecated.rb +0 -593
  82. data/lib/sequel/deprecated_migration.rb +0 -91
  83. data/lib/sequel/model/deprecated.rb +0 -204
  84. data/lib/sequel/model/deprecated_hooks.rb +0 -103
  85. data/lib/sequel/model/deprecated_inflector.rb +0 -335
  86. data/lib/sequel/model/deprecated_validations.rb +0 -388
  87. data/spec/core/core_ext_spec.rb +0 -156
  88. data/spec/core/migration_spec.rb +0 -263
  89. data/spec/core/pretty_table_spec.rb +0 -58
  90. data/spec/model/caching_spec.rb +0 -217
  91. data/spec/model/schema_spec.rb +0 -92
@@ -11,20 +11,6 @@ end
11
11
  Sequel.virtual_row_instance_eval = true
12
12
  Sequel::Model.use_transactions = false
13
13
 
14
- module Spec::Example::ExampleGroupMethods
15
- def deprec_specify(*args, &block)
16
- specify(*args) do
17
- output = Sequel::Deprecation.output
18
- Sequel::Deprecation.output = nil
19
- begin
20
- instance_eval(&block)
21
- ensure
22
- Sequel::Deprecation.output = output
23
- end
24
- end
25
- end
26
- end
27
-
28
14
  $sqls = []
29
15
  def clear_sqls
30
16
  $sqls.clear
@@ -43,6 +43,33 @@ describe "Database transactions" do
43
43
  @d.count.should == 0
44
44
  end
45
45
 
46
+ specify "should support nested transactions" do
47
+ @db = INTEGRATION_DB
48
+ @db.transaction do
49
+ @db.transaction do
50
+ @d << {:name => 'abc', :value => 1}
51
+ end
52
+ end
53
+ @d.count.should == 1
54
+
55
+ @d.delete
56
+ proc {@db.transaction do
57
+ @d << {:name => 'abc', :value => 1}
58
+ @db.transaction do
59
+ raise Sequel::Rollback
60
+ end
61
+ end}.should_not raise_error
62
+ @d.count.should == 0
63
+
64
+ proc {@db.transaction do
65
+ @d << {:name => 'abc', :value => 1}
66
+ @db.transaction do
67
+ raise Interrupt, 'asdf'
68
+ end
69
+ end}.should raise_error(Interrupt)
70
+ @d.count.should == 0
71
+ end
72
+
46
73
  specify "should handle returning inside of the block by committing" do
47
74
  def INTEGRATION_DB.ret_commit
48
75
  transaction do
@@ -392,20 +392,6 @@ describe Sequel::Model, "many_to_one" do
392
392
  proc{c.parent = p}.should raise_error(Sequel::Error)
393
393
  end
394
394
 
395
- deprec_specify "should have belongs_to alias" do
396
- @c2.belongs_to :parent, :class => @c2
397
-
398
- d = @c2.load(:id => 1)
399
- MODEL_DB.reset
400
- d.parent_id = 234
401
- d.associations[:parent].should == nil
402
- ds = @c2.dataset
403
- def ds.fetch_rows(sql, &block); MODEL_DB.sqls << sql; yield({:id=>234}) end
404
- e = d.parent
405
- MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
406
- d.associations[:parent].should == e
407
- end
408
-
409
395
  it "should make the change to the foreign_key value inside a _association= method" do
410
396
  @c2.many_to_one :parent, :class => @c2
411
397
  @c2.private_instance_methods.collect{|x| x.to_s}.sort.should(include("_parent="))
@@ -866,19 +852,6 @@ describe Sequel::Model, "one_to_many" do
866
852
  im2.should_not(include('remove_all_attributes'))
867
853
  end
868
854
 
869
- deprec_specify "should have has_many alias" do
870
- @c2.has_many :attributes, :class => @c1
871
-
872
- n = @c2.new(:id => 1234)
873
- atts = n.attributes
874
- atts.should be_a_kind_of(Array)
875
- atts.size.should == 1
876
- atts.first.should be_a_kind_of(@c1)
877
- atts.first.values.should == {}
878
-
879
- MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
880
- end
881
-
882
855
  it "should populate the reciprocal many_to_one instance variable when loading the one_to_many association" do
883
856
  @c2.one_to_many :attributes, :class => @c1, :key => :node_id
884
857
  @c1.many_to_one :node, :class => @c2, :key => :node_id
@@ -1532,15 +1505,6 @@ describe Sequel::Model, "many_to_many" do
1532
1505
  im2.should_not(include('remove_all_attributes'))
1533
1506
  end
1534
1507
 
1535
- deprec_specify "should have has_and_belongs_to_many alias" do
1536
- @c2.has_and_belongs_to_many :attributes, :class => @c1
1537
-
1538
- n = @c2.new(:id => 1234)
1539
- a = n.attributes_dataset
1540
- a.should be_a_kind_of(Sequel::Dataset)
1541
- a.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234))'
1542
- end
1543
-
1544
1508
  it "should have an remove_all_ method that removes all associations" do
1545
1509
  @c2.many_to_many :attributes, :class => @c1
1546
1510
  @c2.new(:id => 1234).remove_all_attributes
@@ -6,135 +6,35 @@ describe "Model attribute setters" do
6
6
  MODEL_DB.reset
7
7
 
8
8
  @c = Class.new(Sequel::Model(:items)) do
9
- columns :id, :x, :y
9
+ columns :id, :x, :y, :"x y"
10
10
  end
11
+ @o = @c.new
11
12
  end
12
13
 
13
14
  it "should mark the column value as changed" do
14
- o = @c.new
15
- o.changed_columns.should == []
15
+ @o.changed_columns.should == []
16
16
 
17
- o.x = 2
18
- o.changed_columns.should == [:x]
17
+ @o.x = 2
18
+ @o.changed_columns.should == [:x]
19
19
 
20
- o.y = 3
21
- o.changed_columns.should == [:x, :y]
20
+ @o.y = 3
21
+ @o.changed_columns.should == [:x, :y]
22
22
 
23
- o.changed_columns.clear
23
+ @o.changed_columns.clear
24
24
 
25
- o[:x] = 2
26
- o.changed_columns.should == [:x]
25
+ @o[:x] = 2
26
+ @o.changed_columns.should == [:x]
27
27
 
28
- o[:y] = 3
29
- o.changed_columns.should == [:x, :y]
28
+ @o[:y] = 3
29
+ @o.changed_columns.should == [:x, :y]
30
30
  end
31
31
 
32
- end
33
-
34
- describe "Model#serialize" do
35
-
36
- before(:each) do
37
- MODEL_DB.reset
38
- end
39
-
40
- deprec_specify "should translate values to YAML when creating records" do
41
- @c = Class.new(Sequel::Model(:items)) do
42
- no_primary_key
43
- serialize :abc
44
- columns :abc
45
- end
46
-
47
- @c.create(:abc => 1)
48
- @c.create(:abc => "hello")
49
-
50
- MODEL_DB.sqls.should == [ \
51
- "INSERT INTO items (abc) VALUES ('--- 1\n')", \
52
- "INSERT INTO items (abc) VALUES ('--- hello\n')", \
53
- ]
54
- end
55
-
56
- deprec_specify "should support calling after the class is defined" do
57
- @c = Class.new(Sequel::Model(:items)) do
58
- no_primary_key
59
- columns :def
60
- end
61
-
62
- @c.serialize :def
63
-
64
- @c.create(:def => 1)
65
- @c.create(:def => "hello")
66
-
67
- MODEL_DB.sqls.should == [ \
68
- "INSERT INTO items (def) VALUES ('--- 1\n')", \
69
- "INSERT INTO items (def) VALUES ('--- hello\n')", \
70
- ]
71
- end
72
-
73
- deprec_specify "should support using the Marshal format" do
74
- @c = Class.new(Sequel::Model(:items)) do
75
- no_primary_key
76
- serialize :abc, :format => :marshal
77
- columns :abc
78
- end
79
-
80
- @c.create(:abc => 1)
81
- @c.create(:abc => "hello")
82
- x = [Marshal.dump("hello")].pack('m')
83
-
84
- MODEL_DB.sqls.should == [ \
85
- "INSERT INTO items (abc) VALUES ('BAhpBg==\n')", \
86
- "INSERT INTO items (abc) VALUES ('#{x}')", \
87
- ]
32
+ it "should have columns that can't be called like normal ruby methods" do
33
+ @o.send(:"x y=", 3)
34
+ @o.changed_columns.should == [:"x y"]
35
+ @o.values.should == {:"x y"=>3}
36
+ @o.send(:"x y").should == 3
88
37
  end
89
-
90
- deprec_specify "should translate values to and from YAML using accessor methods" do
91
- @c = Class.new(Sequel::Model(:items)) do
92
- serialize :abc, :def
93
- columns :abc, :def
94
- end
95
-
96
- ds = @c.dataset
97
- ds.extend(Module.new {
98
- attr_accessor :raw
99
-
100
- def fetch_rows(sql, &block)
101
- block.call(@raw)
102
- end
103
-
104
- @@sqls = nil
105
-
106
- def insert(*args)
107
- @@sqls = insert_sql(*args)
108
- end
109
-
110
- def update(*args)
111
- @@sqls = update_sql(*args)
112
- end
113
-
114
- def sqls
115
- @@sqls
116
- end
117
-
118
- def columns
119
- [:id, :abc, :def]
120
- end
121
- }
122
- )
123
-
124
- ds.raw = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
125
- o = @c.first
126
- o.id.should == 1
127
- o.abc.should == 1
128
- o.def.should == "hello"
129
-
130
- o.update(:abc => 23)
131
- ds.sqls.should == "UPDATE items SET abc = '#{23.to_yaml}' WHERE (id = 1)"
132
-
133
- ds.raw = {:id => 1, :abc => "--- 1\n", :def => "--- hello\n"}
134
- o = @c.create(:abc => [1, 2, 3])
135
- ds.sqls.should == "INSERT INTO items (abc) VALUES ('#{[1, 2, 3].to_yaml}')"
136
- end
137
-
138
38
  end
139
39
 
140
40
  describe Sequel::Model, "dataset" do
@@ -289,7 +189,7 @@ describe Sequel::Model, ".(allowed|restricted)_columns " do
289
189
  before do
290
190
  @c = Class.new(Sequel::Model(:blahblah)) do
291
191
  columns :x, :y, :z
292
- def refresh
192
+ def _refresh(ds)
293
193
  self
294
194
  end
295
195
  end
@@ -475,11 +375,6 @@ describe Sequel::Model, ".[] optimization" do
475
375
  Class.new(@c).simple_table.should == "'b'"
476
376
  end
477
377
 
478
- specify "should have simple_table = nil if inheriting and sti_key is set" do
479
- @c.plugin :single_table_inheritance, :x
480
- Class.new(@c).simple_table.should == nil
481
- end
482
-
483
378
  it "should use Dataset#with_sql if simple_table and simple_pk are true" do
484
379
  @c.set_dataset :a
485
380
  @c.dataset.should_receive(:with_sql).and_return(@c.dataset)
@@ -1,173 +1,5 @@
1
1
  require File.join(File.dirname(__FILE__), "spec_helper")
2
2
 
3
- describe "Model hooks" do
4
- before do
5
- MODEL_DB.reset
6
- end
7
-
8
- deprec_specify "should be definable using a block" do
9
- $adds = []
10
- c = Class.new(Sequel::Model)
11
- c.class_eval do
12
- before_save {$adds << 'hi'}
13
- end
14
-
15
- c.new.before_save
16
- $adds.should == ['hi']
17
- end
18
-
19
- deprec_specify "should be definable using a method name" do
20
- $adds = []
21
- c = Class.new(Sequel::Model)
22
- c.class_eval do
23
- def bye; $adds << 'bye'; end
24
- before_save :bye
25
- end
26
-
27
- c.new.before_save
28
- $adds.should == ['bye']
29
- end
30
-
31
- deprec_specify "should be additive" do
32
- $adds = []
33
- c = Class.new(Sequel::Model)
34
- c.class_eval do
35
- after_save {$adds << 'hyiyie'}
36
- after_save {$adds << 'byiyie'}
37
- end
38
-
39
- c.new.after_save
40
- $adds.should == ['hyiyie', 'byiyie']
41
- end
42
-
43
- deprec_specify "before hooks should run in reverse order" do
44
- $adds = []
45
- c = Class.new(Sequel::Model)
46
- c.class_eval do
47
- before_save {$adds << 'hyiyie'}
48
- before_save {$adds << 'byiyie'}
49
- end
50
-
51
- c.new.before_save
52
- $adds.should == ['byiyie', 'hyiyie']
53
- end
54
-
55
- deprec_specify "should not be additive if the method or tag already exists" do
56
- $adds = []
57
- c = Class.new(Sequel::Model)
58
- c.class_eval do
59
- def bye; $adds << 'bye'; end
60
- before_save :bye
61
- before_save :bye
62
- end
63
-
64
- c.new.before_save
65
- $adds.should == ['bye']
66
-
67
- $adds = []
68
- d = Class.new(Sequel::Model)
69
- d.class_eval do
70
- before_save(:bye){$adds << 'hyiyie'}
71
- before_save(:bye){$adds << 'byiyie'}
72
- end
73
-
74
- d.new.before_save
75
- $adds.should == ['byiyie']
76
-
77
- $adds = []
78
- e = Class.new(Sequel::Model)
79
- e.class_eval do
80
- def bye; $adds << 'bye'; end
81
- before_save :bye
82
- before_save(:bye){$adds << 'byiyie'}
83
- end
84
-
85
- e.new.before_save
86
- $adds.should == ['byiyie']
87
-
88
- $adds = []
89
- e = Class.new(Sequel::Model)
90
- e.class_eval do
91
- def bye; $adds << 'bye'; end
92
- before_save(:bye){$adds << 'byiyie'}
93
- before_save :bye
94
- end
95
-
96
- e.new.before_save
97
- $adds.should == ['bye']
98
- end
99
-
100
- deprec_specify "should be inheritable" do
101
- $adds = []
102
- a = Class.new(Sequel::Model)
103
- a.class_eval do
104
- after_save {$adds << '123'}
105
- end
106
-
107
- b = Class.new(a)
108
- b.class_eval do
109
- after_save {$adds << '456'}
110
- after_save {$adds << '789'}
111
- end
112
-
113
- b.new.after_save
114
- $adds.should == ['123', '456', '789']
115
- end
116
-
117
- deprec_specify "should be overridable in descendant classes" do
118
- $adds = []
119
- a = Class.new(Sequel::Model)
120
- a.class_eval do
121
- before_save {$adds << '123'}
122
- end
123
-
124
- b = Class.new(a)
125
- b.class_eval do
126
- def before_save; $adds << '456'; end
127
- end
128
-
129
- a.new.before_save
130
- $adds.should == ['123']
131
- $adds = []
132
- b.new.before_save
133
- $adds.should == ['456']
134
- end
135
-
136
- deprec_specify "should stop processing if a hook returns false" do
137
- $flag = true
138
- $adds = []
139
-
140
- a = Class.new(Sequel::Model)
141
- a.class_eval do
142
- after_save {$adds << 'blah'; $flag}
143
- after_save {$adds << 'cruel'}
144
- end
145
-
146
- a.new.after_save
147
- $adds.should == ['blah', 'cruel']
148
-
149
- # chain should not break on nil
150
- $adds = []
151
- $flag = nil
152
- a.new.after_save
153
- $adds.should == ['blah', 'cruel']
154
-
155
- $adds = []
156
- $flag = false
157
- a.new.after_save
158
- $adds.should == ['blah']
159
-
160
- b = Class.new(a)
161
- b.class_eval do
162
- after_save {$adds << 'mau'}
163
- end
164
-
165
- $adds = []
166
- b.new.after_save
167
- $adds.should == ['blah']
168
- end
169
- end
170
-
171
3
  describe "Model#after_initialize" do
172
4
  specify "should be called after initialization" do
173
5
  $values1 = nil
@@ -359,8 +191,8 @@ describe "Model#before_validation && Model#after_validation" do
359
191
  @c.class_eval do
360
192
  def after_validation; MODEL_DB << "BLAH after" end
361
193
 
362
- def self.validate(o)
363
- o.errors[:id] << 'not valid' unless o[:id] == 2233
194
+ def validate
195
+ errors.add(:id, 'not valid') unless id == 2233
364
196
  end
365
197
  columns :id
366
198
  end
@@ -405,68 +237,3 @@ describe "Model#before_validation && Model#after_validation" do
405
237
  MODEL_DB.sqls.should == []
406
238
  end
407
239
  end
408
-
409
- describe "Model.has_hooks?" do
410
- before do
411
- @c = Class.new(Sequel::Model(:items))
412
- end
413
-
414
- deprec_specify "should return false if no hooks are defined" do
415
- @c.has_hooks?(:before_save).should be_false
416
- end
417
-
418
- deprec_specify "should return true if hooks are defined" do
419
- @c.before_save {'blah'}
420
- @c.has_hooks?(:before_save).should be_true
421
- end
422
-
423
- deprec_specify "should return true if hooks are inherited" do
424
- @d = Class.new(@c)
425
- @d.has_hooks?(:before_save).should be_false
426
- end
427
- end
428
-
429
- describe "Model#add_hook_type" do
430
- before do
431
- deprec do
432
- class Foo < Sequel::Model(:items)
433
- add_hook_type :before_bar, :after_bar
434
-
435
- def bar
436
- return :b if before_bar == false
437
- return :a if after_bar == false
438
- true
439
- end
440
- end
441
- end
442
- @f = Class.new(Foo)
443
- end
444
-
445
- deprec_specify "should have before_bar and after_bar class methods" do
446
- @f.should respond_to(:before_bar)
447
- @f.should respond_to(:before_bar)
448
- end
449
-
450
- deprec_specify "should have before_bar and after_bar instance methods" do
451
- @f.new.should respond_to(:before_bar)
452
- @f.new.should respond_to(:before_bar)
453
- end
454
-
455
- deprec_specify "it should return true for bar when before_bar and after_bar hooks are returing true" do
456
- a = 1
457
- @f.before_bar { a += 1}
458
- @f.new.bar.should be_true
459
- a.should == 2
460
- @f.after_bar { a *= 2}
461
- @f.new.bar.should be_true
462
- a.should == 6
463
- end
464
-
465
- deprec_specify "it should return nil for bar when before_bar and after_bar hooks are returing false" do
466
- @f.new.bar.should be_true
467
- @f.after_bar { false }
468
- @f.new.bar.should == :a
469
- @f.before_bar { false }
470
- @f.new.bar.should == :b
471
- end
472
- end