sequel 5.108.0 → 5.110.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/lib/sequel/adapters/ado.rb +1 -0
- data/lib/sequel/adapters/amalgalite.rb +34 -8
- data/lib/sequel/adapters/jdbc/mssql.rb +28 -5
- data/lib/sequel/adapters/jdbc/postgresql.rb +14 -3
- data/lib/sequel/adapters/jdbc.rb +2 -1
- data/lib/sequel/adapters/postgres.rb +5 -2
- data/lib/sequel/adapters/shared/access.rb +5 -1
- data/lib/sequel/adapters/shared/db2.rb +3 -0
- data/lib/sequel/adapters/shared/mssql.rb +7 -1
- data/lib/sequel/adapters/shared/oracle.rb +7 -0
- data/lib/sequel/adapters/shared/postgres.rb +97 -1001
- data/lib/sequel/adapters/shared/sqlanywhere.rb +0 -32
- data/lib/sequel/adapters/sqlite.rb +13 -9
- data/lib/sequel/adapters/trilogy.rb +2 -1
- data/lib/sequel/core.rb +71 -23
- data/lib/sequel/database/misc.rb +1 -6
- data/lib/sequel/database/schema_methods.rb +3 -3
- data/lib/sequel/database/transactions.rb +1 -3
- data/lib/sequel/dataset/actions.rb +1 -1
- data/lib/sequel/dataset/sql.rb +14 -3
- data/lib/sequel/extensions/core_refinements.rb +1 -4
- data/lib/sequel/extensions/current_datetime_timestamp.rb +2 -2
- data/lib/sequel/extensions/duplicate_columns_handler.rb +1 -3
- data/lib/sequel/extensions/lit_require_frozen.rb +17 -1
- data/lib/sequel/extensions/named_timezones.rb +9 -7
- data/lib/sequel/extensions/pg_array.rb +1 -0
- data/lib/sequel/extensions/pg_json_ops.rb +4 -2
- data/lib/sequel/extensions/pg_loose_count.rb +37 -2
- data/lib/sequel/extensions/s.rb +4 -8
- data/lib/sequel/extensions/schema_dumper.rb +6 -2
- data/lib/sequel/extensions/sql_comments.rb +0 -4
- data/lib/sequel/extensions/string_date_time.rb +7 -4
- data/lib/sequel/extensions/symbol_aref.rb +11 -31
- data/lib/sequel/extensions/symbol_aref_refinement.rb +1 -4
- data/lib/sequel/extensions/symbol_as.rb +1 -2
- data/lib/sequel/extensions/symbol_as_refinement.rb +1 -5
- data/lib/sequel/model/base.rb +4 -9
- data/lib/sequel/plugins/caching.rb +27 -2
- data/lib/sequel/plugins/csv_serializer.rb +9 -20
- data/lib/sequel/plugins/instance_filters.rb +8 -0
- data/lib/sequel/plugins/instance_hooks.rb +19 -0
- data/lib/sequel/plugins/mssql_optimistic_locking.rb +9 -0
- data/lib/sequel/plugins/optimistic_locking.rb +12 -2
- data/lib/sequel/plugins/optimistic_locking_base.rb +14 -0
- data/lib/sequel/plugins/pg_xmin_optimistic_locking.rb +11 -2
- data/lib/sequel/plugins/select_on_skipped_update.rb +63 -0
- data/lib/sequel/plugins/single_table_inheritance.rb +20 -2
- data/lib/sequel/plugins/subset_conditions.rb +5 -16
- data/lib/sequel/plugins/throw_failures.rb +1 -1
- data/lib/sequel/plugins/validate_associated.rb +7 -1
- data/lib/sequel/plugins/validate_associated_context.rb +52 -0
- data/lib/sequel/sql.rb +109 -105
- data/lib/sequel/version.rb +1 -1
- metadata +5 -3
|
@@ -305,38 +305,6 @@ module Sequel
|
|
|
305
305
|
super(sql, :+, args)
|
|
306
306
|
when :<<, :>>
|
|
307
307
|
complex_expression_emulate_append(sql, op, args)
|
|
308
|
-
when :LIKE, :"NOT LIKE"
|
|
309
|
-
sql << '('
|
|
310
|
-
literal_append(sql, args[0])
|
|
311
|
-
sql << (op == :LIKE ? ' REGEXP ' : ' NOT REGEXP ')
|
|
312
|
-
pattern = String.new
|
|
313
|
-
last_c = ''
|
|
314
|
-
args[1].each_char do |c|
|
|
315
|
-
if c == '_' and not pattern.end_with?('\\') and last_c != '\\'
|
|
316
|
-
pattern << '.'
|
|
317
|
-
elsif c == '%' and not pattern.end_with?('\\') and last_c != '\\'
|
|
318
|
-
pattern << '.*'
|
|
319
|
-
elsif c == '[' and not pattern.end_with?('\\') and last_c != '\\'
|
|
320
|
-
pattern << '\['
|
|
321
|
-
elsif c == ']' and not pattern.end_with?('\\') and last_c != '\\'
|
|
322
|
-
pattern << '\]'
|
|
323
|
-
elsif c == '*' and not pattern.end_with?('\\') and last_c != '\\'
|
|
324
|
-
pattern << '\*'
|
|
325
|
-
elsif c == '?' and not pattern.end_with?('\\') and last_c != '\\'
|
|
326
|
-
pattern << '\?'
|
|
327
|
-
else
|
|
328
|
-
pattern << c
|
|
329
|
-
end
|
|
330
|
-
if c == '\\' and last_c == '\\'
|
|
331
|
-
last_c = ''
|
|
332
|
-
else
|
|
333
|
-
last_c = c
|
|
334
|
-
end
|
|
335
|
-
end
|
|
336
|
-
literal_append(sql, pattern)
|
|
337
|
-
sql << " ESCAPE "
|
|
338
|
-
literal_append(sql, "\\")
|
|
339
|
-
sql << ')'
|
|
340
308
|
when :ILIKE, :"NOT ILIKE"
|
|
341
309
|
super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args)
|
|
342
310
|
when :extract
|
|
@@ -336,16 +336,20 @@ module Sequel
|
|
|
336
336
|
log_sql << sql
|
|
337
337
|
log_sql << ")"
|
|
338
338
|
end
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
339
|
+
begin
|
|
340
|
+
if block
|
|
341
|
+
log_connection_yield(log_sql, conn, args){cps.execute(ps_args, &block)}
|
|
342
|
+
else
|
|
343
|
+
log_connection_yield(log_sql, conn, args){cps.execute!(ps_args){|r|}}
|
|
344
|
+
case type
|
|
345
|
+
when :insert
|
|
346
|
+
conn.last_insert_row_id
|
|
347
|
+
when :update
|
|
348
|
+
conn.changes
|
|
349
|
+
end
|
|
348
350
|
end
|
|
351
|
+
ensure
|
|
352
|
+
cps.clear_bindings!
|
|
349
353
|
end
|
|
350
354
|
end
|
|
351
355
|
|
data/lib/sequel/core.rb
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
# DB = Sequel.sqlite # Memory database
|
|
11
11
|
# DB = Sequel.sqlite('blog.db')
|
|
12
12
|
# DB = Sequel.postgres('database_name',
|
|
13
|
-
# user:'user',
|
|
13
|
+
# user: 'user',
|
|
14
14
|
# password: 'password',
|
|
15
15
|
# host: 'host'
|
|
16
16
|
# port: 5432,
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
# For a more expanded introduction, see the {README}[rdoc-ref:README.rdoc].
|
|
26
26
|
# For a quicker introduction, see the {cheat sheet}[rdoc-ref:doc/cheat_sheet.rdoc].
|
|
27
27
|
module Sequel
|
|
28
|
-
@convert_two_digit_years = true
|
|
28
|
+
@convert_two_digit_years = true # SEQUEL6: Remove
|
|
29
29
|
@datetime_class = Time # SEQUEL6: Remove
|
|
30
30
|
@split_symbols = false # SEQUEL6: Remove
|
|
31
31
|
@single_threaded = false
|
|
@@ -37,6 +37,8 @@ module Sequel
|
|
|
37
37
|
OPTS = {}.freeze
|
|
38
38
|
|
|
39
39
|
SPLIT_SYMBOL_CACHE = {} # SEQUEL6: Remove
|
|
40
|
+
SPLIT_SYMBOL_CACHE_ = SPLIT_SYMBOL_CACHE
|
|
41
|
+
private_constant :SPLIT_SYMBOL_CACHE_
|
|
40
42
|
|
|
41
43
|
module SequelMethods
|
|
42
44
|
# Sequel converts two digit years in <tt>Date</tt>s and <tt>DateTime</tt>s by default,
|
|
@@ -45,7 +47,16 @@ module Sequel
|
|
|
45
47
|
# January 2nd, 0003 and December 13, 0099, respectively, by:
|
|
46
48
|
#
|
|
47
49
|
# Sequel.convert_two_digit_years = false
|
|
48
|
-
|
|
50
|
+
#
|
|
51
|
+
# The setter method is deprecated and will be removed in Sequel 6.
|
|
52
|
+
# The reader method will be deprecated in Sequel 6.0 and removed in
|
|
53
|
+
# Sequel 6.1.
|
|
54
|
+
attr_reader :convert_two_digit_years # SEQUEL6.1: Remove
|
|
55
|
+
|
|
56
|
+
def convert_two_digit_years=(v)
|
|
57
|
+
Sequel::Deprecation.deprecate("Sequel.convert_two_digit_years= is deprecated and will be removed in Sequel 6.")
|
|
58
|
+
@convert_two_digit_years = v
|
|
59
|
+
end
|
|
49
60
|
|
|
50
61
|
# Sequel can use either +Time+ or +DateTime+ for times returned from the
|
|
51
62
|
# database. It defaults to +Time+. To change it to +DateTime+:
|
|
@@ -55,9 +66,16 @@ module Sequel
|
|
|
55
66
|
# Note that +Time+ and +DateTime+ objects have a different API, and in
|
|
56
67
|
# cases where they implement the same methods, they often implement them
|
|
57
68
|
# differently (e.g. + using seconds on +Time+ and days on +DateTime+).
|
|
58
|
-
|
|
59
|
-
#
|
|
60
|
-
#
|
|
69
|
+
#
|
|
70
|
+
# The setter method is deprecated and will be removed in Sequel 6.
|
|
71
|
+
# The reader method will be deprecated in Sequel 6.0 and removed in
|
|
72
|
+
# Sequel 6.1.
|
|
73
|
+
attr_reader :datetime_class # SEQUEL6.1: Remove
|
|
74
|
+
|
|
75
|
+
def datetime_class=(v)
|
|
76
|
+
Sequel::Deprecation.deprecate("Sequel.datetime_class= is deprecated and will be removed in Sequel 6.")
|
|
77
|
+
@datetime_class = v
|
|
78
|
+
end
|
|
61
79
|
|
|
62
80
|
# Set whether Sequel is being used in single threaded mode. By default,
|
|
63
81
|
# Sequel uses a thread-safe connection pool, which isn't as fast as the
|
|
@@ -68,8 +86,8 @@ module Sequel
|
|
|
68
86
|
# Sequel.single_threaded = true
|
|
69
87
|
attr_accessor :single_threaded
|
|
70
88
|
|
|
71
|
-
#
|
|
72
|
-
|
|
89
|
+
# SEQUEL6: Remove
|
|
90
|
+
define_method(:orig_require, Kernel.instance_method(:require))
|
|
73
91
|
private :orig_require
|
|
74
92
|
|
|
75
93
|
# Returns true if the passed object could be a specifier of conditions, false otherwise.
|
|
@@ -92,7 +110,7 @@ module Sequel
|
|
|
92
110
|
end
|
|
93
111
|
end
|
|
94
112
|
|
|
95
|
-
# Creates a new
|
|
113
|
+
# Creates a new Database object based on the supplied connection string
|
|
96
114
|
# and optional arguments. The specified scheme determines the database
|
|
97
115
|
# class used, and the rest of the string specifies the connection options.
|
|
98
116
|
# For example:
|
|
@@ -156,18 +174,30 @@ module Sequel
|
|
|
156
174
|
# Sequel.extension(:blank)
|
|
157
175
|
# Sequel.extension(:core_extensions, :named_timezones)
|
|
158
176
|
def extension(*extensions)
|
|
159
|
-
extensions.each
|
|
177
|
+
extensions.each do |e|
|
|
178
|
+
e = e.to_s
|
|
179
|
+
|
|
180
|
+
if %r{..[/\\]} =~ e
|
|
181
|
+
raise Error, "cannot use extension with ../ for security reasons"
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
Kernel.require("sequel/extensions/#{e}")
|
|
185
|
+
end
|
|
160
186
|
end
|
|
161
187
|
|
|
162
|
-
# The exception
|
|
188
|
+
# The exception class raised if there is an error parsing JSON.
|
|
163
189
|
# This can be overridden to use an alternative json implementation.
|
|
164
|
-
|
|
190
|
+
#
|
|
191
|
+
# This method is deprecated and will be removed in Sequel 6.1.
|
|
192
|
+
def json_parser_error_class # SEQUEL6.1: Remove
|
|
165
193
|
JSON::ParserError
|
|
166
194
|
end
|
|
167
195
|
|
|
168
196
|
if RUBY_VERSION >= '3'
|
|
169
197
|
# Join the array or set.
|
|
170
|
-
|
|
198
|
+
#
|
|
199
|
+
# This method is deprecated and will be removed in Sequel 6.1.
|
|
200
|
+
def array_or_set_join(obj, arg) # SEQUEL6.1: Remove
|
|
171
201
|
obj.join(arg)
|
|
172
202
|
end
|
|
173
203
|
# simplecov:disable
|
|
@@ -196,14 +226,22 @@ module Sequel
|
|
|
196
226
|
|
|
197
227
|
# Convert given object to json and return the result.
|
|
198
228
|
# This can be overridden to use an alternative json implementation.
|
|
199
|
-
|
|
229
|
+
#
|
|
230
|
+
# This method is deprecated and will be removed in Sequel 6.1.
|
|
231
|
+
def object_to_json(obj, *args, &block) # SEQUEL6.1: Remove
|
|
200
232
|
obj.to_json(*args, &block)
|
|
201
233
|
end
|
|
202
234
|
|
|
203
235
|
# Parse the string as JSON and return the result.
|
|
204
236
|
# This can be overridden to use an alternative json implementation.
|
|
205
|
-
|
|
206
|
-
|
|
237
|
+
#
|
|
238
|
+
# This method is deprecated and will be removed in Sequel 6.1.
|
|
239
|
+
def parse_json(json) # SEQUEL6.1: Remove
|
|
240
|
+
if JSON::VERSION >= '3'
|
|
241
|
+
JSON.parse(json)
|
|
242
|
+
else
|
|
243
|
+
JSON.parse(json, :create_additions=>false)
|
|
244
|
+
end
|
|
207
245
|
end
|
|
208
246
|
|
|
209
247
|
# If a mutex is given, synchronize access using it. If nil is given, just
|
|
@@ -249,7 +287,7 @@ module Sequel
|
|
|
249
287
|
# For tables, these parts are the schema, table, and alias.
|
|
250
288
|
def split_symbol(sym)
|
|
251
289
|
# SEQUEL6.1: Remove
|
|
252
|
-
unless v = Sequel.synchronize{
|
|
290
|
+
unless v = Sequel.synchronize{SPLIT_SYMBOL_CACHE_[sym]}
|
|
253
291
|
if split_symbols?
|
|
254
292
|
v = case s = sym.to_s
|
|
255
293
|
when /\A((?:(?!__).)+)__((?:(?!___).)+)___(.+)\z/
|
|
@@ -264,7 +302,7 @@ module Sequel
|
|
|
264
302
|
else
|
|
265
303
|
v = [nil,sym.to_s.freeze,nil].freeze
|
|
266
304
|
end
|
|
267
|
-
Sequel.synchronize{
|
|
305
|
+
Sequel.synchronize{SPLIT_SYMBOL_CACHE_[sym] = v}
|
|
268
306
|
end
|
|
269
307
|
v
|
|
270
308
|
end
|
|
@@ -300,8 +338,8 @@ module Sequel
|
|
|
300
338
|
# Sequel.expr{table__column} # table__column
|
|
301
339
|
# Sequel.expr{table[:column]} # table.column
|
|
302
340
|
def split_symbols=(v)
|
|
303
|
-
|
|
304
|
-
Sequel.synchronize{
|
|
341
|
+
Sequel::Deprecation.deprecate("Sequel.split_symbols= is deprecated and will be removed in Sequel 6.")
|
|
342
|
+
Sequel.synchronize{SPLIT_SYMBOL_CACHE_.clear}
|
|
305
343
|
@split_symbols = v
|
|
306
344
|
end
|
|
307
345
|
|
|
@@ -324,7 +362,9 @@ module Sequel
|
|
|
324
362
|
# value of <tt>Sequel.datetime_class</tt>.
|
|
325
363
|
#
|
|
326
364
|
# Sequel.string_to_datetime('2010-09-10 10:20:30') # Time.local(2010, 09, 10, 10, 20, 30)
|
|
327
|
-
|
|
365
|
+
#
|
|
366
|
+
# This method is deprecated and will be removed in Sequel 6.1.
|
|
367
|
+
def string_to_datetime(string) # SEQUEL6.1: Remove
|
|
328
368
|
if datetime_class == DateTime
|
|
329
369
|
DateTime.parse(string, convert_two_digit_years)
|
|
330
370
|
else
|
|
@@ -356,7 +396,10 @@ module Sequel
|
|
|
356
396
|
if RUBY_VERSION >= '2.1'
|
|
357
397
|
# A timer object that can be passed to Sequel.elapsed_seconds_since
|
|
358
398
|
# to return the number of seconds elapsed.
|
|
359
|
-
|
|
399
|
+
#
|
|
400
|
+
# This method is deprecated and will be removed in Sequel 6.1 (or
|
|
401
|
+
# potentially in 6.0 if Ruby 2.1 support is dropped before 6.0).
|
|
402
|
+
def start_timer # SEQUEL6.1: Remove
|
|
360
403
|
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
361
404
|
end
|
|
362
405
|
else
|
|
@@ -369,7 +412,10 @@ module Sequel
|
|
|
369
412
|
|
|
370
413
|
# The elapsed seconds since the given timer object was created. The
|
|
371
414
|
# timer object should have been created via Sequel.start_timer.
|
|
372
|
-
|
|
415
|
+
#
|
|
416
|
+
# This method is deprecated and will be removed in Sequel 6.1 (or
|
|
417
|
+
# potentially in 6.0 if Ruby 2.1 support is dropped before 6.0).
|
|
418
|
+
def elapsed_seconds_since(timer) # SEQUEL6.1: Remove
|
|
373
419
|
start_timer - timer
|
|
374
420
|
end
|
|
375
421
|
|
|
@@ -481,4 +527,6 @@ module Sequel
|
|
|
481
527
|
|
|
482
528
|
# Add the database adapter class methods to Sequel via metaprogramming
|
|
483
529
|
def_adapter_method(*Database::ADAPTERS)
|
|
530
|
+
|
|
531
|
+
Deprecation.deprecate_constant(self, :SPLIT_SYMBOL_CACHE)
|
|
484
532
|
end
|
data/lib/sequel/database/misc.rb
CHANGED
|
@@ -229,12 +229,7 @@ module Sequel
|
|
|
229
229
|
end
|
|
230
230
|
|
|
231
231
|
# Disallow dup/clone for Database instances
|
|
232
|
-
undef_method :dup, :clone, :initialize_copy
|
|
233
|
-
# simplecov:disable
|
|
234
|
-
if RUBY_VERSION >= '1.9.3'
|
|
235
|
-
# simplecov:enable
|
|
236
|
-
undef_method :initialize_clone, :initialize_dup
|
|
237
|
-
end
|
|
232
|
+
undef_method :dup, :clone, :initialize_copy, :initialize_clone, :initialize_dup
|
|
238
233
|
|
|
239
234
|
# Cast the given type to a literal type
|
|
240
235
|
#
|
|
@@ -170,18 +170,18 @@ module Sequel
|
|
|
170
170
|
# :engine :: The table engine to use for the table.
|
|
171
171
|
#
|
|
172
172
|
# PostgreSQL specific options:
|
|
173
|
-
# :on_commit :: Either :preserve_rows (default), :drop or :delete_rows. Should
|
|
174
|
-
# only be specified when creating a temporary table.
|
|
175
173
|
# :foreign :: Create a foreign table. The value should be the name of the
|
|
176
174
|
# foreign server that was specified in CREATE SERVER.
|
|
177
175
|
# :inherits :: Inherit from a different table. An array can be
|
|
178
176
|
# specified to inherit from multiple tables.
|
|
179
|
-
# :
|
|
177
|
+
# :on_commit :: Either :preserve_rows (default), :drop or :delete_rows. Should
|
|
178
|
+
# only be specified when creating a temporary table.
|
|
180
179
|
# :options :: The OPTIONS clause to use for foreign tables. Should be a hash
|
|
181
180
|
# where keys are option names and values are option values. Note
|
|
182
181
|
# that option names are unquoted, so you should not use untrusted
|
|
183
182
|
# keys.
|
|
184
183
|
# :tablespace :: The tablespace to use for the table.
|
|
184
|
+
# :unlogged :: Create the table as an unlogged table.
|
|
185
185
|
#
|
|
186
186
|
# SQLite specific options:
|
|
187
187
|
# :strict :: Create a STRICT table, which checks that the values for the columns
|
|
@@ -374,9 +374,7 @@ module Sequel
|
|
|
374
374
|
|
|
375
375
|
# Whether to commit the current transaction. Thread.current.status is
|
|
376
376
|
# checked because Thread#kill skips rescue blocks (so exception would be
|
|
377
|
-
# nil), but the transaction should still be rolled back.
|
|
378
|
-
# not 2.0+), the thread status will still be "run", so Thread#kill
|
|
379
|
-
# will erroneously commit the transaction, and there isn't a workaround.
|
|
377
|
+
# nil), but the transaction should still be rolled back.
|
|
380
378
|
def commit_or_rollback_transaction(exception, conn, opts)
|
|
381
379
|
if exception
|
|
382
380
|
false
|
data/lib/sequel/dataset/sql.rb
CHANGED
|
@@ -1346,10 +1346,21 @@ module Sequel
|
|
|
1346
1346
|
alias delete_returning_sql insert_returning_sql
|
|
1347
1347
|
alias update_returning_sql insert_returning_sql
|
|
1348
1348
|
|
|
1349
|
-
|
|
1350
|
-
|
|
1349
|
+
JOIN_TYPE_SQL = {}
|
|
1350
|
+
(CONDITIONED_JOIN_TYPES + UNCONDITIONED_JOIN_TYPES + %i[natural_inner natural_left_outer natural_right_outer natural_full_outer]).each do |join_type|
|
|
1351
|
+
JOIN_TYPE_SQL[join_type] = "#{join_type.to_s.tr('_', ' ').upcase} JOIN".freeze
|
|
1352
|
+
end
|
|
1353
|
+
JOIN_TYPE_SQL[nil] = "JOIN"
|
|
1354
|
+
JOIN_TYPE_SQL.freeze
|
|
1355
|
+
private_constant :JOIN_TYPE_SQL
|
|
1356
|
+
|
|
1357
|
+
# SQL fragment for join type
|
|
1351
1358
|
def join_type_sql(join_type)
|
|
1352
|
-
|
|
1359
|
+
JOIN_TYPE_SQL.fetch(join_type) do
|
|
1360
|
+
# SEQUEL6: Raise error
|
|
1361
|
+
Sequel::Deprecation.deprecate("Unrecognized join type used: #{join_type.inspect}. This will raise an error starting in Sequel 6.")
|
|
1362
|
+
"#{join_type.to_s.tr('_', ' ').upcase} JOIN"
|
|
1363
|
+
end
|
|
1353
1364
|
end
|
|
1354
1365
|
|
|
1355
1366
|
# Append USING clause for JOIN USING
|
|
@@ -10,10 +10,7 @@
|
|
|
10
10
|
#
|
|
11
11
|
# using Sequel::CoreRefinements
|
|
12
12
|
|
|
13
|
-
#
|
|
14
|
-
raise(Sequel::Error, "Refinements require ruby 2.0.0 or greater") unless RUBY_VERSION >= '2.0.0'
|
|
15
|
-
# simplecov:enable
|
|
16
|
-
|
|
13
|
+
#
|
|
17
14
|
module Sequel::CoreRefinements
|
|
18
15
|
# simplecov:disable
|
|
19
16
|
include_meth = RUBY_VERSION >= '3.1' ? :import_methods : :include
|
|
@@ -38,7 +38,7 @@ module Sequel
|
|
|
38
38
|
private
|
|
39
39
|
|
|
40
40
|
# Literalize custom DateTime subclass objects as CURRENT_TIMESTAMP.
|
|
41
|
-
def literal_datetime_append(sql, v)
|
|
41
|
+
def literal_datetime_append(sql, v) # SEQUEL6: Remove
|
|
42
42
|
v.is_a?(DateTime) ? literal_append(sql, Sequel::CURRENT_TIMESTAMP) : super
|
|
43
43
|
end
|
|
44
44
|
|
|
@@ -52,7 +52,7 @@ module Sequel
|
|
|
52
52
|
class Time < ::Time; end
|
|
53
53
|
|
|
54
54
|
# DateTime subclass literalized as CURRENT_TIMESTAMP
|
|
55
|
-
class DateTime < ::DateTime; end
|
|
55
|
+
class DateTime < ::DateTime; end # SEQUEL6.1: Remove
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
Dataset.register_extension(:current_datetime_timestamp, CurrentDateTimeTimestamp::DatasetMethods)
|
|
@@ -40,9 +40,7 @@
|
|
|
40
40
|
|
|
41
41
|
module Sequel
|
|
42
42
|
module DuplicateColumnsHandler
|
|
43
|
-
|
|
44
|
-
CALLER_ARGS = (RUBY_VERSION >= '2.0' ? [0,1] : [0]).freeze
|
|
45
|
-
# simplecov:enable
|
|
43
|
+
CALLER_ARGS = [0,1].freeze
|
|
46
44
|
|
|
47
45
|
# Customize handling of duplicate columns for this dataset.
|
|
48
46
|
def on_duplicate_columns(handler = (raise Error, "Must provide either an argument or a block to on_duplicate_columns" unless defined?(yield); nil), &block)
|
|
@@ -63,6 +63,20 @@ module Sequel
|
|
|
63
63
|
class Error < Sequel::Error
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
+
module BooleanExpressionClassMethods
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
# Do not freeze literal strings in value pairs, so they don't skip
|
|
70
|
+
# the frozen checks.
|
|
71
|
+
def from_value_pair(l, r)
|
|
72
|
+
if LiteralString === r
|
|
73
|
+
new(:'=', l, r)
|
|
74
|
+
else
|
|
75
|
+
super
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
66
80
|
module DatabaseMethods
|
|
67
81
|
def self.extended(db)
|
|
68
82
|
db.extend_datasets(DatasetMethods)
|
|
@@ -105,7 +119,7 @@ module Sequel
|
|
|
105
119
|
def _check_unfrozen_literal_string(str)
|
|
106
120
|
return if !str.is_a?(String) || str.frozen?
|
|
107
121
|
|
|
108
|
-
if str.is_a?(LiteralString)
|
|
122
|
+
if str.is_a?(LiteralString) && str == str.source
|
|
109
123
|
_check_unfrozen_literal_string(str.source)
|
|
110
124
|
else
|
|
111
125
|
raise Error, "cannot treat unfrozen string as literal SQL: #{str.inspect}"
|
|
@@ -126,6 +140,8 @@ module Sequel
|
|
|
126
140
|
end
|
|
127
141
|
end
|
|
128
142
|
|
|
143
|
+
SQL::BooleanExpression.extend(LitRequireFrozen::BooleanExpressionClassMethods)
|
|
144
|
+
|
|
129
145
|
Dataset.register_extension(:lit_require_frozen, LitRequireFrozen::DatasetMethods)
|
|
130
146
|
Database.register_extension(:lit_require_frozen, LitRequireFrozen::DatabaseMethods)
|
|
131
147
|
end
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
#
|
|
3
3
|
# Allows the use of named timezones via TZInfo (requires tzinfo).
|
|
4
|
-
# Forces the use of DateTime as Sequel's datetime_class, since
|
|
4
|
+
# Forces the use of DateTime as Sequel's datetime_class by default, since
|
|
5
5
|
# historically, Ruby's Time class doesn't support timezones other
|
|
6
6
|
# than local and UTC. To continue using Ruby's Time class when using
|
|
7
|
-
# the named_timezones extension
|
|
7
|
+
# the named_timezones extension, set the
|
|
8
|
+
# +SEQUEL_NAMED_TIMEZONES_USE_TIME+ environment variable before
|
|
9
|
+
# loading the extension:
|
|
8
10
|
#
|
|
9
11
|
# # Load the extension
|
|
12
|
+
# ENV['SEQUEL_NAMED_TIMEZONES_USE_TIME'] = "1"
|
|
10
13
|
# Sequel.extension :named_timezones
|
|
11
14
|
#
|
|
12
|
-
# # Set Sequel.datetime_class back to Time
|
|
13
|
-
# Sequel.datetime_class = Time
|
|
14
|
-
#
|
|
15
15
|
# This allows you to either pass strings or TZInfo::Timezone
|
|
16
16
|
# instance to Sequel.database_timezone=, application_timezone=, and
|
|
17
17
|
# typecast_timezone=. If a string is passed, it is converted to a
|
|
@@ -49,7 +49,9 @@ require 'tzinfo'
|
|
|
49
49
|
|
|
50
50
|
#
|
|
51
51
|
module Sequel
|
|
52
|
-
|
|
52
|
+
# simplecov:disable
|
|
53
|
+
self.datetime_class = DateTime unless ENV["SEQUEL_NAMED_TIMEZONES_USE_TIME"]
|
|
54
|
+
# simplecov:enable
|
|
53
55
|
|
|
54
56
|
module NamedTimezones
|
|
55
57
|
module DatabaseMethods
|
|
@@ -69,7 +71,7 @@ module Sequel
|
|
|
69
71
|
|
|
70
72
|
if RUBY_VERSION >= '2.6'
|
|
71
73
|
# Whether Time.at with :nsec and :in is broken. True on JRuby < 9.3.9.0.
|
|
72
|
-
BROKEN_TIME_AT_WITH_NSEC = defined?(JRUBY_VERSION) && (JRUBY_VERSION < '9.3' || (JRUBY_VERSION < '9.4' && JRUBY_VERSION.split('.')[2].to_i < 9))
|
|
74
|
+
BROKEN_TIME_AT_WITH_NSEC = defined?(JRUBY_VERSION) && (JRUBY_VERSION.to_r < Rational('9.3') || (JRUBY_VERSION.to_r < Rational('9.4') && JRUBY_VERSION.split('.')[2].to_i < 9))
|
|
73
75
|
private_constant :BROKEN_TIME_AT_WITH_NSEC
|
|
74
76
|
|
|
75
77
|
# Convert the given input Time (which must be in UTC) to the given input timezone,
|
|
@@ -390,6 +390,7 @@ module Sequel
|
|
|
390
390
|
elsif char == '{'
|
|
391
391
|
raise Sequel::Error, "invalid array, opening brace with existing recorded data" unless @recorded.empty?
|
|
392
392
|
|
|
393
|
+
raise Sequel::Error, "cannot parse array with more than 6 dimensions" if @stack.length >= 6
|
|
393
394
|
# Start of new array, add it to the stack
|
|
394
395
|
new = []
|
|
395
396
|
@stack.last << new
|
|
@@ -984,7 +984,8 @@ module Sequel
|
|
|
984
984
|
comma = true
|
|
985
985
|
end
|
|
986
986
|
ds.literal_append(sql, v)
|
|
987
|
-
sql << " AS "
|
|
987
|
+
sql << " AS "
|
|
988
|
+
ds.send(:identifier_append, sql, k)
|
|
988
989
|
end
|
|
989
990
|
end
|
|
990
991
|
end
|
|
@@ -1254,7 +1255,8 @@ module Sequel
|
|
|
1254
1255
|
comma = true
|
|
1255
1256
|
end
|
|
1256
1257
|
ds.literal_append(sql, v)
|
|
1257
|
-
sql << " AS "
|
|
1258
|
+
sql << " AS "
|
|
1259
|
+
ds.send(:identifier_append, sql, k)
|
|
1258
1260
|
end
|
|
1259
1261
|
end
|
|
1260
1262
|
|
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
#
|
|
11
11
|
# DB.loose_count(Sequel[:schema][:table]) # => 123456
|
|
12
12
|
#
|
|
13
|
-
#
|
|
13
|
+
# To get the loose count of all tables in a given schema:
|
|
14
|
+
#
|
|
15
|
+
# DB.loose_counts(:schema) # => {table: 123456, ...}
|
|
16
|
+
#
|
|
17
|
+
# How accurate these counts are depends on the number of rows
|
|
14
18
|
# added/deleted from the table since the last time it was
|
|
15
19
|
# analyzed. If the table has not been vacuumed or analyzed
|
|
16
20
|
# yet, this can return 0 or -1 depending on the PostgreSQL
|
|
@@ -31,9 +35,40 @@ module Sequel
|
|
|
31
35
|
def loose_count(table)
|
|
32
36
|
from(:pg_class).where(:oid=>regclass_oid(table)).get(Sequel.cast(:reltuples, Integer))
|
|
33
37
|
end
|
|
38
|
+
|
|
39
|
+
# Look at the table statistics for the given schema and return a
|
|
40
|
+
# hash with table name keys and approximate counts. Results include
|
|
41
|
+
# normal tables, materialized views, and partitioned tables.
|
|
42
|
+
def loose_counts(schema)
|
|
43
|
+
case schema
|
|
44
|
+
when Symbol
|
|
45
|
+
schema = schema.to_s
|
|
46
|
+
when String
|
|
47
|
+
nil
|
|
48
|
+
when SQL::Identifier
|
|
49
|
+
schema = schema.value.to_s
|
|
50
|
+
else
|
|
51
|
+
raise Error, "unsupported argument type, should be symbol, string, or Sequel::SQL::Identifier, given #{schema.inspect}"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
namespace_oid = if server_version >= 90500
|
|
55
|
+
Sequel.function(:to_regnamespace, schema).cast(:oid)
|
|
56
|
+
else
|
|
57
|
+
from(:pg_namespace).where(nspname: schema).select(:oid)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
hash = {}
|
|
61
|
+
from(:pg_class).
|
|
62
|
+
where(relnamespace: namespace_oid, relkind: %w"r m p").
|
|
63
|
+
order(:relname).
|
|
64
|
+
select_map([:relname, Sequel.cast(:reltuples, Integer).as(:v)]).
|
|
65
|
+
each do |k, v|
|
|
66
|
+
hash[k.to_sym] = v
|
|
67
|
+
end
|
|
68
|
+
hash
|
|
69
|
+
end
|
|
34
70
|
end
|
|
35
71
|
end
|
|
36
72
|
|
|
37
73
|
Database.register_extension(:pg_loose_count, Postgres::LooseCount)
|
|
38
74
|
end
|
|
39
|
-
|
data/lib/sequel/extensions/s.rb
CHANGED
|
@@ -29,8 +29,7 @@
|
|
|
29
29
|
#
|
|
30
30
|
# Object.send(:include, Sequel::S)
|
|
31
31
|
#
|
|
32
|
-
#
|
|
33
|
-
# can use Sequel::S as a refinement, in which case the private #S method
|
|
32
|
+
# You can use also Sequel::S as a refinement, in which case the private #S method
|
|
34
33
|
# will be available on all objects while the refinement is active.
|
|
35
34
|
#
|
|
36
35
|
# using Sequel::S
|
|
@@ -39,7 +38,6 @@
|
|
|
39
38
|
#
|
|
40
39
|
# Related module: Sequel::S
|
|
41
40
|
|
|
42
|
-
|
|
43
41
|
#
|
|
44
42
|
module Sequel::S
|
|
45
43
|
private
|
|
@@ -50,11 +48,9 @@ module Sequel::S
|
|
|
50
48
|
end
|
|
51
49
|
|
|
52
50
|
# simplecov:disable
|
|
53
|
-
|
|
54
|
-
include_meth = RUBY_VERSION >= '3.1' ? :import_methods : :include
|
|
51
|
+
include_meth = RUBY_VERSION >= '3.1' ? :import_methods : :include
|
|
55
52
|
# simplecov:enable
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
end
|
|
53
|
+
refine Object do
|
|
54
|
+
send include_meth, Sequel::S
|
|
59
55
|
end
|
|
60
56
|
end
|
|
@@ -200,8 +200,12 @@ END_MIG
|
|
|
200
200
|
|
|
201
201
|
# Recreate the column in the passed Schema::CreateTableGenerator from the given name and parsed database schema.
|
|
202
202
|
def recreate_column(name, schema, gen, options)
|
|
203
|
+
db_type = schema[:db_type]
|
|
204
|
+
db_type = literal(db_type) if options[:same_db] && database_type == :sqlite
|
|
205
|
+
|
|
203
206
|
if options[:single_pk] && schema_autoincrementing_primary_key?(schema)
|
|
204
|
-
type_hash = options[:same_db] ? {:type=>
|
|
207
|
+
type_hash = options[:same_db] ? {:type=>db_type} : column_schema_to_ruby_type(schema)
|
|
208
|
+
|
|
205
209
|
[:table, :key, :on_delete, :on_update, :deferrable].each{|f| type_hash[f] = schema[f] if schema[f]}
|
|
206
210
|
if type_hash == {:type=>Integer} || type_hash == {:type=>"integer"} || type_hash == {:type=>"INTEGER"}
|
|
207
211
|
type_hash.delete(:type)
|
|
@@ -220,7 +224,7 @@ END_MIG
|
|
|
220
224
|
end
|
|
221
225
|
else
|
|
222
226
|
col_opts = if options[:same_db]
|
|
223
|
-
h = {:type=>
|
|
227
|
+
h = {:type=>db_type}
|
|
224
228
|
if database_type == :mysql && h[:type].start_with?("timestamp")
|
|
225
229
|
h[:null] = true
|
|
226
230
|
end
|
|
@@ -84,10 +84,6 @@
|
|
|
84
84
|
# # SELECT * FROM albums -- model:Album,action:all -- Some Comment
|
|
85
85
|
# end
|
|
86
86
|
#
|
|
87
|
-
# Note that Microsoft Access does not support inline comments,
|
|
88
|
-
# and attempting to use comments on it will result in SQL syntax
|
|
89
|
-
# errors.
|
|
90
|
-
#
|
|
91
87
|
# Related modules: Sequel::SQLComments, Sequel::Database::SQLComments
|
|
92
88
|
|
|
93
89
|
#
|