sequel 4.48.0 → 4.49.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|