sequel 5.59.0 → 5.60.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 +10 -0
- data/README.rdoc +1 -1
- data/bin/sequel +11 -3
- data/doc/release_notes/5.60.0.txt +22 -0
- data/lib/sequel/adapters/jdbc/sqlite.rb +1 -1
- data/lib/sequel/adapters/jdbc.rb +5 -5
- data/lib/sequel/adapters/mock.rb +1 -1
- data/lib/sequel/adapters/mysql.rb +3 -3
- data/lib/sequel/adapters/oracle.rb +1 -1
- data/lib/sequel/adapters/postgres.rb +46 -11
- data/lib/sequel/adapters/shared/mssql.rb +1 -1
- data/lib/sequel/adapters/shared/oracle.rb +1 -1
- data/lib/sequel/adapters/shared/postgres.rb +26 -14
- data/lib/sequel/adapters/shared/sqlite.rb +1 -1
- data/lib/sequel/adapters/sqlite.rb +1 -1
- data/lib/sequel/ast_transformer.rb +1 -1
- data/lib/sequel/database/misc.rb +2 -2
- data/lib/sequel/dataset/sql.rb +2 -2
- data/lib/sequel/extensions/date_arithmetic.rb +35 -7
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -1
- data/lib/sequel/extensions/is_distinct_from.rb +3 -1
- data/lib/sequel/extensions/pg_array.rb +2 -2
- data/lib/sequel/extensions/pg_array_ops.rb +1 -1
- data/lib/sequel/extensions/pg_enum.rb +1 -1
- data/lib/sequel/extensions/pg_hstore_ops.rb +3 -3
- data/lib/sequel/extensions/pg_inet.rb +2 -2
- data/lib/sequel/extensions/pg_interval.rb +1 -1
- data/lib/sequel/extensions/pg_json.rb +1 -1
- data/lib/sequel/extensions/pg_json_ops.rb +3 -3
- data/lib/sequel/extensions/pg_multirange.rb +2 -2
- data/lib/sequel/extensions/pg_range.rb +2 -2
- data/lib/sequel/extensions/pg_row.rb +2 -2
- data/lib/sequel/extensions/pg_static_cache_updater.rb +2 -2
- data/lib/sequel/extensions/symbol_aref.rb +2 -0
- data/lib/sequel/model/associations.rb +6 -6
- data/lib/sequel/model/base.rb +3 -3
- data/lib/sequel/model/exceptions.rb +1 -1
- data/lib/sequel/model/inflections.rb +6 -6
- data/lib/sequel/plugins/auto_validations.rb +1 -1
- data/lib/sequel/plugins/defaults_setter.rb +1 -1
- data/lib/sequel/plugins/dirty.rb +1 -1
- data/lib/sequel/plugins/insert_conflict.rb +1 -1
- data/lib/sequel/plugins/json_serializer.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/pg_auto_constraint_validations.rb +1 -1
- data/lib/sequel/plugins/serialization.rb +1 -1
- data/lib/sequel/plugins/sharding.rb +1 -1
- data/lib/sequel/plugins/sql_comments.rb +4 -4
- data/lib/sequel/plugins/subclasses.rb +1 -1
- data/lib/sequel/plugins/validation_class_methods.rb +3 -3
- data/lib/sequel/plugins/validation_helpers.rb +1 -1
- data/lib/sequel/sql.rb +1 -1
- data/lib/sequel/version.rb +1 -1
- metadata +4 -2
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
#
|
|
33
33
|
# DB[:table].select(add.as(:d)).where(sub > Sequel::CURRENT_TIMESTAMP)
|
|
34
34
|
#
|
|
35
|
+
# On most databases, the values you provide for years/months/days/etc. must
|
|
36
|
+
# be numeric values and not arbitrary SQL expressions. However, on PostgreSQL
|
|
37
|
+
# 9.4+, use of arbitrary SQL expressions is supported.
|
|
38
|
+
#
|
|
35
39
|
# Related module: Sequel::SQL::DateAdd
|
|
36
40
|
|
|
37
41
|
#
|
|
@@ -54,7 +58,16 @@ module Sequel
|
|
|
54
58
|
interval = interval.parts
|
|
55
59
|
end
|
|
56
60
|
parts = {}
|
|
57
|
-
interval.each
|
|
61
|
+
interval.each do |k,v|
|
|
62
|
+
case v
|
|
63
|
+
when nil
|
|
64
|
+
# ignore
|
|
65
|
+
when Numeric
|
|
66
|
+
parts[k] = -v
|
|
67
|
+
else
|
|
68
|
+
parts[k] = Sequel::SQL::NumericExpression.new(:*, v, -1)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
58
71
|
DateAdd.new(expr, parts, opts)
|
|
59
72
|
end
|
|
60
73
|
end
|
|
@@ -68,6 +81,7 @@ module Sequel
|
|
|
68
81
|
module DatasetMethods
|
|
69
82
|
DURATION_UNITS = [:years, :months, :days, :hours, :minutes, :seconds].freeze
|
|
70
83
|
DEF_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| s.to_s.freeze}).freeze
|
|
84
|
+
POSTGRES_DURATION_UNITS = DURATION_UNITS.zip([:years, :months, :days, :hours, :mins, :secs].map{|s| s.to_s.freeze}).freeze
|
|
71
85
|
MYSQL_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s.upcase[0...-1]).freeze}).freeze
|
|
72
86
|
MSSQL_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| Sequel.lit(s.to_s[0...-1]).freeze}).freeze
|
|
73
87
|
H2_DURATION_UNITS = DURATION_UNITS.zip(DURATION_UNITS.map{|s| s.to_s[0...-1].freeze}).freeze
|
|
@@ -87,14 +101,28 @@ module Sequel
|
|
|
87
101
|
|
|
88
102
|
cast = case db_type = db.database_type
|
|
89
103
|
when :postgres
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
104
|
+
casted = Sequel.cast(expr, cast_type)
|
|
105
|
+
|
|
106
|
+
if db.server_version >= 90400
|
|
107
|
+
placeholder = []
|
|
108
|
+
vals = []
|
|
109
|
+
each_valid_interval_unit(h, POSTGRES_DURATION_UNITS) do |value, sql_unit|
|
|
110
|
+
placeholder << "#{', ' unless placeholder.empty?}#{sql_unit} := "
|
|
111
|
+
vals << value
|
|
112
|
+
end
|
|
113
|
+
interval = Sequel.function(:make_interval, Sequel.lit(placeholder, *vals)) unless vals.empty?
|
|
114
|
+
else
|
|
115
|
+
parts = String.new
|
|
116
|
+
each_valid_interval_unit(h, DEF_DURATION_UNITS) do |value, sql_unit|
|
|
117
|
+
parts << "#{value} #{sql_unit} "
|
|
118
|
+
end
|
|
119
|
+
interval = Sequel.cast(parts, :interval) unless parts.empty?
|
|
93
120
|
end
|
|
94
|
-
|
|
95
|
-
|
|
121
|
+
|
|
122
|
+
if interval
|
|
123
|
+
return complex_expression_sql_append(sql, :+, [casted, interval])
|
|
96
124
|
else
|
|
97
|
-
return
|
|
125
|
+
return literal_append(sql, casted)
|
|
98
126
|
end
|
|
99
127
|
when :sqlite
|
|
100
128
|
args = [expr]
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# The is_distinct_from extension adds the ability to use the
|
|
4
4
|
# SQL standard IS DISTINCT FROM operator, which is similar to the
|
|
5
5
|
# not equals operator, except that NULL values are considered
|
|
6
|
-
# equal.
|
|
6
|
+
# equal. PostgreSQL, SQLite 3.39+, and H2 currently support this operator. On
|
|
7
7
|
# other databases, support is emulated.
|
|
8
8
|
#
|
|
9
9
|
# First, you need to load the extension into the database:
|
|
@@ -90,6 +90,8 @@ module Sequel
|
|
|
90
90
|
case db.database_type
|
|
91
91
|
when :postgres, :h2
|
|
92
92
|
true
|
|
93
|
+
when :sqlite
|
|
94
|
+
db.sqlite_version >= 33900
|
|
93
95
|
else
|
|
94
96
|
false
|
|
95
97
|
end
|
|
@@ -301,7 +301,7 @@ module Sequel
|
|
|
301
301
|
end
|
|
302
302
|
end
|
|
303
303
|
|
|
304
|
-
unless Sequel::Postgres.
|
|
304
|
+
unless defined?(Sequel::Postgres.parse_pg_array)
|
|
305
305
|
require 'strscan'
|
|
306
306
|
|
|
307
307
|
# PostgreSQL array parser that handles PostgreSQL array output format.
|
|
@@ -412,7 +412,7 @@ module Sequel
|
|
|
412
412
|
@converter = converter
|
|
413
413
|
end
|
|
414
414
|
|
|
415
|
-
if Sequel::Postgres.
|
|
415
|
+
if defined?(Sequel::Postgres.parse_pg_array)
|
|
416
416
|
# :nocov:
|
|
417
417
|
# Use sequel_pg's C-based parser if it has already been defined.
|
|
418
418
|
def call(string)
|
|
@@ -144,7 +144,7 @@ module Sequel
|
|
|
144
144
|
select_hash_groups(Sequel.cast(:enumtypid, Integer).as(:v), :enumlabel).freeze
|
|
145
145
|
enum_labels.each_value(&:freeze)
|
|
146
146
|
|
|
147
|
-
if
|
|
147
|
+
if defined?(register_array_type)
|
|
148
148
|
array_types = metadata_dataset.
|
|
149
149
|
from(:pg_type).
|
|
150
150
|
where(:oid=>enum_labels.keys).
|
|
@@ -296,7 +296,7 @@ module Sequel
|
|
|
296
296
|
|
|
297
297
|
# Wrap argument in a PGArray if it is an array
|
|
298
298
|
def wrap_input_array(obj)
|
|
299
|
-
if obj.is_a?(Array) && Sequel.
|
|
299
|
+
if obj.is_a?(Array) && defined?(Sequel.pg_array)
|
|
300
300
|
Sequel.pg_array(obj)
|
|
301
301
|
else
|
|
302
302
|
obj
|
|
@@ -305,7 +305,7 @@ module Sequel
|
|
|
305
305
|
|
|
306
306
|
# Wrap argument in an Hstore if it is a hash
|
|
307
307
|
def wrap_input_hash(obj)
|
|
308
|
-
if obj.is_a?(Hash) && Sequel.
|
|
308
|
+
if obj.is_a?(Hash) && defined?(Sequel.hstore)
|
|
309
309
|
Sequel.hstore(obj)
|
|
310
310
|
else
|
|
311
311
|
obj
|
|
@@ -314,7 +314,7 @@ module Sequel
|
|
|
314
314
|
|
|
315
315
|
# Wrap argument in a PGArrayOp if supported
|
|
316
316
|
def wrap_output_array(obj)
|
|
317
|
-
if Sequel.
|
|
317
|
+
if defined?(Sequel.pg_array_op)
|
|
318
318
|
Sequel.pg_array_op(obj)
|
|
319
319
|
else
|
|
320
320
|
obj
|
|
@@ -49,13 +49,13 @@ module Sequel
|
|
|
49
49
|
meth = IPAddr.method(:new)
|
|
50
50
|
add_conversion_proc(869, meth)
|
|
51
51
|
add_conversion_proc(650, meth)
|
|
52
|
-
if
|
|
52
|
+
if defined?(register_array_type)
|
|
53
53
|
register_array_type('inet', :oid=>1041, :scalar_oid=>869)
|
|
54
54
|
register_array_type('cidr', :oid=>651, :scalar_oid=>650)
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
if
|
|
58
|
+
if defined?(register_array_type)
|
|
59
59
|
register_array_type('macaddr', :oid=>1040, :scalar_oid=>829)
|
|
60
60
|
end
|
|
61
61
|
@schema_type_classes[:ipaddr] = IPAddr
|
|
@@ -144,7 +144,7 @@ module Sequel
|
|
|
144
144
|
db.instance_exec do
|
|
145
145
|
extend_datasets(IntervalDatasetMethods)
|
|
146
146
|
add_conversion_proc(1186, Postgres::IntervalDatabaseMethods::PARSER)
|
|
147
|
-
if
|
|
147
|
+
if defined?(register_array_type)
|
|
148
148
|
register_array_type('interval', :oid=>1187, :scalar_oid=>1186)
|
|
149
149
|
end
|
|
150
150
|
@schema_type_classes[:interval] = ActiveSupport::Duration
|
|
@@ -227,7 +227,7 @@ module Sequel
|
|
|
227
227
|
db.instance_exec do
|
|
228
228
|
add_conversion_proc(114, method(:_db_parse_json))
|
|
229
229
|
add_conversion_proc(3802, method(:_db_parse_jsonb))
|
|
230
|
-
if
|
|
230
|
+
if defined?(register_array_type)
|
|
231
231
|
register_array_type('json', :oid=>199, :scalar_oid=>114)
|
|
232
232
|
register_array_type('jsonb', :oid=>3807, :scalar_oid=>3802)
|
|
233
233
|
end
|
|
@@ -358,7 +358,7 @@ module Sequel
|
|
|
358
358
|
# Automatically wrap argument in a PGArray if it is a plain Array.
|
|
359
359
|
# Requires that the pg_array extension has been loaded to work.
|
|
360
360
|
def wrap_array(arg)
|
|
361
|
-
if arg.instance_of?(Array) && Sequel.
|
|
361
|
+
if arg.instance_of?(Array) && defined?(Sequel.pg_array)
|
|
362
362
|
Sequel.pg_array(arg)
|
|
363
363
|
else
|
|
364
364
|
arg
|
|
@@ -652,7 +652,7 @@ module Sequel
|
|
|
652
652
|
|
|
653
653
|
# Wrap argument in a PGArray if it is an array
|
|
654
654
|
def wrap_input_array(obj)
|
|
655
|
-
if obj.is_a?(Array) && Sequel.
|
|
655
|
+
if obj.is_a?(Array) && defined?(Sequel.pg_array)
|
|
656
656
|
Sequel.pg_array(obj)
|
|
657
657
|
else
|
|
658
658
|
obj
|
|
@@ -661,7 +661,7 @@ module Sequel
|
|
|
661
661
|
|
|
662
662
|
# Wrap argument in a JSONBArray or JSONBHash if it is an array or hash.
|
|
663
663
|
def wrap_input_jsonb(obj)
|
|
664
|
-
if Sequel.
|
|
664
|
+
if defined?(Sequel.pg_jsonb) && (obj.is_a?(Array) || obj.is_a?(Hash))
|
|
665
665
|
Sequel.pg_jsonb(obj)
|
|
666
666
|
else
|
|
667
667
|
obj
|
|
@@ -124,7 +124,7 @@ module Sequel
|
|
|
124
124
|
register_multirange_type('datemultirange', :range_oid=>3912, :oid=>4535)
|
|
125
125
|
register_multirange_type('int8multirange', :range_oid=>3926, :oid=>4536)
|
|
126
126
|
|
|
127
|
-
if
|
|
127
|
+
if defined?(register_array_type)
|
|
128
128
|
register_array_type('int4multirange', :oid=>6150, :scalar_oid=>4451, :scalar_typecast=>:int4multirange)
|
|
129
129
|
register_array_type('nummultirange', :oid=>6151, :scalar_oid=>4532, :scalar_typecast=>:nummultirange)
|
|
130
130
|
register_array_type('tsmultirange', :oid=>6152, :scalar_oid=>4533, :scalar_typecast=>:tsmultirange)
|
|
@@ -141,7 +141,7 @@ module Sequel
|
|
|
141
141
|
add_conversion_proc(4533, PGMultiRange::Creator.new("tsmultirange", procs[3908]))
|
|
142
142
|
add_conversion_proc(4534, PGMultiRange::Creator.new("tstzmultirange", procs[3910]))
|
|
143
143
|
|
|
144
|
-
if
|
|
144
|
+
if defined?(register_array_type) && defined?(PGArray::Creator)
|
|
145
145
|
add_conversion_proc(6152, PGArray::Creator.new("tsmultirange", procs[4533]))
|
|
146
146
|
add_conversion_proc(6153, PGArray::Creator.new("tstzmultirange", procs[4534]))
|
|
147
147
|
end
|
|
@@ -139,7 +139,7 @@ module Sequel
|
|
|
139
139
|
register_range_type('tstzrange', :oid=>3910, :subtype_oid=>1184)
|
|
140
140
|
register_range_type('daterange', :oid=>3912, :subtype_oid=>1082)
|
|
141
141
|
register_range_type('int8range', :oid=>3926, :subtype_oid=>20)
|
|
142
|
-
if
|
|
142
|
+
if defined?(register_array_type)
|
|
143
143
|
register_array_type('int4range', :oid=>3905, :scalar_oid=>3904, :scalar_typecast=>:int4range)
|
|
144
144
|
register_array_type('numrange', :oid=>3907, :scalar_oid=>3906, :scalar_typecast=>:numrange)
|
|
145
145
|
register_array_type('tsrange', :oid=>3909, :scalar_oid=>3908, :scalar_typecast=>:tsrange)
|
|
@@ -154,7 +154,7 @@ module Sequel
|
|
|
154
154
|
procs = conversion_procs
|
|
155
155
|
add_conversion_proc(3908, Parser.new("tsrange", procs[1114]))
|
|
156
156
|
add_conversion_proc(3910, Parser.new("tstzrange", procs[1184]))
|
|
157
|
-
if
|
|
157
|
+
if defined?(register_array_type) && defined?(PGArray::Creator)
|
|
158
158
|
add_conversion_proc(3909, PGArray::Creator.new("tsrange", procs[3908]))
|
|
159
159
|
add_conversion_proc(3911, PGArray::Creator.new("tstzrange", procs[3910]))
|
|
160
160
|
end
|
|
@@ -375,7 +375,7 @@ module Sequel
|
|
|
375
375
|
@row_schema_types = {}
|
|
376
376
|
extend(@row_type_method_module = Module.new)
|
|
377
377
|
add_conversion_proc(2249, PGRow::Parser.new(:converter=>PGRow::ArrayRow))
|
|
378
|
-
if
|
|
378
|
+
if defined?(register_array_type)
|
|
379
379
|
register_array_type('record', :oid=>2287, :scalar_oid=>2249)
|
|
380
380
|
end
|
|
381
381
|
end
|
|
@@ -464,7 +464,7 @@ module Sequel
|
|
|
464
464
|
parser = Parser.new(parser_opts)
|
|
465
465
|
add_conversion_proc(parser.oid, parser)
|
|
466
466
|
|
|
467
|
-
if
|
|
467
|
+
if defined?(register_array_type) && array_oid && array_oid > 0
|
|
468
468
|
array_type_name = if type_schema
|
|
469
469
|
"#{type_schema}.#{type_name}"
|
|
470
470
|
else
|
|
@@ -115,13 +115,13 @@ SQL
|
|
|
115
115
|
# :before_thread_exit :: An object that responds to +call+ that is called before the
|
|
116
116
|
# the created thread exits.
|
|
117
117
|
def listen_for_static_cache_updates(models, opts=OPTS)
|
|
118
|
-
raise Error, "this database object does not respond to listen, use the postgres adapter with the pg driver" unless
|
|
118
|
+
raise Error, "this database object does not respond to listen, use the postgres adapter with the pg driver" unless defined?(listen)
|
|
119
119
|
models = [models] unless models.is_a?(Array)
|
|
120
120
|
raise Error, "array of models to listen for changes cannot be empty" if models.empty?
|
|
121
121
|
|
|
122
122
|
oid_map = {}
|
|
123
123
|
models.each do |model|
|
|
124
|
-
raise Error, "#{model.inspect} does not use the static_cache plugin" unless model.
|
|
124
|
+
raise Error, "#{model.inspect} does not use the static_cache plugin" unless defined?(model.load_cache)
|
|
125
125
|
oid_map[get(regclass_oid(model.dataset.first_source_table))] = model
|
|
126
126
|
end
|
|
127
127
|
|
|
@@ -3016,7 +3016,7 @@ module Sequel
|
|
|
3016
3016
|
def complex_expression_sql_append(sql, op, args)
|
|
3017
3017
|
r = args[1]
|
|
3018
3018
|
if (((op == :'=' || op == :'!=') && r.is_a?(Sequel::Model)) ||
|
|
3019
|
-
(multiple = ((op == :IN || op == :'NOT IN') && ((is_ds = r.is_a?(Sequel::Dataset)) || (r.
|
|
3019
|
+
(multiple = ((op == :IN || op == :'NOT IN') && ((is_ds = r.is_a?(Sequel::Dataset)) || (defined?(r.all?) && r.all?{|x| x.is_a?(Sequel::Model)})))))
|
|
3020
3020
|
l = args[0]
|
|
3021
3021
|
if ar = model.association_reflections[l]
|
|
3022
3022
|
raise Error, "filtering by associations is not allowed for #{ar.inspect}" if ar[:allow_filtering_by] == false
|
|
@@ -3024,7 +3024,7 @@ module Sequel
|
|
|
3024
3024
|
if multiple
|
|
3025
3025
|
klass = ar.associated_class
|
|
3026
3026
|
if is_ds
|
|
3027
|
-
if r.
|
|
3027
|
+
if defined?(r.model)
|
|
3028
3028
|
unless r.model <= klass
|
|
3029
3029
|
# A dataset for a different model class, could be a valid regular query
|
|
3030
3030
|
return super
|
|
@@ -3356,10 +3356,10 @@ module Sequel
|
|
|
3356
3356
|
assoc_table_alias = ds.unused_table_alias(alias_base)
|
|
3357
3357
|
loader = r[:eager_grapher]
|
|
3358
3358
|
if !associations.empty?
|
|
3359
|
-
if associations.first.
|
|
3359
|
+
if defined?(associations.first.call)
|
|
3360
3360
|
callback = associations.first
|
|
3361
3361
|
associations = {}
|
|
3362
|
-
elsif associations.length == 1 && (assocs = associations.first).is_a?(Hash) && assocs.length == 1 && (pr_assoc = assocs.to_a.first) && pr_assoc.first.
|
|
3362
|
+
elsif associations.length == 1 && (assocs = associations.first).is_a?(Hash) && assocs.length == 1 && (pr_assoc = assocs.to_a.first) && defined?(pr_assoc.first.call)
|
|
3363
3363
|
callback, assoc = pr_assoc
|
|
3364
3364
|
associations = assoc.is_a?(Array) ? assoc : [assoc]
|
|
3365
3365
|
end
|
|
@@ -3601,10 +3601,10 @@ module Sequel
|
|
|
3601
3601
|
end
|
|
3602
3602
|
|
|
3603
3603
|
associations = eager_assoc[r[:name]]
|
|
3604
|
-
if associations.
|
|
3604
|
+
if defined?(associations.call)
|
|
3605
3605
|
eager_block = associations
|
|
3606
3606
|
associations = OPTS
|
|
3607
|
-
elsif associations.is_a?(Hash) && associations.length == 1 && (pr_assoc = associations.to_a.first) && pr_assoc.first.
|
|
3607
|
+
elsif associations.is_a?(Hash) && associations.length == 1 && (pr_assoc = associations.to_a.first) && defined?(pr_assoc.first.call)
|
|
3608
3608
|
eager_block, associations = pr_assoc
|
|
3609
3609
|
end
|
|
3610
3610
|
|
data/lib/sequel/model/base.rb
CHANGED
|
@@ -492,13 +492,13 @@ module Sequel
|
|
|
492
492
|
def plugin(plugin, *args, &block)
|
|
493
493
|
m = plugin.is_a?(Module) ? plugin : plugin_module(plugin)
|
|
494
494
|
|
|
495
|
-
if !m.
|
|
495
|
+
if !defined?(m.apply) && !defined?(m.configure) && (!args.empty? || block)
|
|
496
496
|
Deprecation.deprecate("Plugin #{plugin} accepts no arguments or block, and passing arguments/block to it", "Remove arguments and block when loading the plugin")
|
|
497
497
|
end
|
|
498
498
|
|
|
499
499
|
unless @plugins.include?(m)
|
|
500
500
|
@plugins << m
|
|
501
|
-
m.apply(self, *args, &block) if m.
|
|
501
|
+
m.apply(self, *args, &block) if defined?(m.apply)
|
|
502
502
|
extend(m::ClassMethods) if m.const_defined?(:ClassMethods, false)
|
|
503
503
|
include(m::InstanceMethods) if m.const_defined?(:InstanceMethods, false)
|
|
504
504
|
if m.const_defined?(:DatasetMethods, false)
|
|
@@ -506,7 +506,7 @@ module Sequel
|
|
|
506
506
|
end
|
|
507
507
|
end
|
|
508
508
|
|
|
509
|
-
m.configure(self, *args, &block) if m.
|
|
509
|
+
m.configure(self, *args, &block) if defined?(m.configure)
|
|
510
510
|
end
|
|
511
511
|
# :nocov:
|
|
512
512
|
ruby2_keywords(:plugin) if respond_to?(:ruby2_keywords, true)
|
|
@@ -99,7 +99,7 @@ module Sequel
|
|
|
99
99
|
# Convert the given string to CamelCase. Will also convert '/' to '::' which is useful for converting paths to namespaces.
|
|
100
100
|
def camelize(s)
|
|
101
101
|
s = s.to_s
|
|
102
|
-
return s.camelize if s.
|
|
102
|
+
return s.camelize if defined?(s.camelize)
|
|
103
103
|
s = s.gsub(/\/(.?)/){|x| "::#{x[-1..-1].upcase unless x == '/'}"}.gsub(/(^|_)(.)/){|x| x[-1..-1].upcase}
|
|
104
104
|
s
|
|
105
105
|
end
|
|
@@ -109,7 +109,7 @@ module Sequel
|
|
|
109
109
|
# or is not initialized.
|
|
110
110
|
def constantize(s)
|
|
111
111
|
s = s.to_s
|
|
112
|
-
return s.constantize if s.
|
|
112
|
+
return s.constantize if defined?(s.constantize)
|
|
113
113
|
raise(NameError, "#{s.inspect} is not a valid constant name!") unless m = /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/.match(s)
|
|
114
114
|
Object.module_eval("::#{m[1]}", __FILE__, __LINE__)
|
|
115
115
|
end
|
|
@@ -117,14 +117,14 @@ module Sequel
|
|
|
117
117
|
# Removes the module part from the expression in the string
|
|
118
118
|
def demodulize(s)
|
|
119
119
|
s = s.to_s
|
|
120
|
-
return s.demodulize if s.
|
|
120
|
+
return s.demodulize if defined?(s.demodulize)
|
|
121
121
|
s.gsub(/^.*::/, '')
|
|
122
122
|
end
|
|
123
123
|
|
|
124
124
|
# Returns the plural form of the word in the string.
|
|
125
125
|
def pluralize(s)
|
|
126
126
|
s = s.to_s
|
|
127
|
-
return s.pluralize if s.
|
|
127
|
+
return s.pluralize if defined?(s.pluralize)
|
|
128
128
|
result = s.dup
|
|
129
129
|
Inflections.plurals.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(s.downcase)
|
|
130
130
|
result
|
|
@@ -133,7 +133,7 @@ module Sequel
|
|
|
133
133
|
# The reverse of pluralize, returns the singular form of a word in a string.
|
|
134
134
|
def singularize(s)
|
|
135
135
|
s = s.to_s
|
|
136
|
-
return s.singularize if s.
|
|
136
|
+
return s.singularize if defined?(s.singularize)
|
|
137
137
|
result = s.dup
|
|
138
138
|
Inflections.singulars.each{|(rule, replacement)| break if result.gsub!(rule, replacement)} unless Inflections.uncountables.include?(s.downcase)
|
|
139
139
|
result
|
|
@@ -143,7 +143,7 @@ module Sequel
|
|
|
143
143
|
# Also changes '::' to '/' to convert namespaces to paths.
|
|
144
144
|
def underscore(s)
|
|
145
145
|
s = s.to_s
|
|
146
|
-
return s.underscore if s.
|
|
146
|
+
return s.underscore if defined?(s.underscore)
|
|
147
147
|
s.gsub('::', '/').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
|
148
148
|
gsub(/([a-z\d])([A-Z])/, '\1_\2').tr('-', '_').downcase
|
|
149
149
|
end
|
|
@@ -252,7 +252,7 @@ module Sequel
|
|
|
252
252
|
|
|
253
253
|
unless skip.include?(:unique)
|
|
254
254
|
unique_opts = Hash[opts[:unique]]
|
|
255
|
-
if model.
|
|
255
|
+
if defined?(model.sti_dataset)
|
|
256
256
|
unique_opts[:dataset] = model.sti_dataset
|
|
257
257
|
end
|
|
258
258
|
model.auto_validate_unique_columns.each{|cols| validates_unique(cols, unique_opts)}
|
data/lib/sequel/plugins/dirty.rb
CHANGED
|
@@ -203,7 +203,7 @@ module Sequel
|
|
|
203
203
|
get_column_value(column)
|
|
204
204
|
end
|
|
205
205
|
|
|
206
|
-
initial_values[column] = if value && value != true && value.
|
|
206
|
+
initial_values[column] = if value && value != true && defined?(value.clone)
|
|
207
207
|
begin
|
|
208
208
|
value.clone
|
|
209
209
|
rescue TypeError
|
|
@@ -36,7 +36,7 @@ module Sequel
|
|
|
36
36
|
module InsertConflict
|
|
37
37
|
def self.configure(model)
|
|
38
38
|
model.instance_exec do
|
|
39
|
-
if @dataset &&
|
|
39
|
+
if @dataset && !defined?(@dataset.insert_conflict)
|
|
40
40
|
raise Error, "#{self}'s dataset does not support insert_conflict"
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -259,7 +259,7 @@ module Sequel
|
|
|
259
259
|
# specific :fields if configured.
|
|
260
260
|
def nested_attributes_set_attributes(meta, obj, attributes)
|
|
261
261
|
if fields = meta[:fields]
|
|
262
|
-
fields = fields.call(obj) if fields.
|
|
262
|
+
fields = fields.call(obj) if defined?(fields.call)
|
|
263
263
|
obj.set_fields(attributes, fields, :missing=>:skip)
|
|
264
264
|
else
|
|
265
265
|
obj.set(attributes)
|
|
@@ -159,7 +159,7 @@ module Sequel
|
|
|
159
159
|
|
|
160
160
|
case @dataset.first_source_table
|
|
161
161
|
when Symbol, String, SQL::Identifier, SQL::QualifiedIdentifier
|
|
162
|
-
convert_errors = db.
|
|
162
|
+
convert_errors = defined?(db.error_info)
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
unless convert_errors
|
|
@@ -162,7 +162,7 @@ module Sequel
|
|
|
162
162
|
if !cc.include?(column) && (new? || get_column_value(column) != v)
|
|
163
163
|
cc << column
|
|
164
164
|
|
|
165
|
-
will_change_column(column) if
|
|
165
|
+
will_change_column(column) if defined?(will_change_column)
|
|
166
166
|
end
|
|
167
167
|
|
|
168
168
|
deserialized_values[column] = v
|
|
@@ -91,7 +91,7 @@ module Sequel
|
|
|
91
91
|
# +many_to_many+ association, make sure the associated object is created on the
|
|
92
92
|
# current object's shard, unless the passed object already has an assigned shard.
|
|
93
93
|
def ensure_associated_primary_key(opts, o, *args)
|
|
94
|
-
o.set_server?(@server) if o.
|
|
94
|
+
o.set_server?(@server) if defined?(o.set_server?)
|
|
95
95
|
super
|
|
96
96
|
end
|
|
97
97
|
|
|
@@ -63,7 +63,7 @@ module Sequel
|
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
65
|
# :nocov:
|
|
66
|
-
ruby2_keywords
|
|
66
|
+
mod.send(:ruby2_keywords, meth) if mod.respond_to?(:ruby2_keywords, true)
|
|
67
67
|
# :nocov:
|
|
68
68
|
end
|
|
69
69
|
|
|
@@ -97,7 +97,7 @@ module Sequel
|
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
99
|
# :nocov:
|
|
100
|
-
ruby2_keywords(meth) if respond_to?(:ruby2_keywords,
|
|
100
|
+
ruby2_keywords(meth) if respond_to?(:ruby2_keywords, true)
|
|
101
101
|
# :nocov:
|
|
102
102
|
end
|
|
103
103
|
|
|
@@ -129,7 +129,7 @@ module Sequel
|
|
|
129
129
|
end
|
|
130
130
|
end
|
|
131
131
|
# :nocov:
|
|
132
|
-
ruby2_keywords(meth) if respond_to?(:ruby2_keywords,
|
|
132
|
+
ruby2_keywords(meth) if respond_to?(:ruby2_keywords, true)
|
|
133
133
|
# :nocov:
|
|
134
134
|
end
|
|
135
135
|
|
|
@@ -159,7 +159,7 @@ module Sequel
|
|
|
159
159
|
end
|
|
160
160
|
end
|
|
161
161
|
# :nocov:
|
|
162
|
-
ruby2_keywords(meth) if respond_to?(:ruby2_keywords,
|
|
162
|
+
ruby2_keywords(meth) if respond_to?(:ruby2_keywords, true)
|
|
163
163
|
# :nocov:
|
|
164
164
|
end
|
|
165
165
|
|
|
@@ -35,7 +35,7 @@ module Sequel
|
|
|
35
35
|
# class B < Sequel::Model; end
|
|
36
36
|
# a # => [A, B]
|
|
37
37
|
module Subclasses
|
|
38
|
-
NEED_SUBCLASSES = !Object.
|
|
38
|
+
NEED_SUBCLASSES = !defined?(Object.subclasses) || Object.method(:subclasses).source_location
|
|
39
39
|
private_constant :NEED_SUBCLASSES
|
|
40
40
|
|
|
41
41
|
# Initialize the subclasses instance variable for the model.
|
|
@@ -282,7 +282,7 @@ module Sequel
|
|
|
282
282
|
o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && v.size == i
|
|
283
283
|
end
|
|
284
284
|
if w = opts[:within]
|
|
285
|
-
o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && w.public_send(w.
|
|
285
|
+
o.errors.add(a, opts[:message] || opts[:wrong_length]) unless v && w.public_send(defined?(w.cover?) ? :cover? : :include?, v.size)
|
|
286
286
|
end
|
|
287
287
|
end
|
|
288
288
|
end
|
|
@@ -337,14 +337,14 @@ module Sequel
|
|
|
337
337
|
def validates_inclusion_of(*atts)
|
|
338
338
|
opts = extract_options!(atts)
|
|
339
339
|
n = opts[:in]
|
|
340
|
-
unless n && (n.
|
|
340
|
+
unless n && (defined?(n.cover?) || defined?(n.include?))
|
|
341
341
|
raise ArgumentError, "The :in parameter is required, and must respond to cover? or include?"
|
|
342
342
|
end
|
|
343
343
|
opts[:message] ||= "is not in range or set: #{n.inspect}"
|
|
344
344
|
reflect_validation(:inclusion, opts, atts)
|
|
345
345
|
atts << opts
|
|
346
346
|
validates_each(*atts) do |o, a, v|
|
|
347
|
-
o.errors.add(a, opts[:message]) unless n.public_send(n.
|
|
347
|
+
o.errors.add(a, opts[:message]) unless n.public_send(defined?(n.cover?) ? :cover? : :include?, v)
|
|
348
348
|
end
|
|
349
349
|
end
|
|
350
350
|
|
|
@@ -107,7 +107,7 @@ module Sequel
|
|
|
107
107
|
|
|
108
108
|
# Check attribute value(s) is included in the given set.
|
|
109
109
|
def validates_includes(set, atts, opts=OPTS)
|
|
110
|
-
validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.public_send(set.
|
|
110
|
+
validatable_attributes_for_type(:includes, atts, opts){|a,v,m| validation_error_message(m, set) unless set.public_send(defined?(set.cover?) ? :cover? : :include?, v)}
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
# Check attribute value(s) string representation is a valid integer.
|
data/lib/sequel/sql.rb
CHANGED
|
@@ -1347,7 +1347,7 @@ module Sequel
|
|
|
1347
1347
|
# underlying callable only accepts a single argument, call it
|
|
1348
1348
|
# with the given dataset.
|
|
1349
1349
|
def call(ds)
|
|
1350
|
-
if @callable.
|
|
1350
|
+
if defined?(@callable.arity) && @callable.arity == 1
|
|
1351
1351
|
@callable.call(ds)
|
|
1352
1352
|
else
|
|
1353
1353
|
@callable.call
|