sequel 3.28.0 → 3.29.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. data/CHANGELOG +119 -3
  2. data/Rakefile +5 -3
  3. data/bin/sequel +1 -5
  4. data/doc/model_hooks.rdoc +9 -1
  5. data/doc/opening_databases.rdoc +49 -40
  6. data/doc/prepared_statements.rdoc +27 -6
  7. data/doc/release_notes/3.28.0.txt +2 -2
  8. data/doc/release_notes/3.29.0.txt +459 -0
  9. data/doc/sharding.rdoc +7 -1
  10. data/doc/testing.rdoc +18 -9
  11. data/doc/transactions.rdoc +41 -1
  12. data/lib/sequel/adapters/ado.rb +28 -17
  13. data/lib/sequel/adapters/ado/mssql.rb +18 -6
  14. data/lib/sequel/adapters/amalgalite.rb +11 -7
  15. data/lib/sequel/adapters/db2.rb +122 -70
  16. data/lib/sequel/adapters/dbi.rb +15 -15
  17. data/lib/sequel/adapters/do.rb +5 -36
  18. data/lib/sequel/adapters/do/mysql.rb +0 -5
  19. data/lib/sequel/adapters/do/postgres.rb +0 -5
  20. data/lib/sequel/adapters/do/sqlite.rb +0 -5
  21. data/lib/sequel/adapters/firebird.rb +3 -6
  22. data/lib/sequel/adapters/ibmdb.rb +24 -16
  23. data/lib/sequel/adapters/informix.rb +2 -4
  24. data/lib/sequel/adapters/jdbc.rb +47 -11
  25. data/lib/sequel/adapters/jdbc/as400.rb +5 -24
  26. data/lib/sequel/adapters/jdbc/db2.rb +0 -5
  27. data/lib/sequel/adapters/jdbc/derby.rb +217 -0
  28. data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
  29. data/lib/sequel/adapters/jdbc/h2.rb +10 -12
  30. data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
  31. data/lib/sequel/adapters/jdbc/informix.rb +0 -5
  32. data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
  33. data/lib/sequel/adapters/jdbc/mysql.rb +0 -10
  34. data/lib/sequel/adapters/jdbc/oracle.rb +70 -3
  35. data/lib/sequel/adapters/jdbc/postgresql.rb +0 -11
  36. data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
  37. data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
  38. data/lib/sequel/adapters/jdbc/transactions.rb +56 -7
  39. data/lib/sequel/adapters/mock.rb +315 -0
  40. data/lib/sequel/adapters/mysql.rb +64 -51
  41. data/lib/sequel/adapters/mysql2.rb +15 -9
  42. data/lib/sequel/adapters/odbc.rb +13 -6
  43. data/lib/sequel/adapters/odbc/db2.rb +0 -4
  44. data/lib/sequel/adapters/odbc/mssql.rb +0 -5
  45. data/lib/sequel/adapters/openbase.rb +2 -4
  46. data/lib/sequel/adapters/oracle.rb +333 -51
  47. data/lib/sequel/adapters/postgres.rb +80 -27
  48. data/lib/sequel/adapters/shared/access.rb +0 -6
  49. data/lib/sequel/adapters/shared/db2.rb +13 -15
  50. data/lib/sequel/adapters/shared/firebird.rb +6 -6
  51. data/lib/sequel/adapters/shared/mssql.rb +23 -18
  52. data/lib/sequel/adapters/shared/mysql.rb +6 -6
  53. data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
  54. data/lib/sequel/adapters/shared/oracle.rb +185 -30
  55. data/lib/sequel/adapters/shared/postgres.rb +35 -18
  56. data/lib/sequel/adapters/shared/progress.rb +0 -6
  57. data/lib/sequel/adapters/shared/sqlite.rb +116 -37
  58. data/lib/sequel/adapters/sqlite.rb +16 -8
  59. data/lib/sequel/adapters/swift.rb +5 -5
  60. data/lib/sequel/adapters/swift/mysql.rb +0 -5
  61. data/lib/sequel/adapters/swift/postgres.rb +0 -5
  62. data/lib/sequel/adapters/swift/sqlite.rb +6 -4
  63. data/lib/sequel/adapters/tinytds.rb +13 -10
  64. data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -0
  65. data/lib/sequel/core.rb +40 -0
  66. data/lib/sequel/database/connecting.rb +1 -2
  67. data/lib/sequel/database/dataset.rb +3 -3
  68. data/lib/sequel/database/dataset_defaults.rb +58 -0
  69. data/lib/sequel/database/misc.rb +62 -2
  70. data/lib/sequel/database/query.rb +113 -49
  71. data/lib/sequel/database/schema_methods.rb +7 -2
  72. data/lib/sequel/dataset/actions.rb +37 -19
  73. data/lib/sequel/dataset/features.rb +24 -0
  74. data/lib/sequel/dataset/graph.rb +7 -6
  75. data/lib/sequel/dataset/misc.rb +11 -3
  76. data/lib/sequel/dataset/mutation.rb +2 -3
  77. data/lib/sequel/dataset/prepared_statements.rb +6 -4
  78. data/lib/sequel/dataset/query.rb +46 -15
  79. data/lib/sequel/dataset/sql.rb +28 -4
  80. data/lib/sequel/extensions/named_timezones.rb +5 -0
  81. data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
  82. data/lib/sequel/model.rb +2 -1
  83. data/lib/sequel/model/associations.rb +115 -33
  84. data/lib/sequel/model/base.rb +91 -31
  85. data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
  86. data/lib/sequel/plugins/dataset_associations.rb +100 -0
  87. data/lib/sequel/plugins/force_encoding.rb +6 -6
  88. data/lib/sequel/plugins/identity_map.rb +1 -1
  89. data/lib/sequel/plugins/many_through_many.rb +6 -10
  90. data/lib/sequel/plugins/prepared_statements.rb +12 -1
  91. data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
  92. data/lib/sequel/plugins/rcte_tree.rb +29 -15
  93. data/lib/sequel/plugins/serialization.rb +6 -1
  94. data/lib/sequel/plugins/sharding.rb +0 -5
  95. data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
  96. data/lib/sequel/plugins/typecast_on_load.rb +9 -12
  97. data/lib/sequel/plugins/update_primary_key.rb +1 -1
  98. data/lib/sequel/timezones.rb +42 -42
  99. data/lib/sequel/version.rb +1 -1
  100. data/spec/adapters/mssql_spec.rb +29 -29
  101. data/spec/adapters/mysql_spec.rb +86 -104
  102. data/spec/adapters/oracle_spec.rb +48 -76
  103. data/spec/adapters/postgres_spec.rb +98 -33
  104. data/spec/adapters/spec_helper.rb +0 -5
  105. data/spec/adapters/sqlite_spec.rb +24 -21
  106. data/spec/core/connection_pool_spec.rb +9 -15
  107. data/spec/core/core_sql_spec.rb +20 -31
  108. data/spec/core/database_spec.rb +491 -227
  109. data/spec/core/dataset_spec.rb +638 -1051
  110. data/spec/core/expression_filters_spec.rb +0 -1
  111. data/spec/core/mock_adapter_spec.rb +378 -0
  112. data/spec/core/object_graph_spec.rb +48 -114
  113. data/spec/core/schema_generator_spec.rb +3 -3
  114. data/spec/core/schema_spec.rb +51 -114
  115. data/spec/core/spec_helper.rb +3 -90
  116. data/spec/extensions/class_table_inheritance_spec.rb +1 -1
  117. data/spec/extensions/dataset_associations_spec.rb +199 -0
  118. data/spec/extensions/instance_hooks_spec.rb +71 -0
  119. data/spec/extensions/named_timezones_spec.rb +22 -2
  120. data/spec/extensions/nested_attributes_spec.rb +3 -0
  121. data/spec/extensions/schema_spec.rb +1 -1
  122. data/spec/extensions/serialization_modification_detection_spec.rb +1 -0
  123. data/spec/extensions/serialization_spec.rb +5 -8
  124. data/spec/extensions/spec_helper.rb +4 -0
  125. data/spec/extensions/thread_local_timezones_spec.rb +22 -2
  126. data/spec/extensions/typecast_on_load_spec.rb +1 -6
  127. data/spec/integration/associations_test.rb +123 -12
  128. data/spec/integration/dataset_test.rb +140 -47
  129. data/spec/integration/eager_loader_test.rb +19 -21
  130. data/spec/integration/model_test.rb +80 -1
  131. data/spec/integration/plugin_test.rb +179 -128
  132. data/spec/integration/prepared_statement_test.rb +92 -91
  133. data/spec/integration/schema_test.rb +42 -23
  134. data/spec/integration/spec_helper.rb +25 -31
  135. data/spec/integration/timezone_test.rb +38 -12
  136. data/spec/integration/transaction_test.rb +161 -34
  137. data/spec/integration/type_test.rb +3 -3
  138. data/spec/model/association_reflection_spec.rb +83 -7
  139. data/spec/model/associations_spec.rb +393 -676
  140. data/spec/model/base_spec.rb +186 -116
  141. data/spec/model/dataset_methods_spec.rb +7 -27
  142. data/spec/model/eager_loading_spec.rb +343 -867
  143. data/spec/model/hooks_spec.rb +160 -79
  144. data/spec/model/model_spec.rb +118 -165
  145. data/spec/model/plugins_spec.rb +7 -13
  146. data/spec/model/record_spec.rb +138 -207
  147. data/spec/model/spec_helper.rb +10 -73
  148. metadata +14 -8
