sequel 4.48.0 → 4.49.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 +4 -4
- data/CHANGELOG +56 -0
- data/doc/advanced_associations.rdoc +1 -1
- data/doc/opening_databases.rdoc +3 -2
- data/doc/release_notes/4.49.0.txt +222 -0
- data/lib/sequel/adapters/ibmdb.rb +6 -1
- data/lib/sequel/adapters/jdbc.rb +3 -1
- data/lib/sequel/adapters/jdbc/h2.rb +10 -1
- data/lib/sequel/adapters/jdbc/postgresql.rb +3 -2
- data/lib/sequel/adapters/jdbc/sqlserver.rb +9 -2
- data/lib/sequel/adapters/mock.rb +3 -0
- data/lib/sequel/adapters/mysql2.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +2 -1
- data/lib/sequel/adapters/shared/mysql.rb +4 -1
- data/lib/sequel/adapters/shared/oracle.rb +26 -3
- data/lib/sequel/connection_pool.rb +9 -2
- data/lib/sequel/connection_pool/sharded_single.rb +1 -1
- data/lib/sequel/connection_pool/sharded_threaded.rb +1 -1
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/connection_pool/threaded.rb +2 -2
- data/lib/sequel/database/connecting.rb +3 -3
- data/lib/sequel/database/dataset_defaults.rb +14 -1
- data/lib/sequel/dataset.rb +1 -1
- data/lib/sequel/dataset/actions.rb +54 -0
- data/lib/sequel/dataset/dataset_module.rb +58 -0
- data/lib/sequel/dataset/query.rb +3 -3
- data/lib/sequel/exceptions.rb +8 -0
- data/lib/sequel/extensions/_model_pg_row.rb +5 -2
- data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -1
- data/lib/sequel/extensions/date_arithmetic.rb +1 -0
- data/lib/sequel/extensions/duplicate_columns_handler.rb +2 -2
- data/lib/sequel/extensions/migration.rb +5 -2
- data/lib/sequel/extensions/null_dataset.rb +1 -0
- data/lib/sequel/model/associations.rb +3 -0
- data/lib/sequel/model/base.rb +10 -55
- data/lib/sequel/model/dataset_module.rb +5 -43
- data/lib/sequel/model/errors.rb +2 -1
- data/lib/sequel/model/inflections.rb +17 -5
- data/lib/sequel/plugins/active_model.rb +2 -2
- data/lib/sequel/plugins/class_table_inheritance.rb +1 -0
- data/lib/sequel/plugins/composition.rb +2 -2
- data/lib/sequel/plugins/dataset_associations.rb +25 -13
- data/lib/sequel/plugins/json_serializer.rb +2 -2
- data/lib/sequel/plugins/pg_row.rb +4 -2
- data/lib/sequel/plugins/serialization.rb +1 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +6 -1
- data/lib/sequel/plugins/touch.rb +2 -1
- data/lib/sequel/plugins/validation_helpers.rb +10 -2
- data/lib/sequel/sql.rb +16 -7
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +4 -4
- data/spec/adapters/mysql_spec.rb +5 -1
- data/spec/adapters/oracle_spec.rb +4 -0
- data/spec/bin_spec.rb +7 -1
- data/spec/core/connection_pool_spec.rb +28 -14
- data/spec/core/database_spec.rb +149 -0
- data/spec/core/dataset_spec.rb +173 -0
- data/spec/extensions/class_table_inheritance_spec.rb +58 -17
- data/spec/extensions/composition_spec.rb +13 -0
- data/spec/extensions/dataset_associations_spec.rb +12 -0
- data/spec/extensions/many_through_many_spec.rb +4 -4
- data/spec/extensions/null_dataset_spec.rb +1 -1
- data/spec/extensions/serialization_spec.rb +1 -1
- data/spec/extensions/single_table_inheritance_spec.rb +16 -0
- data/spec/extensions/validation_helpers_spec.rb +1 -2
- data/spec/integration/associations_test.rb +8 -0
- data/spec/integration/plugin_test.rb +8 -3
- data/spec/model/association_reflection_spec.rb +1 -1
- data/spec/model/associations_spec.rb +29 -9
- data/spec/model/class_dataset_methods_spec.rb +6 -0
- data/spec/model/eager_loading_spec.rb +8 -8
- data/spec/model/plugins_spec.rb +34 -0
- data/spec/model/record_spec.rb +1 -1
- data/spec/spec_config.rb +2 -0
- metadata +5 -2
@@ -218,7 +218,8 @@ module Sequel
|
|
218
218
|
:user => opts[:user],
|
219
219
|
:password => opts[:password],
|
220
220
|
:connect_timeout => opts[:connect_timeout] || 20,
|
221
|
-
:sslmode => opts[:sslmode]
|
221
|
+
:sslmode => opts[:sslmode],
|
222
|
+
:sslrootcert => opts[:sslrootcert]
|
222
223
|
}.delete_if { |key, value| blank_object?(value) }
|
223
224
|
connection_params.merge!(opts[:driver_options]) if opts[:driver_options]
|
224
225
|
conn = Adapter.connect(connection_params)
|
@@ -841,7 +841,10 @@ module Sequel
|
|
841
841
|
# Transforms an CROSS JOIN to an INNER JOIN if the expr is not nil.
|
842
842
|
# Raises an error on use of :full_outer type, since MySQL doesn't support it.
|
843
843
|
def join_table(type, table, expr=nil, opts=OPTS, &block)
|
844
|
-
|
844
|
+
if (type == :cross) && !expr.nil?
|
845
|
+
Sequel::Deprecation.deprecate(":cross join type with conditions being converted to INNER JOIN on MySQL", "Use :inner join type instead")
|
846
|
+
type = :inner
|
847
|
+
end
|
845
848
|
raise(Sequel::Error, "MySQL doesn't support FULL OUTER JOIN or NATURAL FULL JOIN") if type == :full_outer || type == :natural_full
|
846
849
|
super(type, table, expr, opts, &block)
|
847
850
|
end
|
@@ -348,7 +348,7 @@ module Sequel
|
|
348
348
|
Sequel::Deprecation.deprecate_constant(self, :SKIP_LOCKED)
|
349
349
|
|
350
350
|
include(Module.new do
|
351
|
-
Dataset.def_sql_method(self, :select, %w'with select distinct columns from join where group having compounds order lock')
|
351
|
+
Dataset.def_sql_method(self, :select, %w'with select distinct columns from join where group having compounds order limit lock')
|
352
352
|
end)
|
353
353
|
|
354
354
|
def complex_expression_sql_append(sql, op, args)
|
@@ -421,7 +421,10 @@ module Sequel
|
|
421
421
|
# Handle LIMIT by using a unlimited subselect filtered with ROWNUM.
|
422
422
|
def select_sql
|
423
423
|
return super if @opts[:sql]
|
424
|
-
|
424
|
+
return super if supports_fetch_next_rows?
|
425
|
+
|
426
|
+
o = @opts[:offset]
|
427
|
+
if o && o != 0
|
425
428
|
columns = clone(:append_sql=>String.new, :placeholder_literal_null=>true).columns
|
426
429
|
dsa1 = dataset_alias(1)
|
427
430
|
rn = row_number_column
|
@@ -437,7 +440,7 @@ module Sequel
|
|
437
440
|
subselect_sql_append(sql, ds)
|
438
441
|
sql
|
439
442
|
elsif limit = @opts[:limit]
|
440
|
-
ds =
|
443
|
+
ds = unlimited
|
441
444
|
# Lock doesn't work in subselects, so don't use a subselect when locking.
|
442
445
|
# Don't use a subselect if custom SQL is used, as it breaks somethings.
|
443
446
|
ds = ds.from_self unless @opts[:lock]
|
@@ -449,6 +452,21 @@ module Sequel
|
|
449
452
|
end
|
450
453
|
end
|
451
454
|
|
455
|
+
def select_limit_sql(sql)
|
456
|
+
return unless supports_fetch_next_rows?
|
457
|
+
|
458
|
+
if offset = @opts[:offset]
|
459
|
+
sql << " OFFSET "
|
460
|
+
literal_append(sql, offset)
|
461
|
+
sql << " ROWS"
|
462
|
+
end
|
463
|
+
|
464
|
+
if limit = @opts[:limit]
|
465
|
+
sql << " FETCH NEXT "
|
466
|
+
literal_append(sql, limit)
|
467
|
+
sql << " ROWS ONLY"
|
468
|
+
end
|
469
|
+
end
|
452
470
|
# Oracle requires recursive CTEs to have column aliases.
|
453
471
|
def recursive_cte_requires_column_aliases?
|
454
472
|
true
|
@@ -463,6 +481,11 @@ module Sequel
|
|
463
481
|
false
|
464
482
|
end
|
465
483
|
|
484
|
+
# Oracle supports FETCH NEXT ROWS since 12c
|
485
|
+
def supports_fetch_next_rows?
|
486
|
+
server_version >= 12000000 && !(@opts[:lock] || @opts[:skip_locked])
|
487
|
+
end
|
488
|
+
|
466
489
|
# Oracle supports GROUP BY CUBE
|
467
490
|
def supports_group_cube?
|
468
491
|
true
|
@@ -29,12 +29,15 @@ class Sequel::ConnectionPool
|
|
29
29
|
|
30
30
|
# The default server to use
|
31
31
|
DEFAULT_SERVER = :default
|
32
|
+
Sequel::Deprecation.deprecate_constant(self, :DEFAULT_SERVER)
|
32
33
|
|
33
34
|
# A map of [single threaded, sharded] values to symbols or ConnectionPool subclasses.
|
34
35
|
CONNECTION_POOL_MAP = {[true, false] => :single,
|
35
36
|
[true, true] => :sharded_single,
|
36
37
|
[false, false] => :threaded,
|
37
38
|
[false, true] => :sharded_threaded}
|
39
|
+
CONNECTION_POOL__MAP = CONNECTION_POOL_MAP
|
40
|
+
Sequel::Deprecation.deprecate_constant(self, :CONNECTION_POOL_MAP)
|
38
41
|
|
39
42
|
# Class methods used to return an appropriate pool subclass, separated
|
40
43
|
# into a module for easier overridding by extensions.
|
@@ -57,7 +60,10 @@ class Sequel::ConnectionPool
|
|
57
60
|
|
58
61
|
# Return a connection pool class based on the given options.
|
59
62
|
def connection_pool_class(opts)
|
60
|
-
|
63
|
+
if opts[:pool_class] && !opts[:pool_class].is_a?(Class) && ![:threaded, :single, :sharded_threaded, :sharded_single].include?(opts[:pool_class])
|
64
|
+
Sequel::Deprecation.deprecate("Using an unrecognized :pool_class option", "Use a class for the :pool_class option to select a custom pool class, or one of the following symbols for one of the default pool classes: :threaded, :single, :sharded_threaded, :sharded_single")
|
65
|
+
end
|
66
|
+
CONNECTION_POOL__MAP[opts[:pool_class]] || opts[:pool_class] || CONNECTION_POOL__MAP[[!!opts[:single_threaded], !!opts[:servers]]]
|
61
67
|
end
|
62
68
|
end
|
63
69
|
extend ClassMethods
|
@@ -89,12 +95,13 @@ class Sequel::ConnectionPool
|
|
89
95
|
|
90
96
|
# Alias for +size+, not aliased directly for ease of subclass implementation
|
91
97
|
def created_count(*args)
|
98
|
+
Sequel::Deprecation.deprecate("Sequel::ConnectionPool#created_count", "Use #size instead")
|
92
99
|
size(*args)
|
93
100
|
end
|
94
101
|
|
95
102
|
# An array of symbols for all shards/servers, which is a single <tt>:default</tt> by default.
|
96
103
|
def servers
|
97
|
-
[
|
104
|
+
[:default]
|
98
105
|
end
|
99
106
|
|
100
107
|
private
|
@@ -26,7 +26,7 @@ class Sequel::SingleConnectionPool < Sequel::ConnectionPool
|
|
26
26
|
def hold(server=nil)
|
27
27
|
begin
|
28
28
|
unless c = @conn.first
|
29
|
-
@conn.replace([c = make_new(
|
29
|
+
@conn.replace([c = make_new(:default)])
|
30
30
|
end
|
31
31
|
yield c
|
32
32
|
rescue Sequel::DatabaseDisconnectError, *@error_classes => e
|
@@ -57,5 +57,5 @@ class Sequel::SingleConnectionPool < Sequel::ConnectionPool
|
|
57
57
|
hold{}
|
58
58
|
end
|
59
59
|
|
60
|
-
|
60
|
+
CONNECTION_POOL__MAP[[true, false]] = self
|
61
61
|
end
|
@@ -198,7 +198,7 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
198
198
|
# available, tries to create a new connection. The calling code should already
|
199
199
|
# have the mutex before calling this.
|
200
200
|
def available
|
201
|
-
next_available || make_new(
|
201
|
+
next_available || make_new(:default)
|
202
202
|
end
|
203
203
|
|
204
204
|
# Return a connection to the pool of available connections, returns the connection.
|
@@ -282,5 +282,5 @@ class Sequel::ThreadedConnectionPool < Sequel::ConnectionPool
|
|
282
282
|
@mutex.synchronize{yield}
|
283
283
|
end
|
284
284
|
|
285
|
-
|
285
|
+
CONNECTION_POOL__MAP[[false, false]] = self
|
286
286
|
end
|
@@ -220,14 +220,14 @@ module Sequel
|
|
220
220
|
|
221
221
|
# Disconnects all available connections from the connection pool. Any
|
222
222
|
# connections currently in use will not be disconnected. Options:
|
223
|
-
# :
|
223
|
+
# :server :: Should be a symbol specifing the server to disconnect from,
|
224
224
|
# or an array of symbols to specify multiple servers.
|
225
225
|
#
|
226
226
|
# Example:
|
227
227
|
#
|
228
228
|
# DB.disconnect # All servers
|
229
|
-
# DB.disconnect(:
|
230
|
-
# DB.disconnect(:
|
229
|
+
# DB.disconnect(:server=>:server1) # Single server
|
230
|
+
# DB.disconnect(:server=>[:server1, :server2]) # Multiple servers
|
231
231
|
def disconnect(opts = OPTS)
|
232
232
|
pool.disconnect(opts)
|
233
233
|
end
|
@@ -69,6 +69,9 @@ module Sequel
|
|
69
69
|
# This allows you to override any of the dataset methods even if they are
|
70
70
|
# defined directly on the dataset class that this Database object uses.
|
71
71
|
#
|
72
|
+
# If a block is given, a Dataset::DatasetModule instance is created, allowing
|
73
|
+
# for the easy creation of named dataset methods that will do caching.
|
74
|
+
#
|
72
75
|
# Examples:
|
73
76
|
#
|
74
77
|
# # Introspec columns for all of DB's datasets
|
@@ -82,9 +85,19 @@ module Sequel
|
|
82
85
|
# super
|
83
86
|
# end
|
84
87
|
# end
|
88
|
+
#
|
89
|
+
# # Add some named dataset methods
|
90
|
+
# DB.extend_datasets do
|
91
|
+
# order :by_id, :id
|
92
|
+
# select :with_id_and_name, :id, :name
|
93
|
+
# where :active, :active
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# DB[:table].active.with_id_and_name.by_id
|
97
|
+
# # SELECT id, name FROM table WHERE active ORDER BY id
|
85
98
|
def extend_datasets(mod=nil, &block)
|
86
99
|
raise(Error, "must provide either mod or block, not both") if mod && block
|
87
|
-
mod =
|
100
|
+
mod = Dataset::DatasetModule.new(&block) if block
|
88
101
|
if @dataset_modules.empty?
|
89
102
|
@dataset_modules = [mod]
|
90
103
|
@dataset_class = Class.new(@dataset_class)
|
data/lib/sequel/dataset.rb
CHANGED
@@ -42,5 +42,5 @@ module Sequel
|
|
42
42
|
include SQL::StringMethods
|
43
43
|
end
|
44
44
|
|
45
|
-
require(%w"query actions features graph prepared_statements misc mutation sql placeholder_literalizer", 'dataset')
|
45
|
+
require(%w"query actions features graph prepared_statements misc mutation sql placeholder_literalizer dataset_module", 'dataset')
|
46
46
|
end
|
@@ -15,6 +15,7 @@ module Sequel
|
|
15
15
|
empty? fetch_rows first first! get import insert interval last
|
16
16
|
map max min multi_insert paged_each range select_hash select_hash_groups select_map select_order_map
|
17
17
|
single_record single_record! single_value single_value! sum to_hash to_hash_groups truncate update
|
18
|
+
where_all where_each where_single_value
|
18
19
|
METHS
|
19
20
|
# SEQUEL5: Remove interval, range
|
20
21
|
|
@@ -917,6 +918,52 @@ module Sequel
|
|
917
918
|
end
|
918
919
|
end
|
919
920
|
|
921
|
+
# Return an array of all rows matching the given filter condition, also
|
922
|
+
# yielding each row to the given block. Basically the same as where(cond).all(&block),
|
923
|
+
# except it can be optimized to not create an intermediate dataset.
|
924
|
+
#
|
925
|
+
# DB[:table].where_all(:id=>[1,2,3])
|
926
|
+
# # SELECT * FROM table WHERE (id IN (1, 2, 3))
|
927
|
+
def where_all(cond, &block)
|
928
|
+
if loader = _where_loader
|
929
|
+
loader.all(filter_expr(cond), &block)
|
930
|
+
else
|
931
|
+
where(cond).all(&block)
|
932
|
+
end
|
933
|
+
end
|
934
|
+
|
935
|
+
# Iterate over all rows matching the given filter condition,
|
936
|
+
# yielding each row to the given block. Basically the same as where(cond).each(&block),
|
937
|
+
# except it can be optimized to not create an intermediate dataset.
|
938
|
+
#
|
939
|
+
# DB[:table].where_each(:id=>[1,2,3]){|row| p row}
|
940
|
+
# # SELECT * FROM table WHERE (id IN (1, 2, 3))
|
941
|
+
def where_each(cond, &block)
|
942
|
+
if loader = _where_loader
|
943
|
+
loader.each(filter_expr(cond), &block)
|
944
|
+
else
|
945
|
+
where(cond).each(&block)
|
946
|
+
end
|
947
|
+
end
|
948
|
+
|
949
|
+
# Filter the datasets using the given filter condition, then return a single value.
|
950
|
+
# This assumes that the dataset has already been setup to limit the selection to
|
951
|
+
# a single column. Basically the same as where(cond).single_value,
|
952
|
+
# except it can be optimized to not create an intermediate dataset.
|
953
|
+
#
|
954
|
+
# DB[:table].select(:name).where_single_value(:id=>1)
|
955
|
+
# # SELECT name FROM table WHERE (id = 1) LIMIT 1
|
956
|
+
def where_single_value(cond)
|
957
|
+
if loader = cached_placeholder_literalizer(:_where_single_value_loader) do |pl|
|
958
|
+
single_value_ds.where(pl.arg)
|
959
|
+
end
|
960
|
+
|
961
|
+
loader.get(filter_expr(cond))
|
962
|
+
else
|
963
|
+
where(cond).single_value
|
964
|
+
end
|
965
|
+
end
|
966
|
+
|
920
967
|
# Run the given SQL and return an array of all rows. If a block is given,
|
921
968
|
# each row is yielded to the block after all rows are loaded. See with_sql_each.
|
922
969
|
def with_sql_all(sql, &block)
|
@@ -1044,6 +1091,13 @@ module Sequel
|
|
1044
1091
|
cached_dataset(:_single_record_ds){clone(:limit=>1)}
|
1045
1092
|
end
|
1046
1093
|
|
1094
|
+
# Loader used for where_all and where_each.
|
1095
|
+
def _where_loader
|
1096
|
+
cached_placeholder_literalizer(:_where_loader) do |pl|
|
1097
|
+
where(pl.arg)
|
1098
|
+
end
|
1099
|
+
end
|
1100
|
+
|
1047
1101
|
# Automatically alias the given expression if it does not have an identifiable alias.
|
1048
1102
|
def auto_alias_expression(v)
|
1049
1103
|
case v
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
module Sequel
|
4
|
+
class Dataset
|
5
|
+
# This Module subclass is used by Database#extend_datasets
|
6
|
+
# and Dataset#with_extend to add dataset methods to classes.
|
7
|
+
# It adds some helper methods inside the module that can define
|
8
|
+
# named methods on the dataset instances which do specific actions.
|
9
|
+
# For example:
|
10
|
+
#
|
11
|
+
# DB.extend_datasets do
|
12
|
+
# order :by_id, :id
|
13
|
+
# select :with_id_and_name, :id, :name
|
14
|
+
# where :active, :active
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# DB[:table].active.with_id_and_name.by_id
|
18
|
+
# # SELECT id, name FROM table WHERE active ORDER BY id
|
19
|
+
class DatasetModule < ::Module
|
20
|
+
%w'where exclude exclude_having having'.map(&:to_sym).each do |meth|
|
21
|
+
define_method(meth) do |name, *args, &block|
|
22
|
+
if block || args.flatten.any?{|arg| arg.is_a?(Proc)}
|
23
|
+
define_method(name){send(meth, *args, &block)}
|
24
|
+
else
|
25
|
+
key = :"_#{meth}_#{name}_ds"
|
26
|
+
define_method(name) do
|
27
|
+
cached_dataset(key){send(meth, *args)}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
meths = (<<-METHS).split.map(&:to_sym)
|
34
|
+
distinct grep group group_and_count group_append
|
35
|
+
limit offset order order_append order_prepend
|
36
|
+
select select_all select_append select_group server
|
37
|
+
METHS
|
38
|
+
|
39
|
+
# Define a method in the module
|
40
|
+
def self.def_dataset_caching_method(mod, meth)
|
41
|
+
mod.send(:define_method, meth) do |name, *args, &block|
|
42
|
+
if block
|
43
|
+
define_method(name){send(meth, *args, &block)}
|
44
|
+
else
|
45
|
+
key = :"_#{meth}_#{name}_ds"
|
46
|
+
define_method(name) do
|
47
|
+
cached_dataset(key){send(meth, *args)}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
meths.each do |meth|
|
54
|
+
def_dataset_caching_method(self, meth)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/sequel/dataset/query.rb
CHANGED
@@ -1087,12 +1087,12 @@ module Sequel
|
|
1087
1087
|
# Return a clone of the dataset extended with the given modules.
|
1088
1088
|
# Note that like Object#extend, when multiple modules are provided
|
1089
1089
|
# as arguments the cloned dataset is extended with the modules in reverse
|
1090
|
-
# order. If a block is provided, a
|
1090
|
+
# order. If a block is provided, a DatasetModule is created using the block and
|
1091
1091
|
# the clone is extended with that module after any modules given as arguments.
|
1092
1092
|
def with_extend(*mods, &block)
|
1093
1093
|
c = _clone(:freeze=>false)
|
1094
1094
|
c.extend(*mods) unless mods.empty?
|
1095
|
-
c.extend(
|
1095
|
+
c.extend(DatasetModule.new(&block)) if block
|
1096
1096
|
c.freeze if frozen? # SEQUEL5: Remove if frozen?
|
1097
1097
|
c
|
1098
1098
|
end
|
@@ -1101,7 +1101,7 @@ module Sequel
|
|
1101
1101
|
def with_extend(*mods, &block) # :nodoc:
|
1102
1102
|
c = clone
|
1103
1103
|
c.extend(*mods) unless mods.empty?
|
1104
|
-
c.extend(
|
1104
|
+
c.extend(DatasetModule.new(&block)) if block
|
1105
1105
|
c
|
1106
1106
|
end
|
1107
1107
|
# :nocov:
|
data/lib/sequel/exceptions.rb
CHANGED
@@ -7,6 +7,14 @@ module Sequel
|
|
7
7
|
# If this exception wraps an underlying exception, the underlying
|
8
8
|
# exception is held here.
|
9
9
|
attr_accessor :wrapped_exception
|
10
|
+
|
11
|
+
if RUBY_VERSION >= '2.1'
|
12
|
+
# Returned the wrapped exception if one exists, otherwise use
|
13
|
+
# ruby's default behavior.
|
14
|
+
def cause
|
15
|
+
wrapped_exception || super
|
16
|
+
end
|
17
|
+
end
|
10
18
|
end
|
11
19
|
|
12
20
|
(
|
@@ -5,14 +5,17 @@ module Sequel
|
|
5
5
|
module PgRow
|
6
6
|
module DatabaseMethods
|
7
7
|
ESCAPE_RE = /("|\\)/.freeze
|
8
|
+
Sequel::Deprecation.deprecate_constant(self, :ESCAPE_RE)
|
8
9
|
ESCAPE_REPLACEMENT = '\\\\\1'.freeze
|
10
|
+
Sequel::Deprecation.deprecate_constant(self, :ESCAPE_REPLACEMENT)
|
9
11
|
COMMA = ','
|
12
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA)
|
10
13
|
|
11
14
|
# Handle Sequel::Model instances in bound variables.
|
12
15
|
def bound_variable_arg(arg, conn)
|
13
16
|
case arg
|
14
17
|
when Sequel::Model
|
15
|
-
"(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(
|
18
|
+
"(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(',')})"
|
16
19
|
else
|
17
20
|
super
|
18
21
|
end
|
@@ -34,7 +37,7 @@ module Sequel
|
|
34
37
|
def bound_variable_array(arg)
|
35
38
|
case arg
|
36
39
|
when Sequel::Model
|
37
|
-
"\"(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(
|
40
|
+
"\"(#{arg.values.values_at(*arg.columns).map{|v| bound_variable_array(v)}.join(',').gsub(/("|\\)/, '\\\\\1')})\""
|
38
41
|
else
|
39
42
|
super
|
40
43
|
end
|
@@ -32,7 +32,7 @@ module Sequel
|
|
32
32
|
# Return an instance of Sequel.datetime_class that will be literalized
|
33
33
|
# as CURRENT_TIMESTAMP.
|
34
34
|
def current_datetime
|
35
|
-
|
35
|
+
(Sequel.datetime_class == ::Time ? Time : DateTime).now
|
36
36
|
end
|
37
37
|
|
38
38
|
private
|
@@ -56,6 +56,7 @@ module Sequel
|
|
56
56
|
|
57
57
|
# Mapping of Time/DateTime classes to subclasses literalized as CURRENT_TIMESTAMP
|
58
58
|
MAP = {::Time=>Time, ::DateTime=>DateTime}
|
59
|
+
Sequel::Deprecation.deprecate_constant(self, :MAP)
|
59
60
|
end
|
60
61
|
|
61
62
|
Dataset.register_extension(:current_datetime_timestamp, CurrentDateTimeTimestamp::DatasetMethods)
|