sequel 3.28.0 → 3.29.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.
- 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}]
|