@@ -16,11 +16,6 @@ end
16
16
 
17
17
  Sequel::Model.use_transactions = false
18
18
 
19
- $sqls = []
20
- def clear_sqls
21
- $sqls.clear
22
- end
23
-
24
19
  unless defined?(RSpec)
25
20
  module Spec::Matchers
26
21
  class BeWithin
@@ -34,46 +29,45 @@ unless defined?(RSpec)
34
29
  end
35
30
  end
36
31
 
37
- (defined?(RSpec) ? RSpec::Core::ExampleGroup : Spec::Example::ExampleGroup).class_eval do
38
- def log
39
- begin
40
- INTEGRATION_DB.loggers << Logger.new(STDOUT)
41
- yield
42
- ensure
43
- INTEGRATION_DB.loggers.pop
44
- end
45
- end
46
-
47
- def self.log_specify(message, &block)
48
- specify(message){log{instance_eval(&block)}}
49
- end
50
-
51
- def self.cspecify(message, *checked, &block)
52
- return specify(message, &block) if ENV['SEQUEL_NO_PENDING']
53
- pending = false
32
+ def Sequel.guarded?(*checked)
33
+ unless ENV['SEQUEL_NO_PENDING']
54
34
  checked.each do |c|
55
35
  case c
56
36
  when INTEGRATION_DB.database_type
