sequel 3.28.0 → 3.29.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +119 -3
- data/Rakefile +5 -3
- data/bin/sequel +1 -5
- data/doc/model_hooks.rdoc +9 -1
- data/doc/opening_databases.rdoc +49 -40
- data/doc/prepared_statements.rdoc +27 -6
- data/doc/release_notes/3.28.0.txt +2 -2
- data/doc/release_notes/3.29.0.txt +459 -0
- data/doc/sharding.rdoc +7 -1
- data/doc/testing.rdoc +18 -9
- data/doc/transactions.rdoc +41 -1
- data/lib/sequel/adapters/ado.rb +28 -17
- data/lib/sequel/adapters/ado/mssql.rb +18 -6
- data/lib/sequel/adapters/amalgalite.rb +11 -7
- data/lib/sequel/adapters/db2.rb +122 -70
- data/lib/sequel/adapters/dbi.rb +15 -15
- data/lib/sequel/adapters/do.rb +5 -36
- data/lib/sequel/adapters/do/mysql.rb +0 -5
- data/lib/sequel/adapters/do/postgres.rb +0 -5
- data/lib/sequel/adapters/do/sqlite.rb +0 -5
- data/lib/sequel/adapters/firebird.rb +3 -6
- data/lib/sequel/adapters/ibmdb.rb +24 -16
- data/lib/sequel/adapters/informix.rb +2 -4
- data/lib/sequel/adapters/jdbc.rb +47 -11
- data/lib/sequel/adapters/jdbc/as400.rb +5 -24
- data/lib/sequel/adapters/jdbc/db2.rb +0 -5
- data/lib/sequel/adapters/jdbc/derby.rb +217 -0
- data/lib/sequel/adapters/jdbc/firebird.rb +0 -5
- data/lib/sequel/adapters/jdbc/h2.rb +10 -12
- data/lib/sequel/adapters/jdbc/hsqldb.rb +166 -0
- data/lib/sequel/adapters/jdbc/informix.rb +0 -5
- data/lib/sequel/adapters/jdbc/jtds.rb +0 -5
- data/lib/sequel/adapters/jdbc/mysql.rb +0 -10
- data/lib/sequel/adapters/jdbc/oracle.rb +70 -3
- data/lib/sequel/adapters/jdbc/postgresql.rb +0 -11
- data/lib/sequel/adapters/jdbc/sqlite.rb +0 -5
- data/lib/sequel/adapters/jdbc/sqlserver.rb +0 -5
- data/lib/sequel/adapters/jdbc/transactions.rb +56 -7
- data/lib/sequel/adapters/mock.rb +315 -0
- data/lib/sequel/adapters/mysql.rb +64 -51
- data/lib/sequel/adapters/mysql2.rb +15 -9
- data/lib/sequel/adapters/odbc.rb +13 -6
- data/lib/sequel/adapters/odbc/db2.rb +0 -4
- data/lib/sequel/adapters/odbc/mssql.rb +0 -5
- data/lib/sequel/adapters/openbase.rb +2 -4
- data/lib/sequel/adapters/oracle.rb +333 -51
- data/lib/sequel/adapters/postgres.rb +80 -27
- data/lib/sequel/adapters/shared/access.rb +0 -6
- data/lib/sequel/adapters/shared/db2.rb +13 -15
- data/lib/sequel/adapters/shared/firebird.rb +6 -6
- data/lib/sequel/adapters/shared/mssql.rb +23 -18
- data/lib/sequel/adapters/shared/mysql.rb +6 -6
- data/lib/sequel/adapters/shared/mysql_prepared_statements.rb +6 -0
- data/lib/sequel/adapters/shared/oracle.rb +185 -30
- data/lib/sequel/adapters/shared/postgres.rb +35 -18
- data/lib/sequel/adapters/shared/progress.rb +0 -6
- data/lib/sequel/adapters/shared/sqlite.rb +116 -37
- data/lib/sequel/adapters/sqlite.rb +16 -8
- data/lib/sequel/adapters/swift.rb +5 -5
- data/lib/sequel/adapters/swift/mysql.rb +0 -5
- data/lib/sequel/adapters/swift/postgres.rb +0 -5
- data/lib/sequel/adapters/swift/sqlite.rb +6 -4
- data/lib/sequel/adapters/tinytds.rb +13 -10
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +8 -0
- data/lib/sequel/core.rb +40 -0
- data/lib/sequel/database/connecting.rb +1 -2
- data/lib/sequel/database/dataset.rb +3 -3
- data/lib/sequel/database/dataset_defaults.rb +58 -0
- data/lib/sequel/database/misc.rb +62 -2
- data/lib/sequel/database/query.rb +113 -49
- data/lib/sequel/database/schema_methods.rb +7 -2
- data/lib/sequel/dataset/actions.rb +37 -19
- data/lib/sequel/dataset/features.rb +24 -0
- data/lib/sequel/dataset/graph.rb +7 -6
- data/lib/sequel/dataset/misc.rb +11 -3
- data/lib/sequel/dataset/mutation.rb +2 -3
- data/lib/sequel/dataset/prepared_statements.rb +6 -4
- data/lib/sequel/dataset/query.rb +46 -15
- data/lib/sequel/dataset/sql.rb +28 -4
- data/lib/sequel/extensions/named_timezones.rb +5 -0
- data/lib/sequel/extensions/thread_local_timezones.rb +1 -1
- data/lib/sequel/model.rb +2 -1
- data/lib/sequel/model/associations.rb +115 -33
- data/lib/sequel/model/base.rb +91 -31
- data/lib/sequel/plugins/class_table_inheritance.rb +4 -4
- data/lib/sequel/plugins/dataset_associations.rb +100 -0
- data/lib/sequel/plugins/force_encoding.rb +6 -6
- data/lib/sequel/plugins/identity_map.rb +1 -1
- data/lib/sequel/plugins/many_through_many.rb +6 -10
- data/lib/sequel/plugins/prepared_statements.rb +12 -1
- data/lib/sequel/plugins/prepared_statements_associations.rb +1 -1
- data/lib/sequel/plugins/rcte_tree.rb +29 -15
- data/lib/sequel/plugins/serialization.rb +6 -1
- data/lib/sequel/plugins/sharding.rb +0 -5
- data/lib/sequel/plugins/single_table_inheritance.rb +1 -1
- data/lib/sequel/plugins/typecast_on_load.rb +9 -12
- data/lib/sequel/plugins/update_primary_key.rb +1 -1
- data/lib/sequel/timezones.rb +42 -42
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +29 -29
- data/spec/adapters/mysql_spec.rb +86 -104
- data/spec/adapters/oracle_spec.rb +48 -76
- data/spec/adapters/postgres_spec.rb +98 -33
- data/spec/adapters/spec_helper.rb +0 -5
- data/spec/adapters/sqlite_spec.rb +24 -21
- data/spec/core/connection_pool_spec.rb +9 -15
- data/spec/core/core_sql_spec.rb +20 -31
- data/spec/core/database_spec.rb +491 -227
- data/spec/core/dataset_spec.rb +638 -1051
- data/spec/core/expression_filters_spec.rb +0 -1
- data/spec/core/mock_adapter_spec.rb +378 -0
- data/spec/core/object_graph_spec.rb +48 -114
- data/spec/core/schema_generator_spec.rb +3 -3
- data/spec/core/schema_spec.rb +51 -114
- data/spec/core/spec_helper.rb +3 -90
- data/spec/extensions/class_table_inheritance_spec.rb +1 -1
- data/spec/extensions/dataset_associations_spec.rb +199 -0
- data/spec/extensions/instance_hooks_spec.rb +71 -0
- data/spec/extensions/named_timezones_spec.rb +22 -2
- data/spec/extensions/nested_attributes_spec.rb +3 -0
- data/spec/extensions/schema_spec.rb +1 -1
- data/spec/extensions/serialization_modification_detection_spec.rb +1 -0
- data/spec/extensions/serialization_spec.rb +5 -8
- data/spec/extensions/spec_helper.rb +4 -0
- data/spec/extensions/thread_local_timezones_spec.rb +22 -2
- data/spec/extensions/typecast_on_load_spec.rb +1 -6
- data/spec/integration/associations_test.rb +123 -12
- data/spec/integration/dataset_test.rb +140 -47
- data/spec/integration/eager_loader_test.rb +19 -21
- data/spec/integration/model_test.rb +80 -1
- data/spec/integration/plugin_test.rb +179 -128
- data/spec/integration/prepared_statement_test.rb +92 -91
- data/spec/integration/schema_test.rb +42 -23
- data/spec/integration/spec_helper.rb +25 -31
- data/spec/integration/timezone_test.rb +38 -12
- data/spec/integration/transaction_test.rb +161 -34
- data/spec/integration/type_test.rb +3 -3
- data/spec/model/association_reflection_spec.rb +83 -7
- data/spec/model/associations_spec.rb +393 -676
- data/spec/model/base_spec.rb +186 -116
- data/spec/model/dataset_methods_spec.rb +7 -27
- data/spec/model/eager_loading_spec.rb +343 -867
- data/spec/model/hooks_spec.rb +160 -79
- data/spec/model/model_spec.rb +118 -165
- data/spec/model/plugins_spec.rb +7 -13
- data/spec/model/record_spec.rb +138 -207
- data/spec/model/spec_helper.rb +10 -73
- 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
|
-
|
38
|
-
|
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
|
-
|
37
|
+
return c
|
58
38
|
when Array
|
59
39
|
case c.length
|
60
40
|
when 1
|
61
|
-
|
41
|
+
return c if c.first == INTEGRATION_DB.adapter_scheme
|
62
42
|
when 2
|
63
43
|
if c.first.is_a?(Proc)
|
64
|
-
|
44
|
+
return c if c.first.call(INTEGRATION_DB) && c.last == INTEGRATION_DB.database_type
|
65
45
|
elsif c.last.is_a?(Proc)
|
66
|
-
|
46
|
+
return c if c.first == INTEGRATION_DB.adapter_scheme && c.last.call(INTEGRATION_DB)
|
67
47
|
else
|
68
|
-
|
48
|
+
return c if c.first == INTEGRATION_DB.adapter_scheme && c.last == INTEGRATION_DB.database_type
|
69
49
|
end
|
70
50
|
when 3
|
71
|
-
|
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
|
-
|
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
|
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 =
|
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
|
12
|
-
t2.utc_offset.should == t.getlocal.utc_offset if
|
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 =
|
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
|
25
|
-
dt2.offset.should == dt.offset if
|
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.
|
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,
|
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,
|
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,
|
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,
|
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
|
-
|
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.
|
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
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
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
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
@db.
|
161
|
-
|
162
|
-
|
163
|
-
|
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 => '
|
274
|
+
@d << {:name => 'def', :value => 2}
|
167
275
|
end
|
168
|
-
|
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}]
|