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
|
@@ -144,13 +144,6 @@ describe "An SQLite dataset" do
|
|
|
144
144
|
@d = SQLITE_DB[:items]
|
|
145
145
|
end
|
|
146
146
|
|
|
147
|
-
specify "should handle string pattern matches correctly" do
|
|
148
|
-
@d.literal(:x.like('a')).should == "(x LIKE 'a')"
|
|
149
|
-
@d.literal(~:x.like('a')).should == "NOT (x LIKE 'a')"
|
|
150
|
-
@d.literal(:x.ilike('a')).should == "(x LIKE 'a')"
|
|
151
|
-
@d.literal(~:x.ilike('a')).should == "NOT (x LIKE 'a')"
|
|
152
|
-
end
|
|
153
|
-
|
|
154
147
|
specify "should raise errors if given a regexp pattern match" do
|
|
155
148
|
proc{@d.literal(:x.like(/a/))}.should raise_error(Sequel::Error)
|
|
156
149
|
proc{@d.literal(~:x.like(/a/))}.should raise_error(Sequel::Error)
|
|
@@ -175,27 +168,27 @@ end
|
|
|
175
168
|
|
|
176
169
|
describe "An SQLite dataset AS clause" do
|
|
177
170
|
specify "should use a string literal for :col___alias" do
|
|
178
|
-
SQLITE_DB.literal(:c___a).should == "c AS 'a'"
|
|
171
|
+
SQLITE_DB.literal(:c___a).should == "`c` AS 'a'"
|
|
179
172
|
end
|
|
180
173
|
|
|
181
174
|
specify "should use a string literal for :table__col___alias" do
|
|
182
|
-
SQLITE_DB.literal(:t__c___a).should == "t
|
|
175
|
+
SQLITE_DB.literal(:t__c___a).should == "`t`.`c` AS 'a'"
|
|
183
176
|
end
|
|
184
177
|
|
|
185
178
|
specify "should use a string literal for :column.as(:alias)" do
|
|
186
|
-
SQLITE_DB.literal(:c.as(:a)).should == "c AS 'a'"
|
|
179
|
+
SQLITE_DB.literal(:c.as(:a)).should == "`c` AS 'a'"
|
|
187
180
|
end
|
|
188
181
|
|
|
189
182
|
specify "should use a string literal in the SELECT clause" do
|
|
190
|
-
SQLITE_DB[:t].select(:c___a).sql.should == "SELECT c AS 'a' FROM t"
|
|
183
|
+
SQLITE_DB[:t].select(:c___a).sql.should == "SELECT `c` AS 'a' FROM `t`"
|
|
191
184
|
end
|
|
192
185
|
|
|
193
186
|
specify "should use a string literal in the FROM clause" do
|
|
194
|
-
SQLITE_DB[:t___a].sql.should == "SELECT * FROM t AS 'a'"
|
|
187
|
+
SQLITE_DB[:t___a].sql.should == "SELECT * FROM `t` AS 'a'"
|
|
195
188
|
end
|
|
196
189
|
|
|
197
190
|
specify "should use a string literal in the JOIN clause" do
|
|
198
|
-
SQLITE_DB[:t].join_table(:natural, :j, nil, :a).sql.should == "SELECT * FROM t NATURAL JOIN j AS 'a'"
|
|
191
|
+
SQLITE_DB[:t].join_table(:natural, :j, nil, :a).sql.should == "SELECT * FROM `t` NATURAL JOIN `j` AS 'a'"
|
|
199
192
|
end
|
|
200
193
|
end
|
|
201
194
|
|
|
@@ -324,6 +317,15 @@ describe "A SQLite database" do
|
|
|
324
317
|
@db[:test2].first.should == {:name => 'mmm'}
|
|
325
318
|
end
|
|
326
319
|
|
|
320
|
+
specify "should keep a composite primary key when dropping columns" do
|
|
321
|
+
@db.create_table!(:test2){Integer :a; Integer :b; Integer :c; primary_key [:a, :b]}
|
|
322
|
+
@db.drop_column :test2, :c
|
|
323
|
+
@db[:test2].columns.should == [:a, :b]
|
|
324
|
+
@db[:test2] << {:a=>1, :b=>2}
|
|
325
|
+
@db[:test2] << {:a=>2, :b=>3}
|
|
326
|
+
proc{@db[:test2] << {:a=>2, :b=>3}}.should raise_error(Sequel::Error)
|
|
327
|
+
end
|
|
328
|
+
|
|
327
329
|
specify "should keep column attributes when dropping a column" do
|
|
328
330
|
@db.create_table! :test3 do
|
|
329
331
|
primary_key :id
|
|
@@ -423,14 +425,15 @@ describe "A SQLite database" do
|
|
|
423
425
|
specify "should choose a temporary table name that isn't already used when dropping or renaming columns" do
|
|
424
426
|
sqls = []
|
|
425
427
|
@db.loggers << (l=Class.new{%w'info error'.each{|m| define_method(m){|sql| sqls << sql}}}.new)
|
|
426
|
-
@db.
|
|
428
|
+
@db.tables.each{|t| @db.drop_table(t) if t.to_s =~ /test3/}
|
|
429
|
+
@db.create_table :test3 do
|
|
427
430
|
Integer :h
|
|
428
431
|
Integer :i
|
|
429
432
|
end
|
|
430
|
-
@db.create_table
|
|
433
|
+
@db.create_table :test3_backup0 do
|
|
431
434
|
Integer :j
|
|
432
435
|
end
|
|
433
|
-
@db.create_table
|
|
436
|
+
@db.create_table :test3_backup1 do
|
|
434
437
|
Integer :k
|
|
435
438
|
end
|
|
436
439
|
|
|
@@ -439,20 +442,20 @@ describe "A SQLite database" do
|
|
|
439
442
|
@db[:test3_backup1].columns.should == [:k]
|
|
440
443
|
sqls.clear
|
|
441
444
|
@db.drop_column(:test3, :i)
|
|
442
|
-
sqls.any?{|x| x =~ /\
|
|
443
|
-
sqls.any?{|x| x =~ /\
|
|
445
|
+
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup2/}.should == true
|
|
446
|
+
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup[01]/}.should == false
|
|
444
447
|
@db[:test3].columns.should == [:h]
|
|
445
448
|
@db[:test3_backup0].columns.should == [:j]
|
|
446
449
|
@db[:test3_backup1].columns.should == [:k]
|
|
447
450
|
|
|
448
|
-
@db.create_table
|
|
451
|
+
@db.create_table :test3_backup2 do
|
|
449
452
|
Integer :l
|
|
450
453
|
end
|
|
451
454
|
|
|
452
455
|
sqls.clear
|
|
453
456
|
@db.rename_column(:test3, :h, :i)
|
|
454
|
-
sqls.any?{|x| x =~ /\
|
|
455
|
-
sqls.any?{|x| x =~ /\
|
|
457
|
+
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup3/}.should == true
|
|
458
|
+
sqls.any?{|x| x =~ /\AALTER TABLE.*test3.*RENAME TO.*test3_backup[012]/}.should == false
|
|
456
459
|
@db[:test3].columns.should == [:i]
|
|
457
460
|
@db[:test3_backup0].columns.should == [:j]
|
|
458
461
|
@db[:test3_backup1].columns.should == [:k]
|
|
@@ -124,36 +124,30 @@ describe "A connection pool handling connection errors" do
|
|
|
124
124
|
end
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
-
class DummyConnection
|
|
128
|
-
@@value = 0
|
|
129
|
-
def initialize
|
|
130
|
-
@@value += 1
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def value
|
|
134
|
-
@@value
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
|
|
138
127
|
describe "ConnectionPool#hold" do
|
|
139
128
|
before do
|
|
140
|
-
|
|
129
|
+
value = 0
|
|
130
|
+
@c = Class.new do
|
|
131
|
+
define_method(:initialize){value += 1}
|
|
132
|
+
define_method(:value){value}
|
|
133
|
+
end
|
|
134
|
+
@pool = Sequel::ConnectionPool.get_pool(CONNECTION_POOL_DEFAULTS){@c.new}
|
|
141
135
|
end
|
|
142
136
|
|
|
143
137
|
specify "should pass the result of the connection maker proc to the supplied block" do
|
|
144
138
|
res = nil
|
|
145
139
|
@pool.hold {|c| res = c}
|
|
146
|
-
res.should be_a_kind_of(
|
|
140
|
+
res.should be_a_kind_of(@c)
|
|
147
141
|
res.value.should == 1
|
|
148
142
|
@pool.hold {|c| res = c}
|
|
149
|
-
res.should be_a_kind_of(
|
|
143
|
+
res.should be_a_kind_of(@c)
|
|
150
144
|
res.value.should == 1 # the connection maker is invoked only once
|
|
151
145
|
end
|
|
152
146
|
|
|
153
147
|
specify "should be re-entrant by the same thread" do
|
|
154
148
|
cc = nil
|
|
155
149
|
@pool.hold {|c| @pool.hold {|c| @pool.hold {|c| cc = c}}}
|
|
156
|
-
cc.should be_a_kind_of(
|
|
150
|
+
cc.should be_a_kind_of(@c)
|
|
157
151
|
end
|
|
158
152
|
|
|
159
153
|
specify "should catch exceptions and reraise them" do
|
data/spec/core/core_sql_spec.rb
CHANGED
|
@@ -75,16 +75,16 @@ end
|
|
|
75
75
|
|
|
76
76
|
describe "String#lit" do
|
|
77
77
|
before do
|
|
78
|
-
@ds = ds =
|
|
78
|
+
@ds = ds = Sequel::Database.new[:t]
|
|
79
79
|
end
|
|
80
|
+
|
|
80
81
|
specify "should return an LiteralString object" do
|
|
81
82
|
'xyz'.lit.should be_a_kind_of(Sequel::LiteralString)
|
|
82
83
|
'xyz'.lit.to_s.should == 'xyz'
|
|
83
84
|
end
|
|
84
85
|
|
|
85
86
|
specify "should inhibit string literalization" do
|
|
86
|
-
|
|
87
|
-
"UPDATE t SET stamp = NOW()"
|
|
87
|
+
@ds.update_sql(:stamp => "NOW()".lit).should == "UPDATE t SET stamp = NOW()"
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
specify "should return a PlaceholderLiteralString object if args are given" do
|
|
@@ -176,10 +176,8 @@ end
|
|
|
176
176
|
|
|
177
177
|
describe "Column references" do
|
|
178
178
|
before do
|
|
179
|
-
@
|
|
180
|
-
|
|
181
|
-
end
|
|
182
|
-
@ds = @c.new(MockDatabase.new)
|
|
179
|
+
@ds = Sequel::Database.new.dataset
|
|
180
|
+
def @ds.quoted_identifier(c); "`#{c}`"; end
|
|
183
181
|
@ds.quote_identifiers = true
|
|
184
182
|
end
|
|
185
183
|
|
|
@@ -289,7 +287,7 @@ end
|
|
|
289
287
|
|
|
290
288
|
describe "Dataset#literal" do
|
|
291
289
|
before do
|
|
292
|
-
@ds =
|
|
290
|
+
@ds = Sequel::Database.new.dataset
|
|
293
291
|
end
|
|
294
292
|
|
|
295
293
|
specify "should convert qualified symbol notation into dot notation" do
|
|
@@ -325,17 +323,12 @@ end
|
|
|
325
323
|
|
|
326
324
|
describe "Symbol" do
|
|
327
325
|
before do
|
|
328
|
-
@ds = Sequel::
|
|
326
|
+
@ds = Sequel::Database.new.dataset
|
|
329
327
|
end
|
|
330
328
|
|
|
331
|
-
specify "should support
|
|
329
|
+
specify "should support sql_function method" do
|
|
332
330
|
:COUNT.sql_function('1').to_s(@ds).should == "COUNT('1')"
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
specify "should inhibit string literalization" do
|
|
336
|
-
db = Sequel::Database.new
|
|
337
|
-
ds = db[:t]
|
|
338
|
-
ds.select(:COUNT.sql_function('1')).sql.should == "SELECT COUNT('1') FROM t"
|
|
331
|
+
@ds.select(:COUNT.sql_function('1')).sql.should == "SELECT COUNT('1')"
|
|
339
332
|
end
|
|
340
333
|
|
|
341
334
|
specify "should support cast method" do
|
|
@@ -367,22 +360,18 @@ describe "Symbol" do
|
|
|
367
360
|
end
|
|
368
361
|
|
|
369
362
|
specify "should allow database independent types when casting" do
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
type
|
|
376
|
-
end
|
|
363
|
+
db = @ds.db
|
|
364
|
+
def db.cast_type_literal(type)
|
|
365
|
+
return :foo if type == Integer
|
|
366
|
+
return :bar if type == String
|
|
367
|
+
type
|
|
377
368
|
end
|
|
378
|
-
@
|
|
379
|
-
:abc.cast(String).to_s(@ds).should == "CAST(abc AS
|
|
380
|
-
:abc.
|
|
381
|
-
:abc.
|
|
382
|
-
:abc.
|
|
383
|
-
:abc.
|
|
384
|
-
:abc.cast_numeric.to_s(@ds2).should == "CAST(abc AS foo)"
|
|
385
|
-
:abc.cast_numeric(String).to_s(@ds2).should == "CAST(abc AS bar)"
|
|
369
|
+
:abc.cast(String).to_s(@ds).should == "CAST(abc AS bar)"
|
|
370
|
+
:abc.cast(String).to_s(@ds).should == "CAST(abc AS bar)"
|
|
371
|
+
:abc.cast_string.to_s(@ds).should == "CAST(abc AS bar)"
|
|
372
|
+
:abc.cast_string(Integer).to_s(@ds).should == "CAST(abc AS foo)"
|
|
373
|
+
:abc.cast_numeric.to_s(@ds).should == "CAST(abc AS foo)"
|
|
374
|
+
:abc.cast_numeric(String).to_s(@ds).should == "CAST(abc AS bar)"
|
|
386
375
|
end
|
|
387
376
|
|
|
388
377
|
specify "should support SQL EXTRACT function via #extract " do
|
data/spec/core/database_spec.rb
CHANGED
|
@@ -74,46 +74,46 @@ describe "A new Database" do
|
|
|
74
74
|
Sequel.identifier_input_method = nil
|
|
75
75
|
Sequel::Database.identifier_input_method.should == ""
|
|
76
76
|
db = Sequel::Database.new(:identifier_input_method=>nil)
|
|
77
|
-
db.identifier_input_method.should
|
|
77
|
+
db.identifier_input_method.should be_nil
|
|
78
78
|
db.identifier_input_method = :downcase
|
|
79
79
|
db.identifier_input_method.should == :downcase
|
|
80
80
|
db = Sequel::Database.new(:identifier_input_method=>:upcase)
|
|
81
81
|
db.identifier_input_method.should == :upcase
|
|
82
82
|
db.identifier_input_method = nil
|
|
83
|
-
db.identifier_input_method.should
|
|
83
|
+
db.identifier_input_method.should be_nil
|
|
84
84
|
Sequel.identifier_input_method = :downcase
|
|
85
85
|
Sequel::Database.identifier_input_method.should == :downcase
|
|
86
86
|
db = Sequel::Database.new(:identifier_input_method=>nil)
|
|
87
|
-
db.identifier_input_method.should
|
|
87
|
+
db.identifier_input_method.should be_nil
|
|
88
88
|
db.identifier_input_method = :upcase
|
|
89
89
|
db.identifier_input_method.should == :upcase
|
|
90
90
|
db = Sequel::Database.new(:identifier_input_method=>:upcase)
|
|
91
91
|
db.identifier_input_method.should == :upcase
|
|
92
92
|
db.identifier_input_method = nil
|
|
93
|
-
db.identifier_input_method.should
|
|
93
|
+
db.identifier_input_method.should be_nil
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
specify "should respect the :identifier_output_method option" do
|
|
97
97
|
Sequel.identifier_output_method = nil
|
|
98
98
|
Sequel::Database.identifier_output_method.should == ""
|
|
99
99
|
db = Sequel::Database.new(:identifier_output_method=>nil)
|
|
100
|
-
db.identifier_output_method.should
|
|
100
|
+
db.identifier_output_method.should be_nil
|
|
101
101
|
db.identifier_output_method = :downcase
|
|
102
102
|
db.identifier_output_method.should == :downcase
|
|
103
103
|
db = Sequel::Database.new(:identifier_output_method=>:upcase)
|
|
104
104
|
db.identifier_output_method.should == :upcase
|
|
105
105
|
db.identifier_output_method = nil
|
|
106
|
-
db.identifier_output_method.should
|
|
106
|
+
db.identifier_output_method.should be_nil
|
|
107
107
|
Sequel.identifier_output_method = :downcase
|
|
108
108
|
Sequel::Database.identifier_output_method.should == :downcase
|
|
109
109
|
db = Sequel::Database.new(:identifier_output_method=>nil)
|
|
110
|
-
db.identifier_output_method.should
|
|
110
|
+
db.identifier_output_method.should be_nil
|
|
111
111
|
db.identifier_output_method = :upcase
|
|
112
112
|
db.identifier_output_method.should == :upcase
|
|
113
113
|
db = Sequel::Database.new(:identifier_output_method=>:upcase)
|
|
114
114
|
db.identifier_output_method.should == :upcase
|
|
115
115
|
db.identifier_output_method = nil
|
|
116
|
-
db.identifier_output_method.should
|
|
116
|
+
db.identifier_output_method.should be_nil
|
|
117
117
|
end
|
|
118
118
|
|
|
119
119
|
specify "should use the default Sequel.quote_identifiers value" do
|
|
@@ -384,10 +384,85 @@ describe "Database#dataset" do
|
|
|
384
384
|
end
|
|
385
385
|
end
|
|
386
386
|
|
|
387
|
+
describe "Database#dataset_class" do
|
|
388
|
+
before do
|
|
389
|
+
@db = Sequel::Database.new
|
|
390
|
+
@dsc = Class.new(Sequel::Dataset)
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
specify "should have setter set the class to use to create datasets" do
|
|
394
|
+
@db.dataset_class = @dsc
|
|
395
|
+
ds = @db.dataset
|
|
396
|
+
ds.should be_a_kind_of(@dsc)
|
|
397
|
+
ds.opts.should == {}
|
|
398
|
+
ds.db.should be(@db)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
specify "should have getter return the class to use to create datasets" do
|
|
402
|
+
@db.dataset_class.should == Sequel::Dataset
|
|
403
|
+
@db.dataset_class = @dsc
|
|
404
|
+
@db.dataset_class.should == @dsc
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
describe "Database#extend_datasets" do
|
|
409
|
+
before do
|
|
410
|
+
@db = Sequel::Database.new
|
|
411
|
+
@m = Module.new{def foo() [3] end}
|
|
412
|
+
@m2 = Module.new{def foo() [4] + super end}
|
|
413
|
+
@db.extend_datasets(@m)
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
specify "should change the dataset class to a subclass the first time it is called" do
|
|
417
|
+
@db.dataset_class.superclass.should == Sequel::Dataset
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
specify "should not create a subclass of the dataset class if called more than once" do
|
|
421
|
+
@db.extend_datasets(@m2)
|
|
422
|
+
@db.dataset_class.superclass.should == Sequel::Dataset
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
specify "should make the dataset class include the module" do
|
|
426
|
+
@db.dataset_class.ancestors.should include(@m)
|
|
427
|
+
@db.dataset_class.ancestors.should_not include(@m2)
|
|
428
|
+
@db.extend_datasets(@m2)
|
|
429
|
+
@db.dataset_class.ancestors.should include(@m)
|
|
430
|
+
@db.dataset_class.ancestors.should include(@m2)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
specify "should have datasets respond to the module's methods" do
|
|
434
|
+
@db.dataset.foo.should == [3]
|
|
435
|
+
@db.extend_datasets(@m2)
|
|
436
|
+
@db.dataset.foo.should == [4, 3]
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
specify "should take a block and create a module from it to use" do
|
|
440
|
+
@db.dataset.foo.should == [3]
|
|
441
|
+
@db.extend_datasets{def foo() [5] + super end}
|
|
442
|
+
@db.dataset.foo.should == [5, 3]
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
specify "should raise an error if both a module and a block are provided" do
|
|
446
|
+
proc{@db.extend_datasets(@m2){def foo() [5] + super end}}.should raise_error(Sequel::Error)
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
specify "should be able to override methods defined in the original Dataset class" do
|
|
450
|
+
@db.extend_datasets(Module.new{def select(*a, &block) super.order(*a, &block) end})
|
|
451
|
+
@db[:t].select(:a, :b).sql.should == 'SELECT a, b FROM t ORDER BY a, b'
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
specify "should reapply settings if dataset_class is chagned" do
|
|
455
|
+
c = Class.new(Sequel::Dataset)
|
|
456
|
+
@db.dataset_class = c
|
|
457
|
+
@db.dataset_class.superclass.should == c
|
|
458
|
+
@db.dataset_class.ancestors.should include(@m)
|
|
459
|
+
@db.dataset.foo.should == [3]
|
|
460
|
+
end
|
|
461
|
+
end
|
|
462
|
+
|
|
387
463
|
describe "Database#execute" do
|
|
388
464
|
specify "should raise Sequel::NotImplemented" do
|
|
389
465
|
proc {Sequel::Database.new.execute('blah blah')}.should raise_error(Sequel::NotImplemented)
|
|
390
|
-
proc {Sequel::Database.new << 'blah blah'}.should raise_error(Sequel::NotImplemented)
|
|
391
466
|
end
|
|
392
467
|
end
|
|
393
468
|
|
|
@@ -409,30 +484,39 @@ describe "Database#indexes" do
|
|
|
409
484
|
end
|
|
410
485
|
end
|
|
411
486
|
|
|
412
|
-
describe "Database
|
|
487
|
+
describe "Database#run" do
|
|
413
488
|
before do
|
|
414
|
-
|
|
415
|
-
@c = Class.new(Sequel::Database) do
|
|
416
|
-
define_method(:execute_ddl){|sql, *opts| sqls.clear; sqls << sql; sqls.concat(opts)}
|
|
417
|
-
end
|
|
418
|
-
@db = @c.new({})
|
|
489
|
+
@db = Sequel.mock(:servers=>{:s1=>{}})
|
|
419
490
|
end
|
|
420
491
|
|
|
421
|
-
specify "should
|
|
422
|
-
|
|
423
|
-
@sqls.should == ["DELETE FROM items"
|
|
424
|
-
@db.run("DELETE FROM items2")
|
|
425
|
-
@sqls.should == ["DELETE FROM items2", {}]
|
|
492
|
+
specify "should execute the code on the database" do
|
|
493
|
+
@db.run("DELETE FROM items")
|
|
494
|
+
@db.sqls.should == ["DELETE FROM items"]
|
|
426
495
|
end
|
|
427
496
|
|
|
428
497
|
specify "should return nil" do
|
|
429
|
-
|
|
430
|
-
@db.run("DELETE FROM items").should == nil
|
|
498
|
+
@db.run("DELETE FROM items").should be_nil
|
|
431
499
|
end
|
|
432
500
|
|
|
433
501
|
specify "should accept options passed to execute_ddl" do
|
|
434
502
|
@db.run("DELETE FROM items", :server=>:s1)
|
|
435
|
-
@sqls.should == ["DELETE FROM items
|
|
503
|
+
@db.sqls.should == ["DELETE FROM items -- s1"]
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
describe "Database#<<" do
|
|
508
|
+
before do
|
|
509
|
+
@db = Sequel.mock
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
specify "should execute the code on the database" do
|
|
513
|
+
@db << "DELETE FROM items"
|
|
514
|
+
@db.sqls.should == ["DELETE FROM items"]
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
specify "should be chainable" do
|
|
518
|
+
@db << "DELETE FROM items" << "DELETE FROM items2"
|
|
519
|
+
@db.sqls.should == ["DELETE FROM items", "DELETE FROM items2"]
|
|
436
520
|
end
|
|
437
521
|
end
|
|
438
522
|
|
|
@@ -442,19 +526,19 @@ describe "Database#synchronize" do
|
|
|
442
526
|
end
|
|
443
527
|
|
|
444
528
|
specify "should wrap the supplied block in pool.hold" do
|
|
445
|
-
|
|
529
|
+
q, q1, q2, q3 = Queue.new, Queue.new, Queue.new, Queue.new
|
|
446
530
|
c1, c2 = nil
|
|
447
|
-
t1 = Thread.new
|
|
448
|
-
|
|
531
|
+
t1 = Thread.new{@db.synchronize{|c| c1 = c; q.push nil; q1.pop}; q.push nil}
|
|
532
|
+
q.pop
|
|
449
533
|
c1.should == 12345
|
|
450
|
-
t2 = Thread.new
|
|
451
|
-
sleep 0.2
|
|
534
|
+
t2 = Thread.new{@db.synchronize{|c| c2 = c; q2.push nil}}
|
|
452
535
|
@db.pool.available_connections.should be_empty
|
|
453
536
|
c2.should be_nil
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
537
|
+
q1.push nil
|
|
538
|
+
q.pop
|
|
539
|
+
q2.pop
|
|
457
540
|
c2.should == 12345
|
|
541
|
+
t1.join
|
|
458
542
|
t2.join
|
|
459
543
|
end
|
|
460
544
|
end
|
|
@@ -464,7 +548,7 @@ describe "Database#test_connection" do
|
|
|
464
548
|
@db = Sequel::Database.new{@test = rand(100)}
|
|
465
549
|
end
|
|
466
550
|
|
|
467
|
-
specify "should
|
|
551
|
+
specify "should attempt to get a connection" do
|
|
468
552
|
@db.test_connection
|
|
469
553
|
@test.should_not be_nil
|
|
470
554
|
end
|
|
@@ -480,30 +564,21 @@ end
|
|
|
480
564
|
|
|
481
565
|
describe "Database#table_exists?" do
|
|
482
566
|
specify "should try to select the first record from the table's dataset" do
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
end
|
|
488
|
-
|
|
489
|
-
class Dummy3Database < Sequel::Database
|
|
490
|
-
attr_reader :sql, :transactions
|
|
491
|
-
def execute(sql, opts={}); @sql ||= []; @sql << sql; end
|
|
492
|
-
|
|
493
|
-
class DummyConnection
|
|
494
|
-
def initialize(db); @db = db; end
|
|
495
|
-
def execute(sql); @db.execute(sql); end
|
|
567
|
+
db = Sequel.mock(:fetch=>[Sequel::Error, [], [{:a=>1}]])
|
|
568
|
+
db.table_exists?(:a).should be_false
|
|
569
|
+
db.table_exists?(:b).should be_true
|
|
570
|
+
db.table_exists?(:c).should be_true
|
|
496
571
|
end
|
|
497
572
|
end
|
|
498
573
|
|
|
499
574
|
describe "Database#transaction" do
|
|
500
575
|
before do
|
|
501
|
-
@db =
|
|
576
|
+
@db = Sequel.mock(:servers=>{:test=>{}})
|
|
502
577
|
end
|
|
503
578
|
|
|
504
579
|
specify "should wrap the supplied block with BEGIN + COMMIT statements" do
|
|
505
580
|
@db.transaction{@db.execute 'DROP TABLE test;'}
|
|
506
|
-
@db.
|
|
581
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
|
507
582
|
end
|
|
508
583
|
|
|
509
584
|
specify "should support transaction isolation levels" do
|
|
@@ -511,7 +586,7 @@ describe "Database#transaction" do
|
|
|
511
586
|
[:uncommitted, :committed, :repeatable, :serializable].each do |l|
|
|
512
587
|
@db.transaction(:isolation=>l){@db.run "DROP TABLE #{l}"}
|
|
513
588
|
end
|
|
514
|
-
@db.
|
|
589
|
+
@db.sqls.should == ['BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', 'DROP TABLE uncommitted', 'COMMIT',
|
|
515
590
|
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', 'DROP TABLE committed', 'COMMIT',
|
|
516
591
|
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ', 'DROP TABLE repeatable', 'COMMIT',
|
|
517
592
|
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', 'DROP TABLE serializable', 'COMMIT']
|
|
@@ -523,7 +598,7 @@ describe "Database#transaction" do
|
|
|
523
598
|
@db.transaction_isolation_level = l
|
|
524
599
|
@db.transaction{@db.run "DROP TABLE #{l}"}
|
|
525
600
|
end
|
|
526
|
-
@db.
|
|
601
|
+
@db.sqls.should == ['BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED', 'DROP TABLE uncommitted', 'COMMIT',
|
|
527
602
|
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL READ COMMITTED', 'DROP TABLE committed', 'COMMIT',
|
|
528
603
|
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ', 'DROP TABLE repeatable', 'COMMIT',
|
|
529
604
|
'BEGIN', 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE', 'DROP TABLE serializable', 'COMMIT']
|
|
@@ -538,12 +613,12 @@ describe "Database#transaction" do
|
|
|
538
613
|
end
|
|
539
614
|
end
|
|
540
615
|
@db.ret_commit
|
|
541
|
-
@db.
|
|
616
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
|
542
617
|
end
|
|
543
618
|
|
|
544
619
|
specify "should issue ROLLBACK if an exception is raised, and re-raise" do
|
|
545
620
|
@db.transaction {@db.execute 'DROP TABLE test'; raise RuntimeError} rescue nil
|
|
546
|
-
@db.
|
|
621
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
|
|
547
622
|
|
|
548
623
|
proc {@db.transaction {raise RuntimeError}}.should raise_error(RuntimeError)
|
|
549
624
|
end
|
|
@@ -555,7 +630,50 @@ describe "Database#transaction" do
|
|
|
555
630
|
@db.drop_table(:b)
|
|
556
631
|
end
|
|
557
632
|
|
|
558
|
-
@db.
|
|
633
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE a', 'ROLLBACK']
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
specify "should have in_transaction? return true if inside a transaction" do
|
|
637
|
+
c = nil
|
|
638
|
+
@db.transaction{c = @db.in_transaction?}
|
|
639
|
+
c.should be_true
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
specify "should have in_transaction? handle sharding correctly" do
|
|
643
|
+
c = []
|
|
644
|
+
@db.transaction(:server=>:test){c << @db.in_transaction?}
|
|
645
|
+
@db.transaction(:server=>:test){c << @db.in_transaction?(:server=>:test)}
|
|
646
|
+
c.should == [false, true]
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
specify "should have in_transaction? return false if not in a transaction" do
|
|
650
|
+
@db.in_transaction?.should be_false
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
specify "should return nil if Sequel::Rollback is called in the transaction" do
|
|
654
|
+
@db.transaction{raise Sequel::Rollback}.should be_nil
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
specify "should reraise Sequel::Rollback errors when using :rollback=>:reraise option is given" do
|
|
658
|
+
proc {@db.transaction(:rollback=>:reraise){raise Sequel::Rollback}}.should raise_error(Sequel::Rollback)
|
|
659
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
|
660
|
+
proc {@db.transaction(:rollback=>:reraise){raise ArgumentError}}.should raise_error(ArgumentError)
|
|
661
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
|
662
|
+
@db.transaction(:rollback=>:reraise){1}.should == 1
|
|
663
|
+
@db.sqls.should == ['BEGIN', 'COMMIT']
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
specify "should always rollback if :rollback=>:always option is given" do
|
|
667
|
+
proc {@db.transaction(:rollback=>:always){raise ArgumentError}}.should raise_error(ArgumentError)
|
|
668
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
|
669
|
+
@db.transaction(:rollback=>:always){raise Sequel::Rollback}.should be_nil
|
|
670
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
|
671
|
+
@db.transaction(:rollback=>:always){1}.should be_nil
|
|
672
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
|
673
|
+
catch (:foo) do
|
|
674
|
+
@db.transaction(:rollback=>:always){throw :foo}
|
|
675
|
+
end
|
|
676
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
|
559
677
|
end
|
|
560
678
|
|
|
561
679
|
specify "should raise database errors when commiting a transaction as Sequel::DatabaseError" do
|
|
@@ -567,22 +685,36 @@ describe "Database#transaction" do
|
|
|
567
685
|
end
|
|
568
686
|
|
|
569
687
|
specify "should be re-entrant" do
|
|
570
|
-
|
|
688
|
+
q, q1 = Queue.new, Queue.new
|
|
571
689
|
cc = nil
|
|
572
690
|
t = Thread.new do
|
|
573
691
|
@db.transaction {@db.transaction {@db.transaction {|c|
|
|
574
692
|
cc = c
|
|
575
|
-
|
|
693
|
+
q.pop
|
|
694
|
+
q1.push nil
|
|
695
|
+
q.pop
|
|
576
696
|
}}}
|
|
577
697
|
end
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
698
|
+
q.push nil
|
|
699
|
+
q1.pop
|
|
700
|
+
cc.should be_a_kind_of(Sequel::Mock::Connection)
|
|
701
|
+
tr = @db.instance_variable_get(:@transactions)
|
|
702
|
+
tr.should == {cc=>{:savepoint_level=>1}}
|
|
703
|
+
q.push nil
|
|
582
704
|
t.join
|
|
583
|
-
|
|
705
|
+
tr.should be_empty
|
|
584
706
|
end
|
|
585
707
|
|
|
708
|
+
specify "should correctly handle nested transacation use with separate shards" do
|
|
709
|
+
@db.transaction do |c1|
|
|
710
|
+
@db.transaction(:server=>:test) do |c2|
|
|
711
|
+
c1.should_not == c2
|
|
712
|
+
@db.execute 'DROP TABLE test;'
|
|
713
|
+
end
|
|
714
|
+
end
|
|
715
|
+
@db.sqls.should == ['BEGIN', 'BEGIN -- test', 'DROP TABLE test;', 'COMMIT -- test', 'COMMIT']
|
|
716
|
+
end
|
|
717
|
+
|
|
586
718
|
if (!defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby' or RUBY_ENGINE == 'rbx') and RUBY_VERSION < '1.9'
|
|
587
719
|
specify "should handle Thread#kill for transactions inside threads" do
|
|
588
720
|
q = Queue.new
|
|
@@ -598,35 +730,173 @@ describe "Database#transaction" do
|
|
|
598
730
|
q1.pop
|
|
599
731
|
t.kill
|
|
600
732
|
t.join
|
|
601
|
-
@db.
|
|
733
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
|
|
602
734
|
end
|
|
603
735
|
end
|
|
736
|
+
|
|
737
|
+
specify "should raise an Error if after_commit or after_rollback is called without a block" do
|
|
738
|
+
proc{@db.after_commit}.should raise_error(Sequel::Error)
|
|
739
|
+
proc{@db.after_rollback}.should raise_error(Sequel::Error)
|
|
740
|
+
end
|
|
741
|
+
|
|
742
|
+
specify "should execute after_commit outside transactions" do
|
|
743
|
+
@db.after_commit{@db.execute('foo')}
|
|
744
|
+
@db.sqls.should == ['foo']
|
|
745
|
+
end
|
|
746
|
+
|
|
747
|
+
specify "should ignore after_rollback outside transactions" do
|
|
748
|
+
@db.after_rollback{@db.execute('foo')}
|
|
749
|
+
@db.sqls.should == []
|
|
750
|
+
end
|
|
751
|
+
|
|
752
|
+
specify "should support after_commit inside transactions" do
|
|
753
|
+
@db.transaction{@db.after_commit{@db.execute('foo')}}
|
|
754
|
+
@db.sqls.should == ['BEGIN', 'COMMIT', 'foo']
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
specify "should support after_rollback inside transactions" do
|
|
758
|
+
@db.transaction{@db.after_rollback{@db.execute('foo')}}
|
|
759
|
+
@db.sqls.should == ['BEGIN', 'COMMIT']
|
|
760
|
+
end
|
|
761
|
+
|
|
762
|
+
specify "should not call after_commit if the transaction rolls back" do
|
|
763
|
+
@db.transaction{@db.after_commit{@db.execute('foo')}; raise Sequel::Rollback}
|
|
764
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
specify "should call after_rollback if the transaction rolls back" do
|
|
768
|
+
@db.transaction{@db.after_rollback{@db.execute('foo')}; raise Sequel::Rollback}
|
|
769
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK', 'foo']
|
|
770
|
+
end
|
|
771
|
+
|
|
772
|
+
specify "should call multiple after_commit blocks in order if called inside transactions" do
|
|
773
|
+
@db.transaction{@db.after_commit{@db.execute('foo')}; @db.after_commit{@db.execute('bar')}}
|
|
774
|
+
@db.sqls.should == ['BEGIN', 'COMMIT', 'foo', 'bar']
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
specify "should call multiple after_rollback blocks in order if called inside transactions" do
|
|
778
|
+
@db.transaction{@db.after_rollback{@db.execute('foo')}; @db.after_rollback{@db.execute('bar')}; raise Sequel::Rollback}
|
|
779
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK', 'foo', 'bar']
|
|
780
|
+
end
|
|
781
|
+
|
|
782
|
+
specify "should support after_commit inside nested transactions" do
|
|
783
|
+
@db.transaction{@db.transaction{@db.after_commit{@db.execute('foo')}}}
|
|
784
|
+
@db.sqls.should == ['BEGIN', 'COMMIT', 'foo']
|
|
785
|
+
end
|
|
786
|
+
|
|
787
|
+
specify "should support after_rollback inside nested transactions" do
|
|
788
|
+
@db.transaction{@db.transaction{@db.after_rollback{@db.execute('foo')}}; raise Sequel::Rollback}
|
|
789
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK', 'foo']
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
specify "should support after_commit inside savepoints" do
|
|
793
|
+
@db.meta_def(:supports_savepoints?){true}
|
|
794
|
+
@db.transaction do
|
|
795
|
+
@db.after_commit{@db.execute('foo')}
|
|
796
|
+
@db.transaction(:savepoint=>true){@db.after_commit{@db.execute('bar')}}
|
|
797
|
+
@db.after_commit{@db.execute('baz')}
|
|
798
|
+
end
|
|
799
|
+
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT', 'foo', 'bar', 'baz']
|
|
800
|
+
end
|
|
801
|
+
|
|
802
|
+
specify "should support after_rollback inside savepoints" do
|
|
803
|
+
@db.meta_def(:supports_savepoints?){true}
|
|
804
|
+
@db.transaction do
|
|
805
|
+
@db.after_rollback{@db.execute('foo')}
|
|
806
|
+
@db.transaction(:savepoint=>true){@db.after_rollback{@db.execute('bar')}}
|
|
807
|
+
@db.after_rollback{@db.execute('baz')}
|
|
808
|
+
raise Sequel::Rollback
|
|
809
|
+
end
|
|
810
|
+
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1', 'RELEASE SAVEPOINT autopoint_1', 'ROLLBACK', 'foo', 'bar', 'baz']
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
specify "should raise an error if you attempt to use after_commit inside a prepared transaction" do
|
|
814
|
+
@db.meta_def(:supports_prepared_transactions?){true}
|
|
815
|
+
proc{@db.transaction(:prepare=>'XYZ'){@db.after_commit{@db.execute('foo')}}}.should raise_error(Sequel::Error)
|
|
816
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
|
817
|
+
end
|
|
818
|
+
|
|
819
|
+
specify "should raise an error if you attempt to use after_rollback inside a prepared transaction" do
|
|
820
|
+
@db.meta_def(:supports_prepared_transactions?){true}
|
|
821
|
+
proc{@db.transaction(:prepare=>'XYZ'){@db.after_rollback{@db.execute('foo')}}}.should raise_error(Sequel::Error)
|
|
822
|
+
@db.sqls.should == ['BEGIN', 'ROLLBACK']
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
specify "should raise an error if you attempt to use after_commit inside a savepoint in a prepared transaction" do
|
|
826
|
+
@db.meta_def(:supports_savepoints?){true}
|
|
827
|
+
@db.meta_def(:supports_prepared_transactions?){true}
|
|
828
|
+
proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_commit{@db.execute('foo')}}}}.should raise_error(Sequel::Error)
|
|
829
|
+
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1','ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
|
|
830
|
+
end
|
|
831
|
+
|
|
832
|
+
specify "should raise an error if you attempt to use after_rollback inside a savepoint in a prepared transaction" do
|
|
833
|
+
@db.meta_def(:supports_savepoints?){true}
|
|
834
|
+
@db.meta_def(:supports_prepared_transactions?){true}
|
|
835
|
+
proc{@db.transaction(:prepare=>'XYZ'){@db.transaction(:savepoint=>true){@db.after_rollback{@db.execute('foo')}}}}.should raise_error(Sequel::Error)
|
|
836
|
+
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1','ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
|
|
837
|
+
end
|
|
604
838
|
end
|
|
605
839
|
|
|
840
|
+
describe "Sequel.transaction" do
|
|
841
|
+
before do
|
|
842
|
+
@sqls = []
|
|
843
|
+
@db1 = Sequel.mock(:append=>'1', :sqls=>@sqls)
|
|
844
|
+
@db2 = Sequel.mock(:append=>'2', :sqls=>@sqls)
|
|
845
|
+
@db3 = Sequel.mock(:append=>'3', :sqls=>@sqls)
|
|
846
|
+
end
|
|
847
|
+
|
|
848
|
+
specify "should run the block inside transacitons on all three databases" do
|
|
849
|
+
Sequel.transaction([@db1, @db2, @db3]){1}.should == 1
|
|
850
|
+
@sqls.should == ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'COMMIT -- 3', 'COMMIT -- 2', 'COMMIT -- 1']
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
specify "should pass options to all the blocks" do
|
|
854
|
+
Sequel.transaction([@db1, @db2, @db3], :rollback=>:always){1}.should be_nil
|
|
855
|
+
@sqls.should == ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'ROLLBACK -- 3', 'ROLLBACK -- 2', 'ROLLBACK -- 1']
|
|
856
|
+
end
|
|
857
|
+
|
|
858
|
+
specify "should handle Sequel::Rollback exceptions raised by the block to rollback on all databases" do
|
|
859
|
+
Sequel.transaction([@db1, @db2, @db3]){raise Sequel::Rollback}.should be_nil
|
|
860
|
+
@sqls.should == ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'ROLLBACK -- 3', 'ROLLBACK -- 2', 'ROLLBACK -- 1']
|
|
861
|
+
end
|
|
862
|
+
|
|
863
|
+
specify "should handle nested transactions" do
|
|
864
|
+
Sequel.transaction([@db1, @db2, @db3]){Sequel.transaction([@db1, @db2, @db3]){1}}.should == 1
|
|
865
|
+
@sqls.should == ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3', 'COMMIT -- 3', 'COMMIT -- 2', 'COMMIT -- 1']
|
|
866
|
+
end
|
|
867
|
+
|
|
868
|
+
specify "should handle savepoints" do
|
|
869
|
+
Sequel.transaction([@db1, @db2, @db3]){Sequel.transaction([@db1, @db2, @db3], :savepoint=>true){1}}.should == 1
|
|
870
|
+
@sqls.should == ['BEGIN -- 1', 'BEGIN -- 2', 'BEGIN -- 3',
|
|
871
|
+
'SAVEPOINT autopoint_1 -- 1', 'SAVEPOINT autopoint_1 -- 2', 'SAVEPOINT autopoint_1 -- 3',
|
|
872
|
+
'RELEASE SAVEPOINT autopoint_1 -- 3', 'RELEASE SAVEPOINT autopoint_1 -- 2', 'RELEASE SAVEPOINT autopoint_1 -- 1',
|
|
873
|
+
'COMMIT -- 3', 'COMMIT -- 2', 'COMMIT -- 1']
|
|
874
|
+
end
|
|
875
|
+
end
|
|
876
|
+
|
|
606
877
|
describe "Database#transaction with savepoints" do
|
|
607
878
|
before do
|
|
608
|
-
@db =
|
|
609
|
-
@db.meta_def(:supports_savepoints?){true}
|
|
879
|
+
@db = Sequel.mock
|
|
610
880
|
end
|
|
611
881
|
|
|
612
882
|
specify "should wrap the supplied block with BEGIN + COMMIT statements" do
|
|
613
883
|
@db.transaction {@db.execute 'DROP TABLE test;'}
|
|
614
|
-
@db.
|
|
884
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
|
615
885
|
end
|
|
616
886
|
|
|
617
887
|
specify "should use savepoints if given the :savepoint option" do
|
|
618
888
|
@db.transaction{@db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test;'}}
|
|
619
|
-
@db.
|
|
889
|
+
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
|
620
890
|
end
|
|
621
891
|
|
|
622
892
|
specify "should not use a savepoints if no transaction is in progress" do
|
|
623
893
|
@db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test;'}
|
|
624
|
-
@db.
|
|
894
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
|
625
895
|
end
|
|
626
896
|
|
|
627
897
|
specify "should reuse the current transaction if no :savepoint option is given" do
|
|
628
898
|
@db.transaction{@db.transaction{@db.execute 'DROP TABLE test;'}}
|
|
629
|
-
@db.
|
|
899
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
|
630
900
|
end
|
|
631
901
|
|
|
632
902
|
specify "should handle returning inside of the block by committing" do
|
|
@@ -638,7 +908,7 @@ describe "Database#transaction with savepoints" do
|
|
|
638
908
|
end
|
|
639
909
|
end
|
|
640
910
|
@db.ret_commit
|
|
641
|
-
@db.
|
|
911
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE test;', 'COMMIT']
|
|
642
912
|
end
|
|
643
913
|
|
|
644
914
|
specify "should handle returning inside of a savepoint by committing" do
|
|
@@ -652,34 +922,34 @@ describe "Database#transaction with savepoints" do
|
|
|
652
922
|
end
|
|
653
923
|
end
|
|
654
924
|
@db.ret_commit
|
|
655
|
-
@db.
|
|
925
|
+
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test;', 'RELEASE SAVEPOINT autopoint_1', 'COMMIT']
|
|
656
926
|
end
|
|
657
927
|
|
|
658
928
|
specify "should issue ROLLBACK if an exception is raised, and re-raise" do
|
|
659
929
|
@db.transaction {@db.execute 'DROP TABLE test'; raise RuntimeError} rescue nil
|
|
660
|
-
@db.
|
|
930
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE test', 'ROLLBACK']
|
|
661
931
|
|
|
662
932
|
proc {@db.transaction {raise RuntimeError}}.should raise_error(RuntimeError)
|
|
663
933
|
end
|
|
664
934
|
|
|
665
935
|
specify "should issue ROLLBACK SAVEPOINT if an exception is raised inside a savepoint, and re-raise" do
|
|
666
936
|
@db.transaction{@db.transaction(:savepoint=>true){@db.execute 'DROP TABLE test'; raise RuntimeError}} rescue nil
|
|
667
|
-
@db.
|
|
937
|
+
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE test', 'ROLLBACK TO SAVEPOINT autopoint_1', 'ROLLBACK']
|
|
668
938
|
|
|
669
939
|
proc {@db.transaction {raise RuntimeError}}.should raise_error(RuntimeError)
|
|
670
940
|
end
|
|
671
941
|
|
|
672
|
-
specify "should issue ROLLBACK if Sequel::Rollback is
|
|
942
|
+
specify "should issue ROLLBACK if Sequel::Rollback is raised in the transaction" do
|
|
673
943
|
@db.transaction do
|
|
674
944
|
@db.drop_table(:a)
|
|
675
945
|
raise Sequel::Rollback
|
|
676
946
|
@db.drop_table(:b)
|
|
677
947
|
end
|
|
678
948
|
|
|
679
|
-
@db.
|
|
949
|
+
@db.sqls.should == ['BEGIN', 'DROP TABLE a', 'ROLLBACK']
|
|
680
950
|
end
|
|
681
951
|
|
|
682
|
-
specify "should issue ROLLBACK SAVEPOINT if Sequel::Rollback is
|
|
952
|
+
specify "should issue ROLLBACK SAVEPOINT if Sequel::Rollback is raised in a savepoint" do
|
|
683
953
|
@db.transaction do
|
|
684
954
|
@db.transaction(:savepoint=>true) do
|
|
685
955
|
@db.drop_table(:a)
|
|
@@ -688,7 +958,7 @@ describe "Database#transaction with savepoints" do
|
|
|
688
958
|
@db.drop_table(:b)
|
|
689
959
|
end
|
|
690
960
|
|
|
691
|
-
@db.
|
|
961
|
+
@db.sqls.should == ['BEGIN', 'SAVEPOINT autopoint_1', 'DROP TABLE a', 'ROLLBACK TO SAVEPOINT autopoint_1', 'DROP TABLE b', 'COMMIT']
|
|
692
962
|
end
|
|
693
963
|
|
|
694
964
|
specify "should raise database errors when commiting a transaction as Sequel::DatabaseError" do
|
|
@@ -704,37 +974,28 @@ end
|
|
|
704
974
|
|
|
705
975
|
describe "A Database adapter with a scheme" do
|
|
706
976
|
before do
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
DISCONNECTS.clear
|
|
710
|
-
else
|
|
711
|
-
DISCONNECTS = []
|
|
712
|
-
end
|
|
713
|
-
set_adapter_scheme :ccc
|
|
714
|
-
def disconnect
|
|
715
|
-
DISCONNECTS << self
|
|
716
|
-
end
|
|
717
|
-
end
|
|
977
|
+
@ccc = Class.new(Sequel::Database)
|
|
978
|
+
@ccc.send(:set_adapter_scheme, :ccc)
|
|
718
979
|
end
|
|
719
980
|
|
|
720
981
|
specify "should be registered in the ADAPTER_MAP" do
|
|
721
|
-
Sequel::ADAPTER_MAP[:ccc].should ==
|
|
982
|
+
Sequel::ADAPTER_MAP[:ccc].should == @ccc
|
|
722
983
|
end
|
|
723
984
|
|
|
724
985
|
specify "should give the database_type as the adapter scheme by default" do
|
|
725
|
-
|
|
986
|
+
@ccc.new.database_type.should == :ccc
|
|
726
987
|
end
|
|
727
988
|
|
|
728
989
|
specify "should be instantiated when its scheme is specified" do
|
|
729
990
|
c = Sequel::Database.connect('ccc://localhost/db')
|
|
730
|
-
c.should be_a_kind_of(
|
|
991
|
+
c.should be_a_kind_of(@ccc)
|
|
731
992
|
c.opts[:host].should == 'localhost'
|
|
732
993
|
c.opts[:database].should == 'db'
|
|
733
994
|
end
|
|
734
995
|
|
|
735
996
|
specify "should be accessible through Sequel.connect" do
|
|
736
997
|
c = Sequel.connect 'ccc://localhost/db'
|
|
737
|
-
c.should be_a_kind_of(
|
|
998
|
+
c.should be_a_kind_of(@ccc)
|
|
738
999
|
c.opts[:host].should == 'localhost'
|
|
739
1000
|
c.opts[:database].should == 'db'
|
|
740
1001
|
end
|
|
@@ -746,7 +1007,7 @@ describe "A Database adapter with a scheme" do
|
|
|
746
1007
|
returnValue = 'anything'
|
|
747
1008
|
|
|
748
1009
|
p = proc do |c|
|
|
749
|
-
c.should be_a_kind_of(
|
|
1010
|
+
c.should be_a_kind_of(@ccc)
|
|
750
1011
|
c.opts[:host].should == 'localhost'
|
|
751
1012
|
c.opts[:database].should == 'db'
|
|
752
1013
|
z = y
|
|
@@ -754,15 +1015,22 @@ describe "A Database adapter with a scheme" do
|
|
|
754
1015
|
x = c
|
|
755
1016
|
returnValue
|
|
756
1017
|
end
|
|
1018
|
+
|
|
1019
|
+
@ccc.class_eval do
|
|
1020
|
+
self::DISCONNECTS = []
|
|
1021
|
+
def disconnect
|
|
1022
|
+
self.class::DISCONNECTS << self
|
|
1023
|
+
end
|
|
1024
|
+
end
|
|
757
1025
|
Sequel::Database.connect('ccc://localhost/db', &p).should == returnValue
|
|
758
|
-
|
|
1026
|
+
@ccc::DISCONNECTS.should == [x]
|
|
759
1027
|
|
|
760
1028
|
Sequel.connect('ccc://localhost/db', &p).should == returnValue
|
|
761
|
-
|
|
1029
|
+
@ccc::DISCONNECTS.should == [y, x]
|
|
762
1030
|
|
|
763
1031
|
Sequel.send(:def_adapter_method, :ccc)
|
|
764
1032
|
Sequel.ccc('db', :host=>'localhost', &p).should == returnValue
|
|
765
|
-
|
|
1033
|
+
@ccc::DISCONNECTS.should == [z, y, x]
|
|
766
1034
|
end
|
|
767
1035
|
|
|
768
1036
|
specify "should be accessible through Sequel.<adapter>" do
|
|
@@ -773,31 +1041,31 @@ describe "A Database adapter with a scheme" do
|
|
|
773
1041
|
|
|
774
1042
|
c = Sequel.ccc('mydb')
|
|
775
1043
|
p = proc{c.opts.delete_if{|k,v| k == :disconnection_proc || k == :single_threaded}}
|
|
776
|
-
c.should be_a_kind_of(
|
|
777
|
-
p.call.should == {:adapter=>:ccc, :database => 'mydb', :adapter_class
|
|
1044
|
+
c.should be_a_kind_of(@ccc)
|
|
1045
|
+
p.call.should == {:adapter=>:ccc, :database => 'mydb', :adapter_class=>@ccc}
|
|
778
1046
|
|
|
779
1047
|
c = Sequel.ccc('mydb', :host => 'localhost')
|
|
780
|
-
c.should be_a_kind_of(
|
|
781
|
-
p.call.should == {:adapter=>:ccc, :database => 'mydb', :host => 'localhost', :adapter_class
|
|
1048
|
+
c.should be_a_kind_of(@ccc)
|
|
1049
|
+
p.call.should == {:adapter=>:ccc, :database => 'mydb', :host => 'localhost', :adapter_class=>@ccc}
|
|
782
1050
|
|
|
783
1051
|
c = Sequel.ccc
|
|
784
|
-
c.should be_a_kind_of(
|
|
785
|
-
p.call.should == {:adapter=>:ccc, :adapter_class
|
|
1052
|
+
c.should be_a_kind_of(@ccc)
|
|
1053
|
+
p.call.should == {:adapter=>:ccc, :adapter_class=>@ccc}
|
|
786
1054
|
|
|
787
1055
|
c = Sequel.ccc(:database => 'mydb', :host => 'localhost')
|
|
788
|
-
c.should be_a_kind_of(
|
|
789
|
-
p.call.should == {:adapter=>:ccc, :database => 'mydb', :host => 'localhost', :adapter_class
|
|
1056
|
+
c.should be_a_kind_of(@ccc)
|
|
1057
|
+
p.call.should == {:adapter=>:ccc, :database => 'mydb', :host => 'localhost', :adapter_class=>@ccc}
|
|
790
1058
|
end
|
|
791
1059
|
|
|
792
1060
|
specify "should be accessible through Sequel.connect with options" do
|
|
793
1061
|
c = Sequel.connect(:adapter => :ccc, :database => 'mydb')
|
|
794
|
-
c.should be_a_kind_of(
|
|
1062
|
+
c.should be_a_kind_of(@ccc)
|
|
795
1063
|
c.opts[:adapter].should == :ccc
|
|
796
1064
|
end
|
|
797
1065
|
|
|
798
1066
|
specify "should be accessible through Sequel.connect with URL parameters" do
|
|
799
1067
|
c = Sequel.connect 'ccc:///db?host=/tmp&user=test'
|
|
800
|
-
c.should be_a_kind_of(
|
|
1068
|
+
c.should be_a_kind_of(@ccc)
|
|
801
1069
|
c.opts[:host].should == '/tmp'
|
|
802
1070
|
c.opts[:database].should == 'db'
|
|
803
1071
|
c.opts[:user].should == 'test'
|
|
@@ -805,14 +1073,14 @@ describe "A Database adapter with a scheme" do
|
|
|
805
1073
|
|
|
806
1074
|
specify "should have URL parameters take precedence over fixed URL parts" do
|
|
807
1075
|
c = Sequel.connect 'ccc://localhost/db?host=a&database=b'
|
|
808
|
-
c.should be_a_kind_of(
|
|
1076
|
+
c.should be_a_kind_of(@ccc)
|
|
809
1077
|
c.opts[:host].should == 'a'
|
|
810
1078
|
c.opts[:database].should == 'b'
|
|
811
1079
|
end
|
|
812
1080
|
|
|
813
1081
|
specify "should have hash options take predence over URL parameters or parts" do
|
|
814
1082
|
c = Sequel.connect 'ccc://localhost/db?host=/tmp', :host=>'a', :database=>'b', :user=>'c'
|
|
815
|
-
c.should be_a_kind_of(
|
|
1083
|
+
c.should be_a_kind_of(@ccc)
|
|
816
1084
|
c.opts[:host].should == 'a'
|
|
817
1085
|
c.opts[:database].should == 'b'
|
|
818
1086
|
c.opts[:user].should == 'c'
|
|
@@ -820,7 +1088,7 @@ describe "A Database adapter with a scheme" do
|
|
|
820
1088
|
|
|
821
1089
|
specify "should unescape values of URL parameters and parts" do
|
|
822
1090
|
c = Sequel.connect 'ccc:///d%5bb%5d?host=domain%5cinstance'
|
|
823
|
-
c.should be_a_kind_of(
|
|
1091
|
+
c.should be_a_kind_of(@ccc)
|
|
824
1092
|
c.opts[:database].should == 'd[b]'
|
|
825
1093
|
c.opts[:host].should == 'domain\\instance'
|
|
826
1094
|
end
|
|
@@ -935,10 +1203,6 @@ describe "A single threaded database" do
|
|
|
935
1203
|
end
|
|
936
1204
|
|
|
937
1205
|
describe "A database" do
|
|
938
|
-
before do
|
|
939
|
-
Sequel::Database.single_threaded = false
|
|
940
|
-
end
|
|
941
|
-
|
|
942
1206
|
after do
|
|
943
1207
|
Sequel::Database.single_threaded = false
|
|
944
1208
|
end
|
|
@@ -983,11 +1247,7 @@ end
|
|
|
983
1247
|
|
|
984
1248
|
describe "Database#fetch" do
|
|
985
1249
|
before do
|
|
986
|
-
@db = Sequel
|
|
987
|
-
c = Class.new(Sequel::Dataset) do
|
|
988
|
-
def fetch_rows(sql); yield({:sql => sql}); end
|
|
989
|
-
end
|
|
990
|
-
@db.meta_def(:dataset) {c.new(self)}
|
|
1250
|
+
@db = Sequel.mock(:fetch=>proc{|sql| {:sql => sql}})
|
|
991
1251
|
end
|
|
992
1252
|
|
|
993
1253
|
specify "should create a dataset and invoke its fetch_rows method with the given sql" do
|
|
@@ -1034,21 +1294,17 @@ end
|
|
|
1034
1294
|
|
|
1035
1295
|
describe "Database#[]" do
|
|
1036
1296
|
before do
|
|
1037
|
-
@db = Sequel
|
|
1297
|
+
@db = Sequel.mock
|
|
1038
1298
|
end
|
|
1039
1299
|
|
|
1040
1300
|
specify "should return a dataset when symbols are given" do
|
|
1041
1301
|
ds = @db[:items]
|
|
1042
|
-
ds.
|
|
1302
|
+
ds.should be_a_kind_of(Sequel::Dataset)
|
|
1043
1303
|
ds.opts[:from].should == [:items]
|
|
1044
1304
|
end
|
|
1045
1305
|
|
|
1046
1306
|
specify "should return a dataset when a string is given" do
|
|
1047
|
-
|
|
1048
|
-
def fetch_rows(sql); yield({:sql => sql}); end
|
|
1049
|
-
end
|
|
1050
|
-
@db.meta_def(:dataset) {c.new(self)}
|
|
1051
|
-
|
|
1307
|
+
@db.fetch = proc{|sql| {:sql=>sql}}
|
|
1052
1308
|
sql = nil
|
|
1053
1309
|
@db['select * from xyz where x = ? and y = ?', 15, 'abc'].each {|r| sql = r[:sql]}
|
|
1054
1310
|
sql.should == "select * from xyz where x = 15 and y = 'abc'"
|
|
@@ -1056,53 +1312,36 @@ describe "Database#[]" do
|
|
|
1056
1312
|
end
|
|
1057
1313
|
|
|
1058
1314
|
describe "Database#inspect" do
|
|
1059
|
-
before do
|
|
1060
|
-
@db = DummyDatabase.new
|
|
1061
|
-
|
|
1062
|
-
@db.meta_def(:uri) {'blah://blahblah/blah'}
|
|
1063
|
-
end
|
|
1064
|
-
|
|
1065
1315
|
specify "should include the class name and the connection url" do
|
|
1066
|
-
|
|
1316
|
+
Sequel.connect('mock://foo/bar').inspect.should == '#<Sequel::Mock::Database: "mock://foo/bar">'
|
|
1067
1317
|
end
|
|
1068
1318
|
end
|
|
1069
1319
|
|
|
1070
1320
|
describe "Database#get" do
|
|
1071
1321
|
before do
|
|
1072
|
-
@
|
|
1073
|
-
def dataset
|
|
1074
|
-
ds = super
|
|
1075
|
-
def ds.get(*args, &block)
|
|
1076
|
-
@db.execute select(*args, &block).sql
|
|
1077
|
-
args
|
|
1078
|
-
end
|
|
1079
|
-
ds
|
|
1080
|
-
end
|
|
1081
|
-
end
|
|
1082
|
-
|
|
1083
|
-
@db = @c.new
|
|
1322
|
+
@db = Sequel.mock(:fetch=>{:a=>1})
|
|
1084
1323
|
end
|
|
1085
1324
|
|
|
1086
1325
|
specify "should use Dataset#get to get a single value" do
|
|
1087
|
-
@db.get(1).should ==
|
|
1088
|
-
@db.sqls.
|
|
1326
|
+
@db.get(1).should == 1
|
|
1327
|
+
@db.sqls.should == ['SELECT 1 LIMIT 1']
|
|
1089
1328
|
|
|
1090
1329
|
@db.get(:version.sql_function)
|
|
1091
|
-
@db.sqls.
|
|
1330
|
+
@db.sqls.should == ['SELECT version() LIMIT 1']
|
|
1092
1331
|
end
|
|
1093
1332
|
|
|
1094
1333
|
specify "should accept a block" do
|
|
1095
1334
|
@db.get{1}
|
|
1096
|
-
@db.sqls.
|
|
1335
|
+
@db.sqls.should == ['SELECT 1 LIMIT 1']
|
|
1097
1336
|
|
|
1098
1337
|
@db.get{version(1)}
|
|
1099
|
-
@db.sqls.
|
|
1338
|
+
@db.sqls.should == ['SELECT version(1) LIMIT 1']
|
|
1100
1339
|
end
|
|
1101
1340
|
end
|
|
1102
1341
|
|
|
1103
1342
|
describe "Database#call" do
|
|
1104
1343
|
specify "should call the prepared statement with the given name" do
|
|
1105
|
-
db =
|
|
1344
|
+
db = Sequel.mock(:fetch=>{:id => 1, :x => 1})
|
|
1106
1345
|
db[:items].prepare(:select, :select_all)
|
|
1107
1346
|
db.call(:select_all).should == [{:id => 1, :x => 1}]
|
|
1108
1347
|
db[:items].filter(:n=>:$n).prepare(:select, :select_n)
|
|
@@ -1114,146 +1353,129 @@ end
|
|
|
1114
1353
|
describe "Database#server_opts" do
|
|
1115
1354
|
specify "should return the general opts if no :servers option is used" do
|
|
1116
1355
|
opts = {:host=>1, :database=>2}
|
|
1117
|
-
|
|
1356
|
+
Sequel::Database.new(opts).send(:server_opts, :server1)[:host].should == 1
|
|
1118
1357
|
end
|
|
1119
1358
|
|
|
1120
1359
|
specify "should return the general opts if entry for the server is present in the :servers option" do
|
|
1121
1360
|
opts = {:host=>1, :database=>2, :servers=>{}}
|
|
1122
|
-
|
|
1361
|
+
Sequel::Database.new(opts).send(:server_opts, :server1)[:host].should == 1
|
|
1123
1362
|
end
|
|
1124
1363
|
|
|
1125
1364
|
specify "should return the general opts merged with the specific opts if given as a hash" do
|
|
1126
1365
|
opts = {:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}}}
|
|
1127
|
-
|
|
1366
|
+
Sequel::Database.new(opts).send(:server_opts, :server1)[:host].should == 3
|
|
1128
1367
|
end
|
|
1129
1368
|
|
|
1130
1369
|
specify "should return the sgeneral opts merged with the specific opts if given as a proc" do
|
|
1131
1370
|
opts = {:host=>1, :database=>2, :servers=>{:server1=>proc{|db| {:host=>4}}}}
|
|
1132
|
-
|
|
1371
|
+
Sequel::Database.new(opts).send(:server_opts, :server1)[:host].should == 4
|
|
1133
1372
|
end
|
|
1134
1373
|
|
|
1135
1374
|
specify "should raise an error if the specific opts is not a proc or hash" do
|
|
1136
1375
|
opts = {:host=>1, :database=>2, :servers=>{:server1=>2}}
|
|
1137
|
-
proc{
|
|
1376
|
+
proc{Sequel::Database.new(opts).send(:server_opts, :server1)}.should raise_error(Sequel::Error)
|
|
1138
1377
|
end
|
|
1139
1378
|
end
|
|
1140
1379
|
|
|
1141
1380
|
describe "Database#add_servers" do
|
|
1142
1381
|
before do
|
|
1143
|
-
@db =
|
|
1144
|
-
def @db.connect(server)
|
|
1145
|
-
server_opts(server)
|
|
1146
|
-
end
|
|
1147
|
-
def @db.disconnect_connection(c)
|
|
1148
|
-
end
|
|
1382
|
+
@db = Sequel.mock(:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}})
|
|
1149
1383
|
end
|
|
1150
1384
|
|
|
1151
1385
|
specify "should add new servers to the connection pool" do
|
|
1152
|
-
@db.synchronize{|c| c[:host].should == 1}
|
|
1153
|
-
@db.synchronize(:server1){|c| c[:host].should == 3}
|
|
1154
|
-
@db.synchronize(:server2){|c| c[:host].should == 1}
|
|
1386
|
+
@db.synchronize{|c| c.opts[:host].should == 1}
|
|
1387
|
+
@db.synchronize(:server1){|c| c.opts[:host].should == 3}
|
|
1388
|
+
@db.synchronize(:server2){|c| c.opts[:host].should == 1}
|
|
1155
1389
|
|
|
1156
1390
|
@db.add_servers(:server2=>{:host=>6})
|
|
1157
|
-
@db.synchronize{|c| c[:host].should == 1}
|
|
1158
|
-
@db.synchronize(:server1){|c| c[:host].should == 3}
|
|
1159
|
-
@db.synchronize(:server2){|c| c[:host].should == 6}
|
|
1391
|
+
@db.synchronize{|c| c.opts[:host].should == 1}
|
|
1392
|
+
@db.synchronize(:server1){|c| c.opts[:host].should == 3}
|
|
1393
|
+
@db.synchronize(:server2){|c| c.opts[:host].should == 6}
|
|
1160
1394
|
|
|
1161
1395
|
@db.disconnect
|
|
1162
|
-
@db.synchronize{|c| c[:host].should == 1}
|
|
1163
|
-
@db.synchronize(:server1){|c| c[:host].should == 3}
|
|
1164
|
-
@db.synchronize(:server2){|c| c[:host].should == 6}
|
|
1396
|
+
@db.synchronize{|c| c.opts[:host].should == 1}
|
|
1397
|
+
@db.synchronize(:server1){|c| c.opts[:host].should == 3}
|
|
1398
|
+
@db.synchronize(:server2){|c| c.opts[:host].should == 6}
|
|
1165
1399
|
end
|
|
1166
1400
|
|
|
1167
1401
|
specify "should replace options for future connections to existing servers" do
|
|
1168
|
-
@db.synchronize{|c| c[:host].should == 1}
|
|
1169
|
-
@db.synchronize(:server1){|c| c[:host].should == 3}
|
|
1170
|
-
@db.synchronize(:server2){|c| c[:host].should == 1}
|
|
1402
|
+
@db.synchronize{|c| c.opts[:host].should == 1}
|
|
1403
|
+
@db.synchronize(:server1){|c| c.opts[:host].should == 3}
|
|
1404
|
+
@db.synchronize(:server2){|c| c.opts[:host].should == 1}
|
|
1171
1405
|
|
|
1172
1406
|
@db.add_servers(:default=>proc{{:host=>4}}, :server1=>{:host=>8})
|
|
1173
|
-
@db.synchronize{|c| c[:host].should == 1}
|
|
1174
|
-
@db.synchronize(:server1){|c| c[:host].should == 3}
|
|
1175
|
-
@db.synchronize(:server2){|c| c[:host].should == 1}
|
|
1407
|
+
@db.synchronize{|c| c.opts[:host].should == 1}
|
|
1408
|
+
@db.synchronize(:server1){|c| c.opts[:host].should == 3}
|
|
1409
|
+
@db.synchronize(:server2){|c| c.opts[:host].should == 1}
|
|
1176
1410
|
|
|
1177
1411
|
@db.disconnect
|
|
1178
|
-
@db.synchronize{|c| c[:host].should == 4}
|
|
1179
|
-
@db.synchronize(:server1){|c| c[:host].should == 8}
|
|
1180
|
-
@db.synchronize(:server2){|c| c[:host].should == 4}
|
|
1412
|
+
@db.synchronize{|c| c.opts[:host].should == 4}
|
|
1413
|
+
@db.synchronize(:server1){|c| c.opts[:host].should == 8}
|
|
1414
|
+
@db.synchronize(:server2){|c| c.opts[:host].should == 4}
|
|
1181
1415
|
end
|
|
1182
1416
|
end
|
|
1183
1417
|
|
|
1184
1418
|
describe "Database#remove_servers" do
|
|
1185
1419
|
before do
|
|
1186
|
-
@db =
|
|
1187
|
-
def @db.connect(server)
|
|
1188
|
-
server_opts(server)
|
|
1189
|
-
end
|
|
1190
|
-
def @db.disconnect_connection(c)
|
|
1191
|
-
end
|
|
1420
|
+
@db = Sequel.mock(:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}, :server2=>{:host=>4}})
|
|
1192
1421
|
end
|
|
1193
1422
|
|
|
1194
1423
|
specify "should remove servers from the connection pool" do
|
|
1195
|
-
@db.synchronize{|c| c[:host].should == 1}
|
|
1196
|
-
@db.synchronize(:server1){|c| c[:host].should == 3}
|
|
1197
|
-
@db.synchronize(:server2){|c| c[:host].should == 4}
|
|
1424
|
+
@db.synchronize{|c| c.opts[:host].should == 1}
|
|
1425
|
+
@db.synchronize(:server1){|c| c.opts[:host].should == 3}
|
|
1426
|
+
@db.synchronize(:server2){|c| c.opts[:host].should == 4}
|
|
1198
1427
|
|
|
1199
1428
|
@db.remove_servers(:server1, :server2)
|
|
1200
|
-
@db.synchronize{|c| c[:host].should == 1}
|
|
1201
|
-
@db.synchronize(:server1){|c| c[:host].should == 1}
|
|
1202
|
-
@db.synchronize(:server2){|c| c[:host].should == 1}
|
|
1429
|
+
@db.synchronize{|c| c.opts[:host].should == 1}
|
|
1430
|
+
@db.synchronize(:server1){|c| c.opts[:host].should == 1}
|
|
1431
|
+
@db.synchronize(:server2){|c| c.opts[:host].should == 1}
|
|
1203
1432
|
end
|
|
1204
1433
|
|
|
1205
1434
|
specify "should accept arrays of symbols" do
|
|
1206
1435
|
@db.remove_servers([:server1, :server2])
|
|
1207
|
-
@db.synchronize{|c| c[:host].should == 1}
|
|
1208
|
-
@db.synchronize(:server1){|c| c[:host].should == 1}
|
|
1209
|
-
@db.synchronize(:server2){|c| c[:host].should == 1}
|
|
1436
|
+
@db.synchronize{|c| c.opts[:host].should == 1}
|
|
1437
|
+
@db.synchronize(:server1){|c| c.opts[:host].should == 1}
|
|
1438
|
+
@db.synchronize(:server2){|c| c.opts[:host].should == 1}
|
|
1210
1439
|
end
|
|
1211
1440
|
|
|
1212
1441
|
specify "should allow removal while connections are still open" do
|
|
1213
1442
|
@db.synchronize do |c1|
|
|
1214
|
-
c1[:host].should == 1
|
|
1443
|
+
c1.opts[:host].should == 1
|
|
1215
1444
|
@db.synchronize(:server1) do |c2|
|
|
1216
|
-
c2[:host].should == 3
|
|
1445
|
+
c2.opts[:host].should == 3
|
|
1217
1446
|
@db.synchronize(:server2) do |c3|
|
|
1218
|
-
c3[:host].should == 4
|
|
1447
|
+
c3.opts[:host].should == 4
|
|
1219
1448
|
@db.remove_servers(:server1, :server2)
|
|
1220
1449
|
@db.synchronize(:server1) do |c4|
|
|
1221
1450
|
c4.should_not == c2
|
|
1222
1451
|
c4.should == c1
|
|
1223
|
-
c4[:host].should == 1
|
|
1452
|
+
c4.opts[:host].should == 1
|
|
1224
1453
|
@db.synchronize(:server2) do |c5|
|
|
1225
1454
|
c5.should_not == c3
|
|
1226
1455
|
c5.should == c1
|
|
1227
|
-
c5[:host].should == 1
|
|
1456
|
+
c5.opts[:host].should == 1
|
|
1228
1457
|
end
|
|
1229
1458
|
end
|
|
1230
|
-
c3[:host].should == 4
|
|
1459
|
+
c3.opts[:host].should == 4
|
|
1231
1460
|
end
|
|
1232
|
-
c2[:host].should == 3
|
|
1461
|
+
c2.opts[:host].should == 3
|
|
1233
1462
|
end
|
|
1234
|
-
c1[:host].should == 1
|
|
1463
|
+
c1.opts[:host].should == 1
|
|
1235
1464
|
end
|
|
1236
1465
|
end
|
|
1237
1466
|
end
|
|
1238
1467
|
|
|
1239
1468
|
describe "Database#each_server with do/jdbc adapter connection string without :adapter option" do
|
|
1240
|
-
|
|
1469
|
+
specify "should yield a separate database object for each server" do
|
|
1241
1470
|
klass = Class.new(Sequel::Database)
|
|
1242
|
-
klass.should_receive(:adapter_class).once.with(:jdbc).and_return(
|
|
1471
|
+
klass.should_receive(:adapter_class).once.with(:jdbc).and_return(Sequel::Mock::Database)
|
|
1243
1472
|
@db = klass.connect('jdbc:blah:', :host=>1, :database=>2, :servers=>{:server1=>{:host=>3}})
|
|
1244
|
-
def @db.connect(server)
|
|
1245
|
-
server_opts(server)
|
|
1246
|
-
end
|
|
1247
|
-
def @db.disconnect_connection(c)
|
|
1248
|
-
end
|
|
1249
|
-
end
|
|
1250
1473
|
|
|
1251
|
-
specify "should yield a separate database object for each server" do
|
|
1252
1474
|
hosts = []
|
|
1253
1475
|
@db.each_server do |db|
|
|
1254
1476
|
db.should be_a_kind_of(Sequel::Database)
|
|
1255
1477
|
db.should_not == @db
|
|
1256
|
-
db.opts[:adapter_class].should ==
|
|
1478
|
+
db.opts[:adapter_class].should == Sequel::Mock::Database
|
|
1257
1479
|
db.opts[:database].should == 2
|
|
1258
1480
|
hosts << db.opts[:host]
|
|
1259
1481
|
end
|
|
@@ -1263,12 +1485,7 @@ end
|
|
|
1263
1485
|
|
|
1264
1486
|
describe "Database#each_server" do
|
|
1265
1487
|
before do
|
|
1266
|
-
@db = Sequel.
|
|
1267
|
-
def @db.connect(server)
|
|
1268
|
-
server_opts(server)
|
|
1269
|
-
end
|
|
1270
|
-
def @db.disconnect_connection(c)
|
|
1271
|
-
end
|
|
1488
|
+
@db = Sequel.mock(:host=>1, :database=>2, :servers=>{:server1=>{:host=>3}, :server2=>{:host=>4}})
|
|
1272
1489
|
end
|
|
1273
1490
|
|
|
1274
1491
|
specify "should yield a separate database object for each server" do
|
|
@@ -1299,21 +1516,25 @@ describe "Database#each_server" do
|
|
|
1299
1516
|
end
|
|
1300
1517
|
|
|
1301
1518
|
describe "Database#raise_error" do
|
|
1519
|
+
before do
|
|
1520
|
+
@db = Sequel.mock
|
|
1521
|
+
end
|
|
1522
|
+
|
|
1302
1523
|
specify "should reraise if the exception class is not in opts[:classes]" do
|
|
1303
1524
|
e = Class.new(StandardError)
|
|
1304
|
-
proc{
|
|
1525
|
+
proc{@db.send(:raise_error, e.new(''), :classes=>[])}.should raise_error(e)
|
|
1305
1526
|
end
|
|
1306
1527
|
|
|
1307
|
-
specify "should convert the exception to a DatabaseError if the exception class is
|
|
1308
|
-
proc{
|
|
1528
|
+
specify "should convert the exception to a DatabaseError if the exception class is in opts[:classes]" do
|
|
1529
|
+
proc{@db.send(:raise_error, Interrupt.new(''), :classes=>[Interrupt])}.should raise_error(Sequel::DatabaseError)
|
|
1309
1530
|
end
|
|
1310
1531
|
|
|
1311
1532
|
specify "should convert the exception to a DatabaseError if opts[:classes] if not present" do
|
|
1312
|
-
proc{
|
|
1533
|
+
proc{@db.send(:raise_error, Interrupt.new(''))}.should raise_error(Sequel::DatabaseError)
|
|
1313
1534
|
end
|
|
1314
1535
|
|
|
1315
1536
|
specify "should convert the exception to a DatabaseDisconnectError if opts[:disconnect] is true" do
|
|
1316
|
-
proc{
|
|
1537
|
+
proc{@db.send(:raise_error, Interrupt.new(''), :disconnect=>true)}.should raise_error(Sequel::DatabaseDisconnectError)
|
|
1317
1538
|
end
|
|
1318
1539
|
end
|
|
1319
1540
|
|
|
@@ -1373,6 +1594,49 @@ describe "Database#typecast_value" do
|
|
|
1373
1594
|
@db.typecast_value(:date, :year=>Date.today.year, :month=>Date.today.month, :day=>Date.today.day).should == Date.today
|
|
1374
1595
|
end
|
|
1375
1596
|
|
|
1597
|
+
specify "should have Sequel.application_to_database_timestamp convert to Sequel.database_timezone" do
|
|
1598
|
+
begin
|
|
1599
|
+
t = Time.utc(2011, 1, 2, 3, 4, 5) # UTC Time
|
|
1600
|
+
t2 = Time.mktime(2011, 1, 2, 3, 4, 5) # Local Time
|
|
1601
|
+
t3 = Time.utc(2011, 1, 2, 3, 4, 5) - (t - t2) # Local Time in UTC Time
|
|
1602
|
+
t4 = Time.mktime(2011, 1, 2, 3, 4, 5) + (t - t2) # UTC Time in Local Time
|
|
1603
|
+
Sequel.application_timezone = :utc
|
|
1604
|
+
Sequel.database_timezone = :local
|
|
1605
|
+
Sequel.application_to_database_timestamp(t).should == t4
|
|
1606
|
+
Sequel.application_timezone = :local
|
|
1607
|
+
Sequel.database_timezone = :utc
|
|
1608
|
+
Sequel.application_to_database_timestamp(t2).should == t3
|
|
1609
|
+
ensure
|
|
1610
|
+
Sequel.default_timezone = nil
|
|
1611
|
+
end
|
|
1612
|
+
end
|
|
1613
|
+
|
|
1614
|
+
specify "should have Database#to_application_timestamp convert values using the database's timezone" do
|
|
1615
|
+
begin
|
|
1616
|
+
t = Time.utc(2011, 1, 2, 3, 4, 5) # UTC Time
|
|
1617
|
+
t2 = Time.mktime(2011, 1, 2, 3, 4, 5) # Local Time
|
|
1618
|
+
t3 = Time.utc(2011, 1, 2, 3, 4, 5) - (t - t2) # Local Time in UTC Time
|
|
1619
|
+
t4 = Time.mktime(2011, 1, 2, 3, 4, 5) + (t - t2) # UTC Time in Local Time
|
|
1620
|
+
Sequel.default_timezone = :utc
|
|
1621
|
+
@db.to_application_timestamp('2011-01-02 03:04:05').should == t
|
|
1622
|
+
Sequel.database_timezone = :local
|
|
1623
|
+
@db.to_application_timestamp('2011-01-02 03:04:05').should == t3
|
|
1624
|
+
Sequel.default_timezone = :local
|
|
1625
|
+
@db.to_application_timestamp('2011-01-02 03:04:05').should == t2
|
|
1626
|
+
Sequel.database_timezone = :utc
|
|
1627
|
+
@db.to_application_timestamp('2011-01-02 03:04:05').should == t4
|
|
1628
|
+
|
|
1629
|
+
Sequel.default_timezone = :utc
|
|
1630
|
+
@db.timezone = :local
|
|
1631
|
+
@db.to_application_timestamp('2011-01-02 03:04:05').should == t3
|
|
1632
|
+
Sequel.default_timezone = :local
|
|
1633
|
+
@db.timezone = :utc
|
|
1634
|
+
@db.to_application_timestamp('2011-01-02 03:04:05').should == t4
|
|
1635
|
+
ensure
|
|
1636
|
+
Sequel.default_timezone = nil
|
|
1637
|
+
end
|
|
1638
|
+
end
|
|
1639
|
+
|
|
1376
1640
|
specify "should typecast datetime values to Sequel.datetime_class with correct timezone handling" do
|
|
1377
1641
|
t = Time.utc(2011, 1, 2, 3, 4, 5) # UTC Time
|
|
1378
1642
|
t2 = Time.mktime(2011, 1, 2, 3, 4, 5) # Local Time
|
|
@@ -1596,7 +1860,7 @@ describe "Database#blank_object?" do
|
|
|
1596
1860
|
end
|
|
1597
1861
|
|
|
1598
1862
|
describe "Database#schema_autoincrementing_primary_key?" do
|
|
1599
|
-
specify "should whether the parsed schema row indicates a primary key" do
|
|
1863
|
+
specify "should indicate whether the parsed schema row indicates a primary key" do
|
|
1600
1864
|
m = Sequel::Database.new.method(:schema_autoincrementing_primary_key?)
|
|
1601
1865
|
m.call(:primary_key=>true).should == true
|
|
1602
1866
|
m.call(:primary_key=>false).should == false
|
|
@@ -1652,7 +1916,7 @@ describe "Database#column_schema_to_ruby_default" do
|
|
|
1652
1916
|
db = Sequel::Database.new
|
|
1653
1917
|
m = db.method(:column_schema_to_ruby_default)
|
|
1654
1918
|
p = lambda{|d,t| m.call(d,t)}
|
|
1655
|
-
p[nil, :integer].should
|
|
1919
|
+
p[nil, :integer].should be_nil
|
|
1656
1920
|
p['1', :integer].should == 1
|
|
1657
1921
|
p['-1', :integer].should == -1
|
|
1658
1922
|
p['1.0', :float].should == 1.0
|
|
@@ -1672,12 +1936,12 @@ describe "Database#column_schema_to_ruby_default" do
|
|
|
1672
1936
|
p["'\\a''b'", :string].should == "\\a'b"
|
|
1673
1937
|
p["'NULL'", :string].should == "NULL"
|
|
1674
1938
|
p["'2009-10-29'", :date].should == Date.new(2009,10,29)
|
|
1675
|
-
p["CURRENT_TIMESTAMP", :date].should
|
|
1676
|
-
p["today()", :date].should
|
|
1939
|
+
p["CURRENT_TIMESTAMP", :date].should be_nil
|
|
1940
|
+
p["today()", :date].should be_nil
|
|
1677
1941
|
p["'2009-10-29T10:20:30-07:00'", :datetime].should == DateTime.parse('2009-10-29T10:20:30-07:00')
|
|
1678
1942
|
p["'2009-10-29 10:20:30'", :datetime].should == DateTime.parse('2009-10-29 10:20:30')
|
|
1679
1943
|
p["'10:20:30'", :time].should == Time.parse('10:20:30')
|
|
1680
|
-
p["NaN", :float].should
|
|
1944
|
+
p["NaN", :float].should be_nil
|
|
1681
1945
|
|
|
1682
1946
|
db.meta_def(:database_type){:postgres}
|
|
1683
1947
|
p["''::text", :string].should == ""
|
|
@@ -1701,8 +1965,8 @@ describe "Database#column_schema_to_ruby_default" do
|
|
|
1701
1965
|
p["2009-10-29", :date].should == Date.new(2009,10,29)
|
|
1702
1966
|
p["2009-10-29 10:20:30", :datetime].should == DateTime.parse('2009-10-29 10:20:30')
|
|
1703
1967
|
p["10:20:30", :time].should == Time.parse('10:20:30')
|
|
1704
|
-
p["CURRENT_DATE", :date].should
|
|
1705
|
-
p["CURRENT_TIMESTAMP", :datetime].should
|
|
1968
|
+
p["CURRENT_DATE", :date].should be_nil
|
|
1969
|
+
p["CURRENT_TIMESTAMP", :datetime].should be_nil
|
|
1706
1970
|
p["a", :enum].should == "a"
|
|
1707
1971
|
|
|
1708
1972
|
db.meta_def(:database_type){:mssql}
|