57
- pending = c
37
+ return c
58
38
  when Array
59
39
  case c.length
60
40
  when 1
61
- pending = c if c.first == INTEGRATION_DB.adapter_scheme
41
+ return c if c.first == INTEGRATION_DB.adapter_scheme
62
42
  when 2
63
43
  if c.first.is_a?(Proc)
64
- pending = c if c.first.call(INTEGRATION_DB) && c.last == INTEGRATION_DB.database_type
44
+ return c if c.first.call(INTEGRATION_DB) && c.last == INTEGRATION_DB.database_type
65
45
  elsif c.last.is_a?(Proc)
66
- pending = c if c.first == INTEGRATION_DB.adapter_scheme && c.last.call(INTEGRATION_DB)
46
+ return c if c.first == INTEGRATION_DB.adapter_scheme && c.last.call(INTEGRATION_DB)
67
47
  else
68
- pending = c if c.first == INTEGRATION_DB.adapter_scheme && c.last == INTEGRATION_DB.database_type
48
+ return c if c.first == INTEGRATION_DB.adapter_scheme && c.last == INTEGRATION_DB.database_type
69
49
  end
70
50
  when 3
71
- pending = c if c[0] == INTEGRATION_DB.adapter_scheme && c[1] == INTEGRATION_DB.database_type && c[2].call(INTEGRATION_DB)
51
+ return c if c[0] == INTEGRATION_DB.adapter_scheme && c[1] == INTEGRATION_DB.database_type && c[2].call(INTEGRATION_DB)
72
52
  end
