sequel 3.45.0 → 3.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +34 -0
- data/README.rdoc +6 -0
- data/Rakefile +46 -33
- data/doc/release_notes/3.46.0.txt +122 -0
- data/doc/schema_modification.rdoc +42 -6
- data/doc/security.rdoc +379 -0
- data/doc/transactions.rdoc +1 -1
- data/lib/sequel/adapters/jdbc/as400.rb +1 -0
- data/lib/sequel/adapters/jdbc/h2.rb +11 -0
- data/lib/sequel/adapters/mysql2.rb +3 -9
- data/lib/sequel/adapters/postgres.rb +34 -2
- data/lib/sequel/adapters/shared/cubrid.rb +5 -0
- data/lib/sequel/adapters/shared/mssql.rb +27 -3
- data/lib/sequel/adapters/shared/mysql.rb +25 -4
- data/lib/sequel/adapters/shared/sqlite.rb +12 -1
- data/lib/sequel/connection_pool.rb +3 -3
- data/lib/sequel/connection_pool/sharded_threaded.rb +7 -8
- data/lib/sequel/connection_pool/threaded.rb +7 -8
- data/lib/sequel/core.rb +5 -2
- data/lib/sequel/database.rb +1 -1
- data/lib/sequel/database/connecting.rb +7 -7
- data/lib/sequel/database/features.rb +88 -0
- data/lib/sequel/database/misc.rb +14 -64
- data/lib/sequel/database/query.rb +0 -332
- data/lib/sequel/database/schema_generator.rb +36 -3
- data/lib/sequel/database/schema_methods.rb +48 -12
- data/lib/sequel/database/transactions.rb +344 -0
- data/lib/sequel/dataset/actions.rb +24 -9
- data/lib/sequel/dataset/mutation.rb +20 -0
- data/lib/sequel/dataset/query.rb +0 -17
- data/lib/sequel/dataset/sql.rb +7 -0
- data/lib/sequel/exceptions.rb +10 -6
- data/lib/sequel/extensions/_pretty_table.rb +2 -2
- data/lib/sequel/extensions/looser_typecasting.rb +10 -0
- data/lib/sequel/extensions/migration.rb +5 -2
- data/lib/sequel/model.rb +1 -1
- data/lib/sequel/model/associations.rb +16 -14
- data/lib/sequel/model/base.rb +14 -2
- data/lib/sequel/plugins/composition.rb +3 -3
- data/lib/sequel/plugins/dirty.rb +6 -6
- data/lib/sequel/plugins/hook_class_methods.rb +3 -0
- data/lib/sequel/plugins/serialization.rb +7 -17
- data/lib/sequel/plugins/string_stripper.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/sql.rb +3 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +21 -0
- data/spec/adapters/postgres_spec.rb +35 -8
- data/spec/core/database_spec.rb +4 -0
- data/spec/core/dataset_spec.rb +48 -2
- data/spec/core/schema_generator_spec.rb +10 -1
- data/spec/core/schema_spec.rb +69 -0
- data/spec/extensions/composition_spec.rb +21 -2
- data/spec/extensions/dirty_spec.rb +17 -10
- data/spec/extensions/eager_each_spec.rb +4 -1
- data/spec/extensions/looser_typecasting_spec.rb +16 -19
- data/spec/extensions/migration_spec.rb +7 -1
- data/spec/extensions/serialization_spec.rb +22 -0
- data/spec/extensions/single_table_inheritance_spec.rb +3 -2
- data/spec/extensions/validation_helpers_spec.rb +6 -0
- data/spec/integration/dataset_test.rb +5 -0
- data/spec/integration/schema_test.rb +16 -0
- data/spec/model/associations_spec.rb +40 -0
- data/spec/model/base_spec.rb +21 -1
- data/spec/model/record_spec.rb +3 -0
- metadata +14 -10
@@ -0,0 +1,88 @@
|
|
1
|
+
module Sequel
|
2
|
+
class Database
|
3
|
+
# ---------------------
|
4
|
+
# :section: 9 - Methods that describe what the database supports
|
5
|
+
# These methods all return booleans, with most describing whether or not the
|
6
|
+
# database supprots a given feature.
|
7
|
+
# ---------------------
|
8
|
+
|
9
|
+
# Whether the database uses a global namespace for the index. If
|
10
|
+
# false, the indexes are going to be namespaced per table.
|
11
|
+
def global_index_namespace?
|
12
|
+
true
|
13
|
+
end
|
14
|
+
|
15
|
+
# Whether the database supports CREATE TABLE IF NOT EXISTS syntax,
|
16
|
+
# false by default.
|
17
|
+
def supports_create_table_if_not_exists?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
# Whether the database supports deferrable constraints, false
|
22
|
+
# by default as few databases do.
|
23
|
+
def supports_deferrable_constraints?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
# Whether the database supports deferrable foreign key constraints,
|
28
|
+
# false by default as few databases do.
|
29
|
+
def supports_deferrable_foreign_key_constraints?
|
30
|
+
supports_deferrable_constraints?
|
31
|
+
end
|
32
|
+
|
33
|
+
# Whether the database supports DROP TABLE IF EXISTS syntax,
|
34
|
+
# default is the same as #supports_create_table_if_not_exists?.
|
35
|
+
def supports_drop_table_if_exists?
|
36
|
+
supports_create_table_if_not_exists?
|
37
|
+
end
|
38
|
+
|
39
|
+
# Whether the database and adapter support prepared transactions
|
40
|
+
# (two-phase commit), false by default.
|
41
|
+
def supports_prepared_transactions?
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
45
|
+
# Whether the database and adapter support savepoints, false by default.
|
46
|
+
def supports_savepoints?
|
47
|
+
false
|
48
|
+
end
|
49
|
+
|
50
|
+
# Whether the database and adapter support savepoints inside prepared transactions
|
51
|
+
# (two-phase commit), default is false.
|
52
|
+
def supports_savepoints_in_prepared_transactions?
|
53
|
+
supports_prepared_transactions? && supports_savepoints?
|
54
|
+
end
|
55
|
+
|
56
|
+
# Whether the database and adapter support transaction isolation levels, false by default.
|
57
|
+
def supports_transaction_isolation_levels?
|
58
|
+
false
|
59
|
+
end
|
60
|
+
|
61
|
+
# Whether DDL statements work correctly in transactions, false by default.
|
62
|
+
def supports_transactional_ddl?
|
63
|
+
false
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# Whether the database supports combining multiple alter table
|
69
|
+
# operations into a single query, false by default.
|
70
|
+
def supports_combining_alter_table_ops?
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
# Whether the database supports CREATE OR REPLACE VIEW. If not, support
|
75
|
+
# will be emulated by dropping the view first. false by default.
|
76
|
+
def supports_create_or_replace_view?
|
77
|
+
false
|
78
|
+
end
|
79
|
+
|
80
|
+
# Whether the database supports named column constraints. True
|
81
|
+
# by default. Those that don't support named column constraints
|
82
|
+
# have to have column constraints converted to table constraints
|
83
|
+
# if the column constraints have names.
|
84
|
+
def supports_named_column_constraints?
|
85
|
+
true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/sequel/database/misc.rb
CHANGED
@@ -163,12 +163,6 @@ module Sequel
|
|
163
163
|
Sequel.convert_output_timestamp(v, timezone)
|
164
164
|
end
|
165
165
|
|
166
|
-
# Whether the database uses a global namespace for the index. If
|
167
|
-
# false, the indexes are going to be namespaced per table.
|
168
|
-
def global_index_namespace?
|
169
|
-
true
|
170
|
-
end
|
171
|
-
|
172
166
|
# Return true if already in a transaction given the options,
|
173
167
|
# false otherwise. Respects the :server option for selecting
|
174
168
|
# a shard.
|
@@ -219,57 +213,6 @@ module Sequel
|
|
219
213
|
Sequel.synchronize{prepared_statements[name] = ps}
|
220
214
|
end
|
221
215
|
|
222
|
-
# Whether the database supports CREATE TABLE IF NOT EXISTS syntax,
|
223
|
-
# false by default.
|
224
|
-
def supports_create_table_if_not_exists?
|
225
|
-
false
|
226
|
-
end
|
227
|
-
|
228
|
-
# Whether the database supports deferrable constraints, false
|
229
|
-
# by default as few databases do.
|
230
|
-
def supports_deferrable_constraints?
|
231
|
-
false
|
232
|
-
end
|
233
|
-
|
234
|
-
# Whether the database supports deferrable foreign key constraints,
|
235
|
-
# false by default as few databases do.
|
236
|
-
def supports_deferrable_foreign_key_constraints?
|
237
|
-
supports_deferrable_constraints?
|
238
|
-
end
|
239
|
-
|
240
|
-
# Whether the database supports DROP TABLE IF EXISTS syntax,
|
241
|
-
# default is the same as #supports_create_table_if_not_exists?.
|
242
|
-
def supports_drop_table_if_exists?
|
243
|
-
supports_create_table_if_not_exists?
|
244
|
-
end
|
245
|
-
|
246
|
-
# Whether the database and adapter support prepared transactions
|
247
|
-
# (two-phase commit), false by default.
|
248
|
-
def supports_prepared_transactions?
|
249
|
-
false
|
250
|
-
end
|
251
|
-
|
252
|
-
# Whether the database and adapter support savepoints, false by default.
|
253
|
-
def supports_savepoints?
|
254
|
-
false
|
255
|
-
end
|
256
|
-
|
257
|
-
# Whether the database and adapter support savepoints inside prepared transactions
|
258
|
-
# (two-phase commit), default is false.
|
259
|
-
def supports_savepoints_in_prepared_transactions?
|
260
|
-
supports_prepared_transactions? && supports_savepoints?
|
261
|
-
end
|
262
|
-
|
263
|
-
# Whether the database and adapter support transaction isolation levels, false by default.
|
264
|
-
def supports_transaction_isolation_levels?
|
265
|
-
false
|
266
|
-
end
|
267
|
-
|
268
|
-
# Whether DDL statements work correctly in transactions, false by default.
|
269
|
-
def supports_transactional_ddl?
|
270
|
-
false
|
271
|
-
end
|
272
|
-
|
273
216
|
# The timezone to use for this database, defaulting to <tt>Sequel.database_timezone</tt>.
|
274
217
|
def timezone
|
275
218
|
@timezone || Sequel.database_timezone
|
@@ -407,12 +350,6 @@ module Sequel
|
|
407
350
|
end
|
408
351
|
end
|
409
352
|
|
410
|
-
# Whether the database supports CREATE OR REPLACE VIEW. If not, support
|
411
|
-
# will be emulated by dropping the view first. false by default.
|
412
|
-
def supports_create_or_replace_view?
|
413
|
-
false
|
414
|
-
end
|
415
|
-
|
416
353
|
# Typecast the value to an SQL::Blob
|
417
354
|
def typecast_value_blob(value)
|
418
355
|
value.is_a?(Sequel::SQL::Blob) ? value : Sequel::SQL::Blob.new(value)
|
@@ -454,8 +391,21 @@ module Sequel
|
|
454
391
|
case value
|
455
392
|
when BigDecimal
|
456
393
|
value
|
457
|
-
when
|
394
|
+
when Numeric
|
458
395
|
BigDecimal.new(value.to_s)
|
396
|
+
when String
|
397
|
+
d = BigDecimal.new(value)
|
398
|
+
if d.zero?
|
399
|
+
# BigDecimal parsing is loose by default, returning a 0 value for
|
400
|
+
# invalid input. If a zero value is received, use Float to check
|
401
|
+
# for validity.
|
402
|
+
begin
|
403
|
+
Float(value)
|
404
|
+
rescue ArgumentError
|
405
|
+
raise InvalidValue, "invalid value for BigDecimal: #{value.inspect}"
|
406
|
+
end
|
407
|
+
end
|
408
|
+
d
|
459
409
|
else
|
460
410
|
raise InvalidValue, "invalid value for BigDecimal: #{value.inspect}"
|
461
411
|
end
|
@@ -5,22 +5,6 @@ module Sequel
|
|
5
5
|
# This methods generally execute SQL code on the database server.
|
6
6
|
# ---------------------
|
7
7
|
|
8
|
-
SQL_BEGIN = 'BEGIN'.freeze
|
9
|
-
SQL_COMMIT = 'COMMIT'.freeze
|
10
|
-
SQL_RELEASE_SAVEPOINT = 'RELEASE SAVEPOINT autopoint_%d'.freeze
|
11
|
-
SQL_ROLLBACK = 'ROLLBACK'.freeze
|
12
|
-
SQL_ROLLBACK_TO_SAVEPOINT = 'ROLLBACK TO SAVEPOINT autopoint_%d'.freeze
|
13
|
-
SQL_SAVEPOINT = 'SAVEPOINT autopoint_%d'.freeze
|
14
|
-
|
15
|
-
TRANSACTION_BEGIN = 'Transaction.begin'.freeze
|
16
|
-
TRANSACTION_COMMIT = 'Transaction.commit'.freeze
|
17
|
-
TRANSACTION_ROLLBACK = 'Transaction.rollback'.freeze
|
18
|
-
|
19
|
-
TRANSACTION_ISOLATION_LEVELS = {:uncommitted=>'READ UNCOMMITTED'.freeze,
|
20
|
-
:committed=>'READ COMMITTED'.freeze,
|
21
|
-
:repeatable=>'REPEATABLE READ'.freeze,
|
22
|
-
:serializable=>'SERIALIZABLE'.freeze}
|
23
|
-
|
24
8
|
STRING_DEFAULT_RE = /\A'(.*)'\z/
|
25
9
|
CURRENT_TIMESTAMP_RE = /now|CURRENT|getdate|\ADate\(\)\z/io
|
26
10
|
COLUMN_SCHEMA_DATETIME_TYPES = [:date, :datetime]
|
@@ -29,13 +13,6 @@ module Sequel
|
|
29
13
|
# The prepared statement object hash for this database, keyed by name symbol
|
30
14
|
attr_reader :prepared_statements
|
31
15
|
|
32
|
-
# The default transaction isolation level for this database,
|
33
|
-
# used for all future transactions. For MSSQL, this should be set
|
34
|
-
# to something if you ever plan to use the :isolation option to
|
35
|
-
# Database#transaction, as on MSSQL if affects all future transactions
|
36
|
-
# on the same connection.
|
37
|
-
attr_accessor :transaction_isolation_level
|
38
|
-
|
39
16
|
# Whether the schema should be cached for this database. True by default
|
40
17
|
# for performance, can be set to false to always issue a database query to
|
41
18
|
# get the schema.
|
@@ -245,80 +222,6 @@ module Sequel
|
|
245
222
|
raise NotImplemented, "#tables should be overridden by adapters"
|
246
223
|
end
|
247
224
|
|
248
|
-
# Starts a database transaction. When a database transaction is used,
|
249
|
-
# either all statements are successful or none of the statements are
|
250
|
-
# successful. Note that MySQL MyISAM tables do not support transactions.
|
251
|
-
#
|
252
|
-
# The following general options are respected:
|
253
|
-
#
|
254
|
-
# :disconnect :: If set to :retry, automatically sets the :retry_on option
|
255
|
-
# with a Sequel::DatabaseDisconnectError. This option is only
|
256
|
-
# present for backwards compatibility, please use the :retry_on
|
257
|
-
# option instead.
|
258
|
-
# :isolation :: The transaction isolation level to use for this transaction,
|
259
|
-
# should be :uncommitted, :committed, :repeatable, or :serializable,
|
260
|
-
# used if given and the database/adapter supports customizable
|
261
|
-
# transaction isolation levels.
|
262
|
-
# :num_retries :: The number of times to retry if the :retry_on option is used.
|
263
|
-
# The default is 5 times. Can be set to nil to retry indefinitely,
|
264
|
-
# but that is not recommended.
|
265
|
-
# :prepare :: A string to use as the transaction identifier for a
|
266
|
-
# prepared transaction (two-phase commit), if the database/adapter
|
267
|
-
# supports prepared transactions.
|
268
|
-
# :retry_on :: An exception class or array of exception classes for which to
|
269
|
-
# automatically retry the transaction. Can only be set if not inside
|
270
|
-
# an existing transaction.
|
271
|
-
# Note that this should not be used unless the entire transaction
|
272
|
-
# block is idempotent, as otherwise it can cause non-idempotent
|
273
|
-
# behavior to execute multiple times.
|
274
|
-
# :rollback :: Can the set to :reraise to reraise any Sequel::Rollback exceptions
|
275
|
-
# raised, or :always to always rollback even if no exceptions occur
|
276
|
-
# (useful for testing).
|
277
|
-
# :server :: The server to use for the transaction.
|
278
|
-
# :savepoint :: Whether to create a new savepoint for this transaction,
|
279
|
-
# only respected if the database/adapter supports savepoints. By
|
280
|
-
# default Sequel will reuse an existing transaction, so if you want to
|
281
|
-
# use a savepoint you must use this option.
|
282
|
-
#
|
283
|
-
# PostgreSQL specific options:
|
284
|
-
#
|
285
|
-
# :deferrable :: (9.1+) If present, set to DEFERRABLE if true or NOT DEFERRABLE if false.
|
286
|
-
# :read_only :: If present, set to READ ONLY if true or READ WRITE if false.
|
287
|
-
# :synchronous :: if non-nil, set synchronous_commit
|
288
|
-
# appropriately. Valid values true, :on, false, :off, :local (9.1+),
|
289
|
-
# and :remote_write (9.2+).
|
290
|
-
def transaction(opts={}, &block)
|
291
|
-
if opts[:disconnect] == :retry
|
292
|
-
raise(Error, 'cannot specify both :disconnect=>:retry and :retry_on') if opts[:retry_on]
|
293
|
-
return transaction(opts.merge(:retry_on=>Sequel::DatabaseDisconnectError, :disconnect=>nil), &block)
|
294
|
-
end
|
295
|
-
|
296
|
-
if retry_on = opts[:retry_on]
|
297
|
-
num_retries = opts.fetch(:num_retries, 5)
|
298
|
-
begin
|
299
|
-
transaction(opts.merge(:retry_on=>nil, :retrying=>true), &block)
|
300
|
-
rescue *retry_on
|
301
|
-
if num_retries
|
302
|
-
num_retries -= 1
|
303
|
-
retry if num_retries >= 0
|
304
|
-
else
|
305
|
-
retry
|
306
|
-
end
|
307
|
-
raise
|
308
|
-
end
|
309
|
-
else
|
310
|
-
synchronize(opts[:server]) do |conn|
|
311
|
-
if already_in_transaction?(conn, opts)
|
312
|
-
if opts[:retrying]
|
313
|
-
raise Sequel::Error, "cannot set :disconnect=>:retry or :retry_on options if you are already inside a transaction"
|
314
|
-
end
|
315
|
-
return yield(conn)
|
316
|
-
end
|
317
|
-
_transaction(conn, opts, &block)
|
318
|
-
end
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
225
|
# Return all views in the database as an array of symbols.
|
323
226
|
#
|
324
227
|
# DB.views # => [:gold_albums, :artists_with_many_albums]
|
@@ -334,125 +237,6 @@ module Sequel
|
|
334
237
|
ds.get(Sequel::NULL)
|
335
238
|
end
|
336
239
|
|
337
|
-
# Internal generic transaction method. Any exception raised by the given
|
338
|
-
# block will cause the transaction to be rolled back. If the exception is
|
339
|
-
# not a Sequel::Rollback, the error will be reraised. If no exception occurs
|
340
|
-
# inside the block, the transaction is commited.
|
341
|
-
def _transaction(conn, opts={})
|
342
|
-
rollback = opts[:rollback]
|
343
|
-
begin
|
344
|
-
add_transaction(conn, opts)
|
345
|
-
begin_transaction(conn, opts)
|
346
|
-
if rollback == :always
|
347
|
-
begin
|
348
|
-
yield(conn)
|
349
|
-
rescue Exception => e1
|
350
|
-
raise e1
|
351
|
-
ensure
|
352
|
-
raise ::Sequel::Rollback unless e1
|
353
|
-
end
|
354
|
-
else
|
355
|
-
yield(conn)
|
356
|
-
end
|
357
|
-
rescue Exception => e
|
358
|
-
begin
|
359
|
-
rollback_transaction(conn, opts)
|
360
|
-
rescue Exception => e3
|
361
|
-
raise_error(e3, :classes=>database_error_classes, :conn=>conn)
|
362
|
-
end
|
363
|
-
transaction_error(e, :conn=>conn, :rollback=>rollback)
|
364
|
-
ensure
|
365
|
-
begin
|
366
|
-
committed = commit_or_rollback_transaction(e, conn, opts)
|
367
|
-
rescue Exception => e2
|
368
|
-
begin
|
369
|
-
raise_error(e2, :classes=>database_error_classes, :conn=>conn)
|
370
|
-
rescue Sequel::DatabaseError => e4
|
371
|
-
begin
|
372
|
-
rollback_transaction(conn, opts)
|
373
|
-
ensure
|
374
|
-
raise e4
|
375
|
-
end
|
376
|
-
end
|
377
|
-
ensure
|
378
|
-
remove_transaction(conn, committed)
|
379
|
-
end
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
# Synchronize access to the current transactions, returning the hash
|
384
|
-
# of options for the current transaction (if any)
|
385
|
-
def _trans(conn)
|
386
|
-
Sequel.synchronize{@transactions[conn]}
|
387
|
-
end
|
388
|
-
|
389
|
-
# Add the current thread to the list of active transactions
|
390
|
-
def add_transaction(conn, opts)
|
391
|
-
if supports_savepoints?
|
392
|
-
unless _trans(conn)
|
393
|
-
if (prep = opts[:prepare]) && supports_prepared_transactions?
|
394
|
-
Sequel.synchronize{@transactions[conn] = {:savepoint_level=>0, :prepare=>prep}}
|
395
|
-
else
|
396
|
-
Sequel.synchronize{@transactions[conn] = {:savepoint_level=>0}}
|
397
|
-
end
|
398
|
-
end
|
399
|
-
elsif (prep = opts[:prepare]) && supports_prepared_transactions?
|
400
|
-
Sequel.synchronize{@transactions[conn] = {:prepare => prep}}
|
401
|
-
else
|
402
|
-
Sequel.synchronize{@transactions[conn] = {}}
|
403
|
-
end
|
404
|
-
end
|
405
|
-
|
406
|
-
# Call all stored after_commit blocks for the given transaction
|
407
|
-
def after_transaction_commit(conn)
|
408
|
-
if ary = _trans(conn)[:after_commit]
|
409
|
-
ary.each{|b| b.call}
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
# Call all stored after_rollback blocks for the given transaction
|
414
|
-
def after_transaction_rollback(conn)
|
415
|
-
if ary = _trans(conn)[:after_rollback]
|
416
|
-
ary.each{|b| b.call}
|
417
|
-
end
|
418
|
-
end
|
419
|
-
|
420
|
-
# Whether the current thread/connection is already inside a transaction
|
421
|
-
def already_in_transaction?(conn, opts)
|
422
|
-
_trans(conn) && (!supports_savepoints? || !opts[:savepoint])
|
423
|
-
end
|
424
|
-
|
425
|
-
# SQL to start a new savepoint
|
426
|
-
def begin_savepoint_sql(depth)
|
427
|
-
SQL_SAVEPOINT % depth
|
428
|
-
end
|
429
|
-
|
430
|
-
# Start a new database connection on the given connection
|
431
|
-
def begin_new_transaction(conn, opts)
|
432
|
-
log_connection_execute(conn, begin_transaction_sql)
|
433
|
-
set_transaction_isolation(conn, opts)
|
434
|
-
end
|
435
|
-
|
436
|
-
# Start a new database transaction or a new savepoint on the given connection.
|
437
|
-
def begin_transaction(conn, opts={})
|
438
|
-
if supports_savepoints?
|
439
|
-
th = _trans(conn)
|
440
|
-
if (depth = th[:savepoint_level]) > 0
|
441
|
-
log_connection_execute(conn, begin_savepoint_sql(depth))
|
442
|
-
else
|
443
|
-
begin_new_transaction(conn, opts)
|
444
|
-
end
|
445
|
-
th[:savepoint_level] += 1
|
446
|
-
else
|
447
|
-
begin_new_transaction(conn, opts)
|
448
|
-
end
|
449
|
-
end
|
450
|
-
|
451
|
-
# SQL to BEGIN a transaction.
|
452
|
-
def begin_transaction_sql
|
453
|
-
SQL_BEGIN
|
454
|
-
end
|
455
|
-
|
456
240
|
# Whether the type should be treated as a string type when parsing the
|
457
241
|
# column schema default value.
|
458
242
|
def column_schema_default_string_type?(type)
|
@@ -517,66 +301,6 @@ module Sequel
|
|
517
301
|
column_schema_default_to_ruby_value(default, type) rescue nil
|
518
302
|
end
|
519
303
|
|
520
|
-
if (! defined?(RUBY_ENGINE) or RUBY_ENGINE == 'ruby' or RUBY_ENGINE == 'rbx') and RUBY_VERSION < '1.9'
|
521
|
-
# :nocov:
|
522
|
-
# Whether to commit the current transaction. On ruby 1.8 and rubinius,
|
523
|
-
# Thread.current.status is checked because Thread#kill skips rescue
|
524
|
-
# blocks (so exception would be nil), but the transaction should
|
525
|
-
# still be rolled back.
|
526
|
-
def commit_or_rollback_transaction(exception, conn, opts)
|
527
|
-
if exception
|
528
|
-
false
|
529
|
-
else
|
530
|
-
if Thread.current.status == 'aborting'
|
531
|
-
rollback_transaction(conn, opts)
|
532
|
-
false
|
533
|
-
else
|
534
|
-
commit_transaction(conn, opts)
|
535
|
-
true
|
536
|
-
end
|
537
|
-
end
|
538
|
-
end
|
539
|
-
# :nocov:
|
540
|
-
else
|
541
|
-
# Whether to commit the current transaction. On ruby 1.9 and JRuby,
|
542
|
-
# transactions will be committed if Thread#kill is used on an thread
|
543
|
-
# that has a transaction open, and there isn't a work around.
|
544
|
-
def commit_or_rollback_transaction(exception, conn, opts)
|
545
|
-
if exception
|
546
|
-
false
|
547
|
-
else
|
548
|
-
commit_transaction(conn, opts)
|
549
|
-
true
|
550
|
-
end
|
551
|
-
end
|
552
|
-
end
|
553
|
-
|
554
|
-
# SQL to commit a savepoint
|
555
|
-
def commit_savepoint_sql(depth)
|
556
|
-
SQL_RELEASE_SAVEPOINT % depth
|
557
|
-
end
|
558
|
-
|
559
|
-
# Commit the active transaction on the connection
|
560
|
-
def commit_transaction(conn, opts={})
|
561
|
-
if supports_savepoints?
|
562
|
-
depth = _trans(conn)[:savepoint_level]
|
563
|
-
log_connection_execute(conn, depth > 1 ? commit_savepoint_sql(depth-1) : commit_transaction_sql)
|
564
|
-
else
|
565
|
-
log_connection_execute(conn, commit_transaction_sql)
|
566
|
-
end
|
567
|
-
end
|
568
|
-
|
569
|
-
# SQL to COMMIT a transaction.
|
570
|
-
def commit_transaction_sql
|
571
|
-
SQL_COMMIT
|
572
|
-
end
|
573
|
-
|
574
|
-
# Method called on the connection object to execute SQL on the database,
|
575
|
-
# used by the transaction code.
|
576
|
-
def connection_execute_method
|
577
|
-
:execute
|
578
|
-
end
|
579
|
-
|
580
304
|
# Return a Method object for the dataset's output_identifier_method.
|
581
305
|
# Used in metadata parsing to make sure the returned information is in the
|
582
306
|
# correct format.
|
@@ -607,41 +331,6 @@ module Sequel
|
|
607
331
|
Sequel.synchronize{@schemas.delete(quote_schema_table(table))} if @schemas
|
608
332
|
end
|
609
333
|
|
610
|
-
# Remove the current thread from the list of active transactions
|
611
|
-
def remove_transaction(conn, committed)
|
612
|
-
if !supports_savepoints? || ((_trans(conn)[:savepoint_level] -= 1) <= 0)
|
613
|
-
begin
|
614
|
-
if committed
|
615
|
-
after_transaction_commit(conn)
|
616
|
-
else
|
617
|
-
after_transaction_rollback(conn)
|
618
|
-
end
|
619
|
-
ensure
|
620
|
-
Sequel.synchronize{@transactions.delete(conn)}
|
621
|
-
end
|
622
|
-
end
|
623
|
-
end
|
624
|
-
|
625
|
-
# SQL to rollback to a savepoint
|
626
|
-
def rollback_savepoint_sql(depth)
|
627
|
-
SQL_ROLLBACK_TO_SAVEPOINT % depth
|
628
|
-
end
|
629
|
-
|
630
|
-
# Rollback the active transaction on the connection
|
631
|
-
def rollback_transaction(conn, opts={})
|
632
|
-
if supports_savepoints?
|
633
|
-
depth = _trans(conn)[:savepoint_level]
|
634
|
-
log_connection_execute(conn, depth > 1 ? rollback_savepoint_sql(depth-1) : rollback_transaction_sql)
|
635
|
-
else
|
636
|
-
log_connection_execute(conn, rollback_transaction_sql)
|
637
|
-
end
|
638
|
-
end
|
639
|
-
|
640
|
-
# SQL to ROLLBACK a transaction.
|
641
|
-
def rollback_transaction_sql
|
642
|
-
SQL_ROLLBACK
|
643
|
-
end
|
644
|
-
|
645
334
|
# Match the database's column type to a ruby type via a
|
646
335
|
# regular expression, and return the ruby type as a symbol
|
647
336
|
# such as :integer or :string.
|
@@ -669,26 +358,5 @@ module Sequel
|
|
669
358
|
:enum
|
670
359
|
end
|
671
360
|
end
|
672
|
-
|
673
|
-
# Set the transaction isolation level on the given connection
|
674
|
-
def set_transaction_isolation(conn, opts)
|
675
|
-
if supports_transaction_isolation_levels? and level = opts.fetch(:isolation, transaction_isolation_level)
|
676
|
-
log_connection_execute(conn, set_transaction_isolation_sql(level))
|
677
|
-
end
|
678
|
-
end
|
679
|
-
|
680
|
-
# SQL to set the transaction isolation level
|
681
|
-
def set_transaction_isolation_sql(level)
|
682
|
-
"SET TRANSACTION ISOLATION LEVEL #{TRANSACTION_ISOLATION_LEVELS[level]}"
|
683
|
-
end
|
684
|
-
|
685
|
-
# Raise a database error unless the exception is an Rollback.
|
686
|
-
def transaction_error(e, opts={})
|
687
|
-
if e.is_a?(Rollback)
|
688
|
-
raise e if opts[:rollback] == :reraise
|
689
|
-
else
|
690
|
-
raise_error(e, opts.merge(:classes=>database_error_classes))
|
691
|
-
end
|
692
|
-
end
|
693
361
|
end
|
694
362
|
end
|