sequel 2.12.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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