73
53
  end
74
- break if pending
75
54
  end
76
- if pending
55
+ end
56
+ false
57
+ end
58
+
59
+ (defined?(RSpec) ? RSpec::Core::ExampleGroup : Spec::Example::ExampleGroup).class_eval do
60
+ def log
61
+ begin
62
+ INTEGRATION_DB.loggers << Logger.new(STDOUT)
63
+ yield
64
+ ensure
65
+ INTEGRATION_DB.loggers.pop
66
+ end
67
+ end
68
+
69
+ def self.cspecify(message, *checked, &block)
70
+ if pending = Sequel.guarded?(*checked)
77
71
  specify(message){pending("Not yet working on #{Array(pending).join(', ')}", &block)}
78
72
  else
79
73
  specify(message, &block)
@@ -88,7 +82,7 @@ if defined?(INTEGRATION_DB) || defined?(INTEGRATION_URL) || ENV['SEQUEL_INTEGRAT
88
82
  #INTEGRATION_DB.instance_variable_set(:@server_version, 80100)
89
83
  end
90
84
  else
91
- INTEGRATION_DB = Sequel.sqlite('', :quote_identifiers=>false)
85
+ INTEGRATION_DB = Sequel.sqlite
92
86
  end
93
87
 
94
88
  if INTEGRATION_DB.adapter_scheme == :ibmdb
@@ -1,15 +1,17 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Sequel timezone support" do
4
- def test_timezone
4
+ def test_timezone(timezone=Sequel.application_timezone)
5
+ tz = timezone
6
+ Sequel.datetime_class = Time
5
7
  # Tests should cover both DST and non-DST times.
6
8
  [Time.now, Time.local(2010,1,1,12), Time.local(2010,6,1,12)].each do |t|
7
9
  @db[:t].insert(t)
8
10
  t2 = @db[:t].single_value
9
- t2 = Sequel.database_to_application_timestamp(t2.to_s) unless t2.is_a?(Time)
11
+ t2 = @db.to_application_timestamp(t2.to_s) unless t2.is_a?(Time)
10
12
  (t2 - t).should be_within(2).of(0)
11
- t2.utc_offset.should == 0 if Sequel.application_timezone == :utc
12
- t2.utc_offset.should == t.getlocal.utc_offset if Sequel.application_timezone == :local
13
+ t2.utc_offset.should == 0 if timezone == :utc
14
+ t2.utc_offset.should == t.getlocal.utc_offset if timezone == :local
13
15
  @db[:t].delete
14
16
  end
15
17
 
@@ -19,10 +21,10 @@ describe "Sequel timezone support" do
19
21
  [DateTime.now, DateTime.civil(2010,1,1,12,0,0,local_std_offset), DateTime.civil(2010,6,1,12,0,0,local_dst_offset)].each do |dt|
20
22
  @db[:t].insert(dt)
21
23
  dt2 = @db[:t].single_value
22
- dt2 = Sequel.database_to_application_timestamp(dt2.to_s) unless dt2.is_a?(DateTime)
24
+ dt2 = @db.to_application_timestamp(dt2.to_s) unless dt2.is_a?(DateTime)
23
25
  (dt2 - dt).should be_within(0.00002).of(0)
24
- dt2.offset.should == 0 if Sequel.application_timezone == :utc
25
- dt2.offset.should == dt.offset if Sequel.application_timezone == :local
26
+ dt2.offset.should == 0 if timezone == :utc
27
+ dt2.offset.should == dt.offset if timezone == :local
26
28
  @db[:t].delete
27
29
  end
28
30
  end
@@ -32,30 +34,54 @@ describe "Sequel timezone support" do
32
34
  @db.create_table!(:t){DateTime :t}
33
35
  end
34
36
  after do
35
- @db.drop_table(:t)
37
+ @db.timezone = nil
36
38
  Sequel.default_timezone = nil
37
39
  Sequel.datetime_class = Time
40
+ @db.drop_table(:t)
38
41
  end
39
42
 
40
- cspecify "should support using UTC for database storage and local time for the application", [:swift], [:tinytds], [:do, proc{|db| db.database_type != :sqlite}] do
43
+ cspecify "should support using UTC for database storage and local time for the application", [:swift], [:tinytds], [:do, :mysql], [:do, :postgres], [:oracle] do
41
44
  Sequel.database_timezone = :utc
42
45
  Sequel.application_timezone = :local
43
46
  test_timezone
47
+ Sequel.database_timezone = nil
48
+ @db.timezone = :utc
49
+ test_timezone
44
50
  end
45
51
 
46
- cspecify "should support using local time for database storage and UTC for the application", [:swift], [:tinytds], [:do, proc{|db| db.database_type != :sqlite}] do
52
+ cspecify "should support using local time for database storage and UTC for the application", [:swift], [:tinytds], [:do, :mysql], [:do, :postgres], [:oracle] do
47
53
  Sequel.database_timezone = :local
48
54
  Sequel.application_timezone = :utc
49
55
  test_timezone
56
+ Sequel.database_timezone = nil
57
+ @db.timezone = :local
58
+ test_timezone
50
59
  end
51
60
 
52
- cspecify "should support using UTC for both database storage and for application", [:swift], [:do, proc{|db| db.database_type != :sqlite}] do
61
+ cspecify "should support using UTC for both database storage and for application", [:swift], [:do, :mysql], [:do, :postgres], [:oracle] do
53
62
  Sequel.default_timezone = :utc
54
63
  test_timezone
64
+ Sequel.database_timezone = :local
65
+ @db.timezone = :utc
66
+ test_timezone
55
67
  end
56
68
 
57
- cspecify "should support using local time for both database storage and for application", [:do, proc{|db| db.database_type != :sqlite}] do
69
+ cspecify "should support using local time for both database storage and for application", [:do, :mysql], [:do, :postgres], [:oracle] do
58
70
  Sequel.default_timezone = :local
59
71
  test_timezone
72
+ Sequel.database_timezone = :utc
73
+ @db.timezone = :local
74
+ test_timezone
75
+ end
76
+
77
+ specify "should allow overriding the database_timezone on a per-database basis" do
78
+ Sequel.database_timezone = :utc
79
+ @db.timezone = :local
80
+ t = Time.now
81
+ @db[:t].insert(t)
82
+ s = @db[:t].get(:t.cast(String))
83
+ if o = Date._parse(s)[:offset]
84
+ o.should == t.utc_offset
85
+ end
60
86
  end
61
87
  end
@@ -1,14 +1,16 @@
1
1
  require File.join(File.dirname(File.expand_path(__FILE__)), 'spec_helper.rb')
2
2
 
3
3
  describe "Database transactions" do
4
- before do
4
+ before(:all) do
5
5
  @db = INTEGRATION_DB
6
6
  @db.drop_table(:items) if @db.table_exists?(:items)
7
7
  @db.create_table(:items, :engine=>'InnoDB'){String :name; Integer :value}
8
8
  @d = @db[:items]
9
- clear_sqls
10
9
  end
11
- after do
10
+ before do
11
+ @d.delete
12
+ end
13
+ after(:all) do
12
14
  @db.drop_table(:items) if @db.table_exists?(:items)
13
15
  end
14
16
 
@@ -21,6 +23,13 @@ describe "Database transactions" do
21
23
  @db.transaction{|conn| conn.should_not == nil}
22
24
  end
23
25
 
26
+ specify "should have #in_transaction? work correctly" do
27
+ @db.in_transaction?.should be_false
28
+ c = nil
29
+ @db.transaction{c = @db.in_transaction?}
30
+ c.should be_true
31
+ end
32
+
24
33
  specify "should correctly rollback transactions" do
25
34
  proc do
26
35
  @db.transaction do
@@ -29,12 +38,22 @@ describe "Database transactions" do
29
38
  end
30
39
  end.should raise_error(Interrupt)
31
40
 
41
+ @db.transaction do
42
+ @d << {:name => 'abc', :value => 1}
43
+ raise Sequel::Rollback
44
+ end.should be_nil
45
+
32
46
  proc do
33
- @db.transaction do
47
+ @db.transaction(:rollback=>:reraise) do
34
48
  @d << {:name => 'abc', :value => 1}
35
49
  raise Sequel::Rollback
36
50
  end
37
- end.should_not raise_error
51
+ end.should raise_error(Sequel::Rollback)
52
+
53
+ @db.transaction(:rollback=>:always) do
54
+ @d << {:name => 'abc', :value => 1}
55
+ 2
56
+ end.should be_nil
38
57
 
39
58
  @d.count.should == 0
40
59
  end
@@ -126,6 +145,14 @@ describe "Database transactions" do
126
145
  @db.rollback_prepared_transaction('XYZ')
127
146
  @d.select_order_map(:name).should == []
128
147
  end
148
+
149
+ if INTEGRATION_DB.supports_savepoints?
150
+ specify "should support savepoints when using prepared transactions" do
151
+ @db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@d << {:name => '1'}}}
152
+ @db.commit_prepared_transaction('XYZ')
153
+ @d.select_order_map(:name).should == ['1']
154
+ end
155
+ end
129
156
  end
