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