sequel 3.45.0 → 3.46.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.
- 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
|