130
157
 
131
158
  specify "should support all transaction isolation levels" do
@@ -135,43 +162,143 @@ describe "Database transactions" do
135
162
  end
136
163
  end
137
164
 
138
- if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby' or (RUBY_ENGINE == 'rbx' && ![[:do, :sqlite], [:tinytds, :mssql]].include?([INTEGRATION_DB.adapter_scheme, INTEGRATION_DB.database_type]))) and RUBY_VERSION < '1.9'
139
- specify "should handle Thread#kill for transactions inside threads" do
140
- q = Queue.new
141
- q1 = Queue.new
142
- t = Thread.new do
143
- @db.transaction do
144
- @d << {:name => 'abc', :value => 1}
145
- q1.push nil
146
- q.pop
147
- @d << {:name => 'def', :value => 2}
165
+ specify "should support after_commit outside transactions" do
166
+ c = nil
167
+ @db.after_commit{c = 1}
168
+ c.should == 1
169
+ end
170
+
171
+ specify "should support after_rollback outside transactions" do
172
+ c = nil
173
+ @db.after_rollback{c = 1}
174
+ c.should be_nil
175
+ end
176
+
177
+ specify "should support after_commit inside transactions" do
178
+ c = nil
179
+ @db.transaction{@db.after_commit{c = 1}; c.should be_nil}
180
+ c.should == 1
181
+ end
182
+
183
+ specify "should support after_rollback inside transactions" do
184
+ c = nil
185
+ @db.transaction{@db.after_rollback{c = 1}; c.should be_nil}
186
+ c.should be_nil
187
+ end
188
+
189
+ specify "should not call after_commit if the transaction rolls back" do
190
+ c = nil
191
+ @db.transaction{@db.after_commit{c = 1}; c.should be_nil; raise Sequel::Rollback}
192
+ c.should be_nil
193
+ end
194
+
195
+ specify "should call after_rollback if the transaction rolls back" do
196
+ c = nil
197
+ @db.transaction{@db.after_rollback{c = 1}; c.should be_nil; raise Sequel::Rollback}
198
+ c.should == 1
199
+ end
200
+
201
+ specify "should support multiple after_commit blocks inside transactions" do
202
+ c = []
203
+ @db.transaction{@db.after_commit{c << 1}; @db.after_commit{c << 2}; c.should == []}
204
+ c.should == [1, 2]
205
+ end
206
+
207
+ specify "should support multiple after_rollback blocks inside transactions" do
208
+ c = []
209
+ @db.transaction{@db.after_rollback{c << 1}; @db.after_rollback{c << 2}; c.should == []; raise Sequel::Rollback}
210
+ c.should == [1, 2]
211
+ end
212
+
213
+ specify "should support after_commit inside nested transactions" do
214
+ c = nil
215
+ @db.transaction{@db.transaction{@db.after_commit{c = 1}}; c.should be_nil}
216
+ c.should == 1
217
+ end
218
+
219
+ specify "should support after_rollback inside nested transactions" do
220
+ c = nil
221
+ @db.transaction{@db.transaction{@db.after_rollback{c = 1}}; c.should be_nil; raise Sequel::Rollback}
222
+ c.should == 1
223
+ end
224
+
225
+ if INTEGRATION_DB.supports_savepoints?
226
+ specify "should support after_commit inside savepoints" do
227
+ c = nil
228
+ @db.transaction{@db.transaction(:savepoint=>true){@db.after_commit{c = 1}}; c.should be_nil}
229
+ c.should == 1
230
+ end
231
+
232
+ specify "should support after_rollback inside savepoints" do
233
+ c = nil
234
+ @db.transaction{@db.transaction(:savepoint=>true){@db.after_rollback{c = 1}}; c.should be_nil; raise Sequel::Rollback}
235
+ c.should == 1
236
+ end
237
+ end
238
+
239
+ if INTEGRATION_DB.supports_prepared_transactions?
240
+ specify "should raise an error if you attempt to use after_commit or after_rollback inside a prepared transaction" do
241
+ proc{@db.transaction(:prepare=>'XYZ'){@db.after_commit{}}}.should raise_error(Sequel::Error)
242
+ proc{@db.transaction(:prepare=>'XYZ'){@db.after_rollback{}}}.should raise_error(Sequel::Error)
243
+ end
244
+
245
+ if INTEGRATION_DB.supports_savepoints?
246
+ specify "should raise an error if you attempt to use after_commit or after rollback inside a savepoint in a prepared transaction" do
247
+ proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_commit{}}}}.should raise_error(Sequel::Error)
248
+ proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_rollback{}}}}.should raise_error(Sequel::Error)
148
249
  end
149
250
  end
150
- q1.pop
151
- t.kill
152
- @d.count.should == 0
153
251
  end
252
+ end
154
253
 
155
- if INTEGRATION_DB.supports_savepoints?
156
- specify "should handle Thread#kill for transactions with savepoints inside threads" do
157
- q = Queue.new
158
- q1 = Queue.new
159
- t = Thread.new do
160
- @db.transaction do
161
- @d << {:name => 'abc', :value => 1}
162
- @db.transaction(:savepoint=>true) do
163
- @d << {:name => 'def', :value => 2}
254
+ if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby' or (RUBY_ENGINE == 'rbx' && !Sequel.guarded?([:do, :sqlite], [:tinytds, :mssql]))) and RUBY_VERSION < '1.9'
255
+ describe "Database transactions and Thread#kill" do
256
+ before do
257
+ @db = INTEGRATION_DB
258
+ @db.drop_table(:items) if @db.table_exists?(:items)
259
+ @db.create_table(:items, :engine=>'InnoDB'){String :name; Integer :value}
260
+ @d = @db[:items]
261
+ end
262
+ after do
263
+ @db.drop_table(:items) if @db.table_exists?(:items)
264
+ end
265
+
266
+ specify "should handle transactions inside threads" do
267
+ q = Queue.new
268
+ q1 = Queue.new
269
+ t = Thread.new do
270
+ @db.transaction do
271
+ @d << {:name => 'abc', :value => 1}
164
272
  q1.push nil
165
273
  q.pop
166
- @d << {:name => 'ghi', :value => 3}
274
+ @d << {:name => 'def', :value => 2}
167
275
  end
168
- @d << {:name => 'jkl', :value => 4}
276
+ end
277
+ q1.pop
278
+ t.kill
279
+ @d.count.should == 0
280
+ end
281
+
282
+ if INTEGRATION_DB.supports_savepoints?
283
+ specify "should handle transactions with savepoints inside threads" do
284
+ q = Queue.new
285
+ q1 = Queue.new
286
+ t = Thread.new do
287
+ @db.transaction do
288
+ @d << {:name => 'abc', :value => 1}
289
+ @db.transaction(:savepoint=>true) do
290
+ @d << {:name => 'def', :value => 2}
291
+ q1.push nil
292
+ q.pop
293
+ @d << {:name => 'ghi', :value => 3}
294
+ end
295
+ @d << {:name => 'jkl', :value => 4}
296
+ end
297
+ end
298
+ q1.pop
299
+ t.kill
300
+ @d.count.should == 0
169
301
  end
170
302
  end
171
- q1.pop
172
- t.kill
173
- @d.count.should == 0
174
303
  end
175
304
  end
176
- end
177
- end
@@ -60,7 +60,7 @@ describe "Supported types" do
60
60
  ds.all.should == [{:name=>'Test User'}]
61
61
  end
62
62
 
63
- cspecify "should support generic date type", [:do, :sqlite], [:jdbc, :sqlite], :mssql do
63
+ cspecify "should support generic date type", [:do, :sqlite], [:jdbc, :sqlite], :mssql, :oracle do
64
64
  ds = create_items_table_with_column(:dat, Date)
65
65
  d = Date.today
66
66
  ds.insert(:dat => d)
@@ -68,7 +68,7 @@ describe "Supported types" do
68
68
  ds.first[:dat].to_s.should == d.to_s
69
69
  end
70
70
 
71
- cspecify "should support generic time type", [:do], [:swift], [:odbc], [:jdbc, :mssql], [:jdbc, :postgres], [:mysql2], [:tinytds] do
71
+ cspecify "should support generic time type", [:do], [:swift], [:odbc], [:jdbc, :mssql], [:jdbc, :postgres], [:jdbc, :sqlite], [:mysql2], [:tinytds], :oracle do
72
72
  ds = create_items_table_with_column(:tim, Time, :only_time=>true)
73
73
  t = Sequel::SQLTime.now
74
74
  ds.insert(:tim => t)
@@ -100,7 +100,7 @@ describe "Supported types" do
100
100
  ds.first[:name].should be_a_kind_of(::Sequel::SQL::Blob)
101
101
  end
102
102
 
103
- cspecify "should support generic boolean type", [:do, :sqlite], [:jdbc, :sqlite], [:jdbc, :db2], [:odbc, :mssql] do
103
+ cspecify "should support generic boolean type", [:do, :sqlite], [:jdbc, :sqlite], [:jdbc, :db2], [:odbc, :mssql], :oracle do
104
104
  ds = create_items_table_with_column(:number, TrueClass)
105
105
  ds.insert(:number => true)
106
106
  ds.all.should == [{:number=>true}]