sequel 4.45.0 → 4.46.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 +108 -0
- data/doc/release_notes/4.46.0.txt +404 -0
- data/doc/security.rdoc +9 -0
- data/doc/sql.rdoc +2 -2
- data/doc/testing.rdoc +1 -1
- data/doc/validations.rdoc +1 -2
- data/lib/sequel/adapters/ado.rb +8 -3
- data/lib/sequel/adapters/ado/access.rb +8 -4
- data/lib/sequel/adapters/ado/mssql.rb +3 -1
- data/lib/sequel/adapters/amalgalite.rb +5 -0
- data/lib/sequel/adapters/cubrid.rb +16 -7
- data/lib/sequel/adapters/do.rb +7 -1
- data/lib/sequel/adapters/do/mysql.rb +8 -4
- data/lib/sequel/adapters/ibmdb.rb +10 -5
- data/lib/sequel/adapters/jdbc.rb +8 -2
- data/lib/sequel/adapters/jdbc/as400.rb +10 -3
- data/lib/sequel/adapters/jdbc/db2.rb +27 -16
- data/lib/sequel/adapters/jdbc/derby.rb +47 -20
- data/lib/sequel/adapters/jdbc/h2.rb +13 -7
- data/lib/sequel/adapters/jdbc/hsqldb.rb +18 -9
- data/lib/sequel/adapters/jdbc/mssql.rb +5 -2
- data/lib/sequel/adapters/jdbc/mysql.rb +3 -2
- data/lib/sequel/adapters/jdbc/oracle.rb +3 -2
- data/lib/sequel/adapters/jdbc/postgresql.rb +4 -3
- data/lib/sequel/adapters/jdbc/sqlanywhere.rb +2 -1
- data/lib/sequel/adapters/jdbc/sqlite.rb +10 -3
- data/lib/sequel/adapters/jdbc/sqlserver.rb +23 -0
- data/lib/sequel/adapters/jdbc/transactions.rb +16 -10
- data/lib/sequel/adapters/mock.rb +5 -0
- data/lib/sequel/adapters/mysql.rb +8 -1
- data/lib/sequel/adapters/mysql2.rb +6 -1
- data/lib/sequel/adapters/odbc.rb +20 -8
- data/lib/sequel/adapters/odbc/mssql.rb +6 -3
- data/lib/sequel/adapters/oracle.rb +12 -6
- data/lib/sequel/adapters/postgres.rb +20 -8
- data/lib/sequel/adapters/shared/access.rb +76 -47
- data/lib/sequel/adapters/shared/cubrid.rb +16 -11
- data/lib/sequel/adapters/shared/db2.rb +46 -19
- data/lib/sequel/adapters/shared/firebird.rb +20 -8
- data/lib/sequel/adapters/shared/informix.rb +6 -3
- data/lib/sequel/adapters/shared/mssql.rb +132 -72
- data/lib/sequel/adapters/shared/mysql.rb +112 -65
- data/lib/sequel/adapters/shared/oracle.rb +36 -21
- data/lib/sequel/adapters/shared/postgres.rb +91 -56
- data/lib/sequel/adapters/shared/sqlanywhere.rb +65 -37
- data/lib/sequel/adapters/shared/sqlite.rb +67 -32
- data/lib/sequel/adapters/sqlanywhere.rb +9 -1
- data/lib/sequel/adapters/sqlite.rb +8 -1
- data/lib/sequel/adapters/swift.rb +5 -0
- data/lib/sequel/adapters/swift/mysql.rb +4 -2
- data/lib/sequel/adapters/swift/sqlite.rb +1 -1
- data/lib/sequel/adapters/tinytds.rb +10 -3
- data/lib/sequel/adapters/utils/emulate_offset_with_reverse_and_count.rb +1 -1
- data/lib/sequel/adapters/utils/emulate_offset_with_row_number.rb +1 -1
- data/lib/sequel/adapters/utils/mysql_mysql2.rb +1 -0
- data/lib/sequel/adapters/utils/pg_types.rb +14 -6
- data/lib/sequel/adapters/utils/replace.rb +4 -2
- data/lib/sequel/connection_pool/single.rb +2 -2
- data/lib/sequel/core.rb +24 -11
- data/lib/sequel/database/connecting.rb +9 -3
- data/lib/sequel/database/dataset_defaults.rb +7 -1
- data/lib/sequel/database/logging.rb +1 -0
- data/lib/sequel/database/misc.rb +5 -2
- data/lib/sequel/database/query.rb +7 -5
- data/lib/sequel/database/schema_generator.rb +1 -0
- data/lib/sequel/database/schema_methods.rb +50 -27
- data/lib/sequel/database/transactions.rb +19 -9
- data/lib/sequel/dataset/actions.rb +15 -6
- data/lib/sequel/dataset/graph.rb +15 -5
- data/lib/sequel/dataset/misc.rb +12 -4
- data/lib/sequel/dataset/mutation.rb +17 -8
- data/lib/sequel/dataset/prepared_statements.rb +3 -2
- data/lib/sequel/dataset/query.rb +84 -38
- data/lib/sequel/dataset/sql.rb +302 -191
- data/lib/sequel/deprecated.rb +26 -17
- data/lib/sequel/extensions/_deprecated_identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/auto_literal_strings.rb +74 -0
- data/lib/sequel/extensions/from_block.rb +1 -0
- data/lib/sequel/extensions/graph_each.rb +1 -1
- data/lib/sequel/extensions/identifier_mangling.rb +2 -2
- data/lib/sequel/extensions/migration.rb +28 -4
- data/lib/sequel/extensions/no_auto_literal_strings.rb +2 -0
- data/lib/sequel/extensions/schema_dumper.rb +4 -4
- data/lib/sequel/extensions/sequel_3_dataset_methods.rb +5 -3
- data/lib/sequel/extensions/set_overrides.rb +2 -0
- data/lib/sequel/extensions/split_array_nil.rb +2 -2
- data/lib/sequel/extensions/virtual_row_method_block.rb +44 -0
- data/lib/sequel/model.rb +11 -7
- data/lib/sequel/model/associations.rb +5 -7
- data/lib/sequel/model/base.rb +47 -45
- data/lib/sequel/model/dataset_module.rb +9 -14
- data/lib/sequel/model/plugins.rb +3 -0
- data/lib/sequel/no_core_ext.rb +1 -0
- data/lib/sequel/plugins/blacklist_security.rb +1 -1
- data/lib/sequel/plugins/boolean_subsets.rb +7 -5
- data/lib/sequel/plugins/class_table_inheritance.rb +47 -10
- data/lib/sequel/plugins/dataset_associations.rb +1 -1
- data/lib/sequel/plugins/def_dataset_method.rb +90 -0
- data/lib/sequel/plugins/finder.rb +240 -0
- data/lib/sequel/plugins/inverted_subsets.rb +19 -12
- data/lib/sequel/plugins/many_through_many.rb +1 -1
- data/lib/sequel/plugins/nested_attributes.rb +1 -1
- data/lib/sequel/plugins/schema.rb +1 -1
- data/lib/sequel/plugins/single_table_inheritance.rb +7 -1
- data/lib/sequel/plugins/subset_conditions.rb +11 -3
- data/lib/sequel/plugins/whitelist_security.rb +118 -0
- data/lib/sequel/sql.rb +80 -36
- data/lib/sequel/timezones.rb +2 -0
- data/lib/sequel/version.rb +1 -1
- data/spec/adapters/mssql_spec.rb +20 -0
- data/spec/adapters/mysql_spec.rb +1 -1
- data/spec/adapters/oracle_spec.rb +12 -8
- data/spec/adapters/postgres_spec.rb +1 -1
- data/spec/adapters/spec_helper.rb +1 -1
- data/spec/adapters/sqlite_spec.rb +36 -34
- data/spec/core/connection_pool_spec.rb +2 -1
- data/spec/core/database_spec.rb +87 -9
- data/spec/core/dataset_spec.rb +501 -129
- data/spec/core/deprecated_spec.rb +1 -1
- data/spec/core/expression_filters_spec.rb +146 -60
- data/spec/core/mock_adapter_spec.rb +1 -1
- data/spec/core/object_graph_spec.rb +61 -9
- data/spec/core/placeholder_literalizer_spec.rb +20 -2
- data/spec/core/schema_generator_spec.rb +6 -6
- data/spec/core/schema_spec.rb +54 -5
- data/spec/core_extensions_spec.rb +122 -18
- data/spec/deprecation_helper.rb +27 -2
- data/spec/extensions/_deprecated_identifier_mangling_spec.rb +6 -6
- data/spec/extensions/association_proxies_spec.rb +2 -2
- data/spec/extensions/auto_literal_strings_spec.rb +212 -0
- data/spec/extensions/blacklist_security_spec.rb +1 -0
- data/spec/extensions/class_table_inheritance_spec.rb +1037 -39
- data/spec/extensions/column_select_spec.rb +20 -8
- data/spec/extensions/columns_introspection_spec.rb +3 -3
- data/spec/extensions/core_refinements_spec.rb +29 -12
- data/spec/extensions/dataset_associations_spec.rb +12 -12
- data/spec/extensions/def_dataset_method_spec.rb +100 -0
- data/spec/extensions/error_sql_spec.rb +1 -1
- data/spec/extensions/finder_spec.rb +260 -0
- data/spec/extensions/graph_each_spec.rb +2 -2
- data/spec/extensions/identifier_mangling_spec.rb +14 -8
- data/spec/extensions/inverted_subsets_spec.rb +4 -4
- data/spec/extensions/lazy_attributes_spec.rb +7 -0
- data/spec/extensions/many_through_many_spec.rb +38 -14
- data/spec/extensions/nested_attributes_spec.rb +18 -6
- data/spec/extensions/no_auto_literal_strings_spec.rb +1 -1
- data/spec/extensions/pg_enum_spec.rb +16 -1
- data/spec/extensions/pg_interval_spec.rb +11 -2
- data/spec/extensions/pg_loose_count_spec.rb +5 -0
- data/spec/extensions/pg_row_spec.rb +25 -0
- data/spec/extensions/prepared_statements_spec.rb +10 -1
- data/spec/extensions/query_spec.rb +2 -2
- data/spec/extensions/schema_dumper_spec.rb +2 -2
- data/spec/extensions/schema_spec.rb +2 -2
- data/spec/extensions/set_overrides_spec.rb +7 -3
- data/spec/extensions/sql_expr_spec.rb +0 -1
- data/spec/extensions/subset_conditions_spec.rb +6 -6
- data/spec/extensions/table_select_spec.rb +24 -12
- data/spec/extensions/to_dot_spec.rb +4 -4
- data/spec/extensions/whitelist_security_spec.rb +131 -0
- data/spec/integration/dataset_test.rb +9 -5
- data/spec/integration/model_test.rb +2 -0
- data/spec/integration/plugin_test.rb +2 -2
- data/spec/integration/spec_helper.rb +1 -1
- data/spec/model/associations_spec.rb +39 -11
- data/spec/model/base_spec.rb +44 -24
- data/spec/model/class_dataset_methods_spec.rb +18 -16
- data/spec/model/dataset_methods_spec.rb +4 -4
- data/spec/model/eager_loading_spec.rb +84 -24
- data/spec/model/model_spec.rb +97 -63
- data/spec/model/record_spec.rb +21 -13
- metadata +13 -2
|
@@ -8,7 +8,9 @@ module Sequel
|
|
|
8
8
|
|
|
9
9
|
module DatabaseMethods
|
|
10
10
|
AUTO_INCREMENT = ''.freeze
|
|
11
|
+
Sequel::Deprecation.deprecate_constant(self, :AUTO_INCREMENT)
|
|
11
12
|
TEMPORARY = 'GLOBAL TEMPORARY '.freeze
|
|
13
|
+
Sequel::Deprecation.deprecate_constant(self, :TEMPORARY)
|
|
12
14
|
|
|
13
15
|
def clear_primary_key(*tables)
|
|
14
16
|
tables.each{|t| @primary_keys.delete(dataset.send(:input_identifier, t))}
|
|
@@ -54,6 +56,10 @@ module Sequel
|
|
|
54
56
|
|
|
55
57
|
private
|
|
56
58
|
|
|
59
|
+
def temporary_table_sql
|
|
60
|
+
'GLOBAL TEMPORARY '
|
|
61
|
+
end
|
|
62
|
+
|
|
57
63
|
# Use Firebird specific syntax for add column
|
|
58
64
|
def alter_table_sql(table, op)
|
|
59
65
|
case op[:op]
|
|
@@ -70,8 +76,8 @@ module Sequel
|
|
|
70
76
|
end
|
|
71
77
|
end
|
|
72
78
|
|
|
73
|
-
def auto_increment_sql
|
|
74
|
-
|
|
79
|
+
def auto_increment_sql
|
|
80
|
+
''
|
|
75
81
|
end
|
|
76
82
|
|
|
77
83
|
def create_sequence_sql(name, opts=OPTS)
|
|
@@ -158,12 +164,18 @@ module Sequel
|
|
|
158
164
|
end
|
|
159
165
|
|
|
160
166
|
module DatasetMethods
|
|
167
|
+
NULL = LiteralString.new('NULL').freeze
|
|
168
|
+
|
|
161
169
|
BOOL_TRUE = '1'.freeze
|
|
170
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_TRUE)
|
|
162
171
|
BOOL_FALSE = '0'.freeze
|
|
163
|
-
|
|
172
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_FALSE)
|
|
164
173
|
FIRST = " FIRST ".freeze
|
|
174
|
+
Sequel::Deprecation.deprecate_constant(self, :FIRST)
|
|
165
175
|
SKIP = " SKIP ".freeze
|
|
176
|
+
Sequel::Deprecation.deprecate_constant(self, :SKIP)
|
|
166
177
|
DEFAULT_FROM = " FROM RDB$DATABASE"
|
|
178
|
+
Sequel::Deprecation.deprecate_constant(self, :DEFAULT_FROM)
|
|
167
179
|
|
|
168
180
|
Dataset.def_sql_method(self, :select, %w'with select distinct limit columns from join where group having compounds order')
|
|
169
181
|
Dataset.def_sql_method(self, :insert, %w'insert into columns values returning')
|
|
@@ -213,7 +225,7 @@ module Sequel
|
|
|
213
225
|
private
|
|
214
226
|
|
|
215
227
|
def empty_from_sql
|
|
216
|
-
|
|
228
|
+
" FROM RDB$DATABASE"
|
|
217
229
|
end
|
|
218
230
|
|
|
219
231
|
def insert_pk(*values)
|
|
@@ -222,11 +234,11 @@ module Sequel
|
|
|
222
234
|
end
|
|
223
235
|
|
|
224
236
|
def literal_false
|
|
225
|
-
|
|
237
|
+
'0'
|
|
226
238
|
end
|
|
227
239
|
|
|
228
240
|
def literal_true
|
|
229
|
-
|
|
241
|
+
'1'
|
|
230
242
|
end
|
|
231
243
|
|
|
232
244
|
# Firebird can insert multiple rows using a UNION
|
|
@@ -236,11 +248,11 @@ module Sequel
|
|
|
236
248
|
|
|
237
249
|
def select_limit_sql(sql)
|
|
238
250
|
if l = @opts[:limit]
|
|
239
|
-
sql << FIRST
|
|
251
|
+
sql << " FIRST "
|
|
240
252
|
literal_append(sql, l)
|
|
241
253
|
end
|
|
242
254
|
if o = @opts[:offset]
|
|
243
|
-
sql << SKIP
|
|
255
|
+
sql << " SKIP "
|
|
244
256
|
literal_append(sql, o)
|
|
245
257
|
end
|
|
246
258
|
end
|
|
@@ -8,6 +8,7 @@ module Sequel
|
|
|
8
8
|
|
|
9
9
|
module DatabaseMethods
|
|
10
10
|
TEMPORARY = 'TEMP '.freeze
|
|
11
|
+
Sequel::Deprecation.deprecate_constant(self, :TEMPORARY)
|
|
11
12
|
|
|
12
13
|
# Informix uses the :informix database type
|
|
13
14
|
def database_type
|
|
@@ -24,13 +25,15 @@ module Sequel
|
|
|
24
25
|
|
|
25
26
|
# SQL fragment for showing a table is temporary
|
|
26
27
|
def temporary_table_sql
|
|
27
|
-
|
|
28
|
+
'TEMP '
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
module DatasetMethods
|
|
32
33
|
FIRST = " FIRST ".freeze
|
|
34
|
+
Sequel::Deprecation.deprecate_constant(self, :FIRST)
|
|
33
35
|
SKIP = " SKIP ".freeze
|
|
36
|
+
Sequel::Deprecation.deprecate_constant(self, :SKIP)
|
|
34
37
|
|
|
35
38
|
Dataset.def_sql_method(self, :select, %w'select limit distinct columns from join where having group compounds order')
|
|
36
39
|
|
|
@@ -47,11 +50,11 @@ module Sequel
|
|
|
47
50
|
|
|
48
51
|
def select_limit_sql(sql)
|
|
49
52
|
if o = @opts[:offset]
|
|
50
|
-
sql << SKIP
|
|
53
|
+
sql << " SKIP "
|
|
51
54
|
literal_append(sql, o)
|
|
52
55
|
end
|
|
53
56
|
if l = @opts[:limit]
|
|
54
|
-
sql << FIRST
|
|
57
|
+
sql << " FIRST "
|
|
55
58
|
literal_append(sql, l)
|
|
56
59
|
end
|
|
57
60
|
end
|
|
@@ -14,14 +14,26 @@ module Sequel
|
|
|
14
14
|
|
|
15
15
|
module DatabaseMethods
|
|
16
16
|
AUTO_INCREMENT = 'IDENTITY(1,1)'.freeze
|
|
17
|
+
Sequel::Deprecation.deprecate_constant(self, :AUTO_INCREMENT)
|
|
17
18
|
SERVER_VERSION_RE = /^(\d+)\.(\d+)\.(\d+)/.freeze
|
|
19
|
+
Sequel::Deprecation.deprecate_constant(self, :SERVER_VERSION_RE)
|
|
18
20
|
SERVER_VERSION_SQL = "SELECT CAST(SERVERPROPERTY('ProductVersion') AS varchar)".freeze
|
|
21
|
+
Sequel::Deprecation.deprecate_constant(self, :SERVER_VERSION_SQL)
|
|
19
22
|
SQL_BEGIN = "BEGIN TRANSACTION".freeze
|
|
23
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_BEGIN)
|
|
20
24
|
SQL_COMMIT = "COMMIT TRANSACTION".freeze
|
|
25
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_COMMIT)
|
|
21
26
|
SQL_ROLLBACK = "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION".freeze
|
|
27
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_ROLLBACK)
|
|
22
28
|
SQL_ROLLBACK_TO_SAVEPOINT = 'IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION autopoint_%d'.freeze
|
|
29
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_ROLLBACK_TO_SAVEPOINT)
|
|
23
30
|
SQL_SAVEPOINT = 'SAVE TRANSACTION autopoint_%d'.freeze
|
|
31
|
+
Sequel::Deprecation.deprecate_constant(self, :SQL_SAVEPOINT)
|
|
24
32
|
MSSQL_DEFAULT_RE = /\A(?:\(N?('.*')\)|\(\((-?\d+(?:\.\d+)?)\)\))\z/
|
|
33
|
+
Sequel::Deprecation.deprecate_constant(self, :MSSQL_DEFAULT_RE)
|
|
34
|
+
DECIMAL_TYPE_RE = /number|numeric|decimal/io
|
|
35
|
+
Sequel::Deprecation.deprecate_constant(self, :DECIMAL_TYPE_RE)
|
|
36
|
+
|
|
25
37
|
FOREIGN_KEY_ACTION_MAP = {0 => :no_action, 1 => :cascade, 2 => :set_null, 3 => :set_default}.freeze
|
|
26
38
|
|
|
27
39
|
include Sequel::Database::SplitAlterTable
|
|
@@ -37,10 +49,6 @@ module Sequel
|
|
|
37
49
|
reset_default_dataset
|
|
38
50
|
end
|
|
39
51
|
|
|
40
|
-
# The types to check for 0 scale to transform :decimal types
|
|
41
|
-
# to :integer.
|
|
42
|
-
DECIMAL_TYPE_RE = /number|numeric|decimal/io
|
|
43
|
-
|
|
44
52
|
# Execute the given stored procedure with the given name.
|
|
45
53
|
#
|
|
46
54
|
# Options:
|
|
@@ -215,7 +223,7 @@ module Sequel
|
|
|
215
223
|
(conn.server_version rescue nil) if conn.respond_to?(:server_version)
|
|
216
224
|
end
|
|
217
225
|
unless @server_version
|
|
218
|
-
m =
|
|
226
|
+
m = /^(\d+)\.(\d+)\.(\d+)/.match(fetch("SELECT CAST(SERVERPROPERTY('ProductVersion') AS varchar)").single_value.to_s)
|
|
219
227
|
@server_version = (m[1].to_i * 1000000) + (m[2].to_i * 10000) + m[3].to_i
|
|
220
228
|
end
|
|
221
229
|
@server_version
|
|
@@ -265,7 +273,7 @@ module Sequel
|
|
|
265
273
|
|
|
266
274
|
# MSSQL uses the IDENTITY(1,1) column for autoincrementing columns.
|
|
267
275
|
def auto_increment_sql
|
|
268
|
-
|
|
276
|
+
'IDENTITY(1,1)'
|
|
269
277
|
end
|
|
270
278
|
|
|
271
279
|
# MSSQL specific syntax for altering tables.
|
|
@@ -310,12 +318,12 @@ module Sequel
|
|
|
310
318
|
|
|
311
319
|
# SQL to start a new savepoint
|
|
312
320
|
def begin_savepoint_sql(depth)
|
|
313
|
-
|
|
321
|
+
"SAVE TRANSACTION autopoint_#{depth}"
|
|
314
322
|
end
|
|
315
323
|
|
|
316
324
|
# SQL to BEGIN a transaction.
|
|
317
325
|
def begin_transaction_sql
|
|
318
|
-
|
|
326
|
+
"BEGIN TRANSACTION"
|
|
319
327
|
end
|
|
320
328
|
|
|
321
329
|
# MSSQL does not allow adding primary key constraints to NULLable columns.
|
|
@@ -325,7 +333,7 @@ module Sequel
|
|
|
325
333
|
|
|
326
334
|
# Handle MSSQL specific default format.
|
|
327
335
|
def column_schema_normalize_default(default, type)
|
|
328
|
-
if m =
|
|
336
|
+
if m = /\A(?:\(N?('.*')\)|\(\((-?\d+(?:\.\d+)?)\)\))\z/.match(default)
|
|
329
337
|
default = m[1] || m[2]
|
|
330
338
|
end
|
|
331
339
|
super(default, type)
|
|
@@ -339,7 +347,7 @@ module Sequel
|
|
|
339
347
|
|
|
340
348
|
# SQL to COMMIT a transaction.
|
|
341
349
|
def commit_transaction_sql
|
|
342
|
-
|
|
350
|
+
"COMMIT TRANSACTION"
|
|
343
351
|
end
|
|
344
352
|
|
|
345
353
|
# MSSQL uses the name of the table to decide the difference between
|
|
@@ -418,12 +426,12 @@ module Sequel
|
|
|
418
426
|
|
|
419
427
|
# SQL to rollback to a savepoint
|
|
420
428
|
def rollback_savepoint_sql(depth)
|
|
421
|
-
|
|
429
|
+
"IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION autopoint_#{depth}"
|
|
422
430
|
end
|
|
423
431
|
|
|
424
432
|
# SQL to ROLLBACK a transaction.
|
|
425
433
|
def rollback_transaction_sql
|
|
426
|
-
|
|
434
|
+
"IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
|
|
427
435
|
end
|
|
428
436
|
|
|
429
437
|
# The closest MSSQL equivalent of a boolean datatype is the bit type.
|
|
@@ -480,7 +488,7 @@ module Sequel
|
|
|
480
488
|
end
|
|
481
489
|
row[:allow_null] = row[:allow_null] == 'YES' ? true : false
|
|
482
490
|
row[:default] = nil if blank_object?(row[:default])
|
|
483
|
-
row[:type] = if row[:db_type] =~
|
|
491
|
+
row[:type] = if row[:db_type] =~ /number|numeric|decimal/i && row[:scale] == 0
|
|
484
492
|
:integer
|
|
485
493
|
else
|
|
486
494
|
schema_column_type(row[:db_type])
|
|
@@ -529,54 +537,98 @@ module Sequel
|
|
|
529
537
|
end)
|
|
530
538
|
include EmulateOffsetWithRowNumber
|
|
531
539
|
|
|
540
|
+
CONSTANT_MAP = {:CURRENT_DATE=>'CAST(CURRENT_TIMESTAMP AS DATE)'.freeze, :CURRENT_TIME=>'CAST(CURRENT_TIMESTAMP AS TIME)'.freeze}#.freeze # SEQUEL5
|
|
541
|
+
EXTRACT_MAP = {:year=>"yy", :month=>"m", :day=>"d", :hour=>"hh", :minute=>"n", :second=>"s"}#.freeze # SEQUEL5
|
|
542
|
+
#EXTRACT_MAP.each_value(&:freeze) # SEQUEL5
|
|
543
|
+
NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:disable_insert_output, :mssql_unicode_strings]).freeze
|
|
544
|
+
LIMIT_ALL = Object.new.freeze
|
|
545
|
+
|
|
532
546
|
BOOL_TRUE = '1'.freeze
|
|
547
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_TRUE)
|
|
533
548
|
BOOL_FALSE = '0'.freeze
|
|
549
|
+
Sequel::Deprecation.deprecate_constant(self, :BOOL_FALSE)
|
|
534
550
|
COMMA_SEPARATOR = ', '.freeze
|
|
551
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA_SEPARATOR)
|
|
535
552
|
TABLE_HINT = " WITH (".freeze
|
|
553
|
+
Sequel::Deprecation.deprecate_constant(self, :TABLE_HINT)
|
|
536
554
|
READPAST = "READPAST".freeze
|
|
555
|
+
Sequel::Deprecation.deprecate_constant(self, :READPAST)
|
|
537
556
|
NOLOCK = 'NOLOCK'.freeze
|
|
557
|
+
Sequel::Deprecation.deprecate_constant(self, :NOLOCK)
|
|
538
558
|
UPDLOCK = 'UPDLOCK'.freeze
|
|
559
|
+
Sequel::Deprecation.deprecate_constant(self, :UPDLOCK)
|
|
539
560
|
WILDCARD = LiteralString.new('*').freeze
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
BRACKET_OPEN =
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
561
|
+
Sequel::Deprecation.deprecate_constant(self, :WILDCARD)
|
|
562
|
+
BRACKET_CLOSE = ']'.freeze
|
|
563
|
+
Sequel::Deprecation.deprecate_constant(self, :BRACKET_CLOSE)
|
|
564
|
+
BRACKET_OPEN = '['.freeze
|
|
565
|
+
Sequel::Deprecation.deprecate_constant(self, :BRACKET_OPEN)
|
|
566
|
+
COMMA = ', '.freeze
|
|
567
|
+
Sequel::Deprecation.deprecate_constant(self, :COMMA)
|
|
568
|
+
PAREN_CLOSE = ')'.freeze
|
|
569
|
+
Sequel::Deprecation.deprecate_constant(self, :PAREN_CLOSE)
|
|
570
|
+
PAREN_SPACE_OPEN = ' ('.freeze
|
|
571
|
+
Sequel::Deprecation.deprecate_constant(self, :PAREN_SPACE_OPEN)
|
|
572
|
+
SPACE = ' '.freeze
|
|
573
|
+
Sequel::Deprecation.deprecate_constant(self, :SPACE)
|
|
574
|
+
FROM = ' FROM '.freeze
|
|
575
|
+
Sequel::Deprecation.deprecate_constant(self, :FROM)
|
|
576
|
+
APOS = "'".freeze
|
|
577
|
+
Sequel::Deprecation.deprecate_constant(self, :APOS)
|
|
578
|
+
APOS_RE = /'/.freeze
|
|
579
|
+
Sequel::Deprecation.deprecate_constant(self, :APOS_RE)
|
|
580
|
+
DOUBLE_APOS = "''".freeze
|
|
581
|
+
Sequel::Deprecation.deprecate_constant(self, :DOUBLE_APOS)
|
|
582
|
+
INTO = " INTO ".freeze
|
|
583
|
+
Sequel::Deprecation.deprecate_constant(self, :INTO)
|
|
553
584
|
DOUBLE_BRACKET_CLOSE = ']]'.freeze
|
|
585
|
+
Sequel::Deprecation.deprecate_constant(self, :DOUBLE_BRACKET_CLOSE)
|
|
554
586
|
DATEPART_SECOND_OPEN = "CAST((datepart(".freeze
|
|
587
|
+
Sequel::Deprecation.deprecate_constant(self, :DATEPART_SECOND_OPEN)
|
|
555
588
|
DATEPART_SECOND_MIDDLE = ') + datepart(ns, '.freeze
|
|
589
|
+
Sequel::Deprecation.deprecate_constant(self, :DATEPART_SECOND_MIDDLE)
|
|
556
590
|
DATEPART_SECOND_CLOSE = ")/1000000000.0) AS double precision)".freeze
|
|
591
|
+
Sequel::Deprecation.deprecate_constant(self, :DATEPART_SECOND_CLOSE)
|
|
557
592
|
DATEPART_OPEN = "datepart(".freeze
|
|
593
|
+
Sequel::Deprecation.deprecate_constant(self, :DATEPART_OPEN)
|
|
558
594
|
OUTPUT_INSERTED = " OUTPUT INSERTED.*".freeze
|
|
595
|
+
Sequel::Deprecation.deprecate_constant(self, :OUTPUT_INSERTED)
|
|
559
596
|
HEX_START = '0x'.freeze
|
|
597
|
+
Sequel::Deprecation.deprecate_constant(self, :HEX_START)
|
|
560
598
|
UNICODE_STRING_START = "N'".freeze
|
|
599
|
+
Sequel::Deprecation.deprecate_constant(self, :UNICODE_STRING_START)
|
|
561
600
|
BACKSLASH_CRLF_RE = /\\((?:\r\n)|\n)/.freeze
|
|
601
|
+
Sequel::Deprecation.deprecate_constant(self, :BACKSLASH_CRLF_RE)
|
|
562
602
|
BACKSLASH_CRLF_REPLACE = '\\\\\\\\\\1\\1'.freeze
|
|
603
|
+
Sequel::Deprecation.deprecate_constant(self, :BACKSLASH_CRLF_REPLACE)
|
|
563
604
|
TOP_PAREN = " TOP (".freeze
|
|
605
|
+
Sequel::Deprecation.deprecate_constant(self, :TOP_PAREN)
|
|
564
606
|
TOP = " TOP ".freeze
|
|
607
|
+
Sequel::Deprecation.deprecate_constant(self, :TOP)
|
|
565
608
|
OUTPUT = " OUTPUT ".freeze
|
|
609
|
+
Sequel::Deprecation.deprecate_constant(self, :OUTPUT)
|
|
566
610
|
HSTAR = "H*".freeze
|
|
611
|
+
Sequel::Deprecation.deprecate_constant(self, :HSTAR)
|
|
567
612
|
CASE_SENSITIVE_COLLATION = 'Latin1_General_CS_AS'.freeze
|
|
613
|
+
Sequel::Deprecation.deprecate_constant(self, :CASE_SENSITIVE_COLLATION)
|
|
568
614
|
CASE_INSENSITIVE_COLLATION = 'Latin1_General_CI_AS'.freeze
|
|
615
|
+
Sequel::Deprecation.deprecate_constant(self, :CASE_INSENSITIVE_COLLATION)
|
|
569
616
|
DEFAULT_TIMESTAMP_FORMAT = "'%Y-%m-%dT%H:%M:%S%N%z'".freeze
|
|
617
|
+
Sequel::Deprecation.deprecate_constant(self, :DEFAULT_TIMESTAMP_FORMAT)
|
|
570
618
|
FORMAT_DATE = "'%Y%m%d'".freeze
|
|
619
|
+
Sequel::Deprecation.deprecate_constant(self, :FORMAT_DATE)
|
|
571
620
|
CROSS_APPLY = 'CROSS APPLY'.freeze
|
|
621
|
+
Sequel::Deprecation.deprecate_constant(self, :CROSS_APPLY)
|
|
572
622
|
OUTER_APPLY = 'OUTER APPLY'.freeze
|
|
623
|
+
Sequel::Deprecation.deprecate_constant(self, :OUTER_APPLY)
|
|
573
624
|
OFFSET = " OFFSET ".freeze
|
|
625
|
+
Sequel::Deprecation.deprecate_constant(self, :OFFSET)
|
|
574
626
|
ROWS = " ROWS".freeze
|
|
627
|
+
Sequel::Deprecation.deprecate_constant(self, :ROWS)
|
|
575
628
|
ROWS_ONLY = " ROWS ONLY".freeze
|
|
629
|
+
Sequel::Deprecation.deprecate_constant(self, :ROWS_ONLY)
|
|
576
630
|
FETCH_NEXT = " FETCH NEXT ".freeze
|
|
577
|
-
|
|
578
|
-
NON_SQL_OPTIONS = (Dataset::NON_SQL_OPTIONS + [:disable_insert_output, :mssql_unicode_strings]).freeze
|
|
579
|
-
LIMIT_ALL = Object.new.freeze
|
|
631
|
+
Sequel::Deprecation.deprecate_constant(self, :FETCH_NEXT)
|
|
580
632
|
|
|
581
633
|
Dataset.def_mutation_method(:disable_insert_output, :output, :module=>self)
|
|
582
634
|
Dataset.def_sql_method(self, :delete, %w'with delete limit from output from2 where')
|
|
@@ -604,25 +656,25 @@ module Sequel
|
|
|
604
656
|
when :'||'
|
|
605
657
|
super(sql, :+, args)
|
|
606
658
|
when :LIKE, :"NOT LIKE"
|
|
607
|
-
super(sql, op, args.map{|a| Sequel.lit(["(", " COLLATE
|
|
659
|
+
super(sql, op, args.map{|a| Sequel.lit(["(", " COLLATE Latin1_General_CS_AS)"], a)})
|
|
608
660
|
when :ILIKE, :"NOT ILIKE"
|
|
609
|
-
super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|a| Sequel.lit(["(", " COLLATE
|
|
661
|
+
super(sql, (op == :ILIKE ? :LIKE : :"NOT LIKE"), args.map{|a| Sequel.lit(["(", " COLLATE Latin1_General_CI_AS)"], a)})
|
|
610
662
|
when :<<, :>>
|
|
611
663
|
complex_expression_emulate_append(sql, op, args)
|
|
612
664
|
when :extract
|
|
613
|
-
part = args
|
|
665
|
+
part = args[0]
|
|
614
666
|
raise(Sequel::Error, "unsupported extract argument: #{part.inspect}") unless format = EXTRACT_MAP[part]
|
|
615
667
|
if part == :second
|
|
616
|
-
expr = args
|
|
617
|
-
sql <<
|
|
668
|
+
expr = args[1]
|
|
669
|
+
sql << "CAST((datepart(" << format.to_s << ', '
|
|
618
670
|
literal_append(sql, expr)
|
|
619
|
-
sql <<
|
|
671
|
+
sql << ') + datepart(ns, '
|
|
620
672
|
literal_append(sql, expr)
|
|
621
|
-
sql <<
|
|
673
|
+
sql << ")/1000000000.0) AS double precision)"
|
|
622
674
|
else
|
|
623
|
-
sql <<
|
|
624
|
-
literal_append(sql, args
|
|
625
|
-
sql <<
|
|
675
|
+
sql << "datepart(" << format.to_s << ', '
|
|
676
|
+
literal_append(sql, args[1])
|
|
677
|
+
sql << ')'
|
|
626
678
|
end
|
|
627
679
|
else
|
|
628
680
|
super
|
|
@@ -656,7 +708,7 @@ module Sequel
|
|
|
656
708
|
# MSSQL uses the CONTAINS keyword for full text search
|
|
657
709
|
def full_text_search(cols, terms, opts = OPTS)
|
|
658
710
|
terms = "\"#{terms.join('" OR "')}\"" if terms.is_a?(Array)
|
|
659
|
-
where("CONTAINS (?, ?)", cols, terms)
|
|
711
|
+
where(Sequel.lit("CONTAINS (?, ?)", cols, terms))
|
|
660
712
|
end
|
|
661
713
|
|
|
662
714
|
# Use the OUTPUT clause to get the value of all columns for the newly inserted record.
|
|
@@ -714,7 +766,7 @@ module Sequel
|
|
|
714
766
|
|
|
715
767
|
# MSSQL uses [] to quote identifiers.
|
|
716
768
|
def quoted_identifier_append(sql, name)
|
|
717
|
-
sql <<
|
|
769
|
+
sql << '[' << name.to_s.gsub(/\]/, ']]') << ']'
|
|
718
770
|
end
|
|
719
771
|
|
|
720
772
|
# Emulate RETURNING using the output clause. This only handles values that are simple column references.
|
|
@@ -895,12 +947,12 @@ module Sequel
|
|
|
895
947
|
# since that is the format that is multilanguage and not
|
|
896
948
|
# DATEFORMAT dependent.
|
|
897
949
|
def default_timestamp_format
|
|
898
|
-
|
|
950
|
+
"'%Y-%m-%dT%H:%M:%S%N%z'"
|
|
899
951
|
end
|
|
900
952
|
|
|
901
953
|
# Only include the primary table in the main delete clause
|
|
902
954
|
def delete_from_sql(sql)
|
|
903
|
-
sql << FROM
|
|
955
|
+
sql << ' FROM '
|
|
904
956
|
source_list_append(sql, @opts[:from][0..0])
|
|
905
957
|
end
|
|
906
958
|
|
|
@@ -954,9 +1006,9 @@ module Sequel
|
|
|
954
1006
|
def join_type_sql(join_type)
|
|
955
1007
|
case join_type
|
|
956
1008
|
when :cross_apply
|
|
957
|
-
|
|
1009
|
+
'CROSS APPLY'
|
|
958
1010
|
when :outer_apply
|
|
959
|
-
|
|
1011
|
+
'OUTER APPLY'
|
|
960
1012
|
else
|
|
961
1013
|
super
|
|
962
1014
|
end
|
|
@@ -964,30 +1016,30 @@ module Sequel
|
|
|
964
1016
|
|
|
965
1017
|
# MSSQL uses a literal hexidecimal number for blob strings
|
|
966
1018
|
def literal_blob_append(sql, v)
|
|
967
|
-
sql <<
|
|
1019
|
+
sql << '0x' << v.unpack("H*").first
|
|
968
1020
|
end
|
|
969
1021
|
|
|
970
1022
|
# Use YYYYmmdd format, since that's the only want that is
|
|
971
1023
|
# multilanguage and not DATEFORMAT dependent.
|
|
972
1024
|
def literal_date(v)
|
|
973
|
-
v.strftime(
|
|
1025
|
+
v.strftime("'%Y%m%d'")
|
|
974
1026
|
end
|
|
975
1027
|
|
|
976
1028
|
# Use 0 for false on MSSQL
|
|
977
1029
|
def literal_false
|
|
978
|
-
|
|
1030
|
+
'0'
|
|
979
1031
|
end
|
|
980
1032
|
|
|
981
1033
|
# Optionally use unicode string syntax for all strings. Don't double
|
|
982
1034
|
# backslashes.
|
|
983
1035
|
def literal_string_append(sql, v)
|
|
984
|
-
sql << (mssql_unicode_strings ?
|
|
985
|
-
sql << v.gsub(
|
|
1036
|
+
sql << (mssql_unicode_strings ? "N'" : "'")
|
|
1037
|
+
sql << v.gsub("'", "''").gsub(/\\((?:\r\n)|\n)/, '\\\\\\\\\\1\\1') << "'"
|
|
986
1038
|
end
|
|
987
1039
|
|
|
988
1040
|
# Use 1 for true on MSSQL
|
|
989
1041
|
def literal_true
|
|
990
|
-
|
|
1042
|
+
'1'
|
|
991
1043
|
end
|
|
992
1044
|
|
|
993
1045
|
# MSSQL 2008+ supports multiple rows in the VALUES clause, older versions
|
|
@@ -1003,7 +1055,7 @@ module Sequel
|
|
|
1003
1055
|
|
|
1004
1056
|
def select_into_sql(sql)
|
|
1005
1057
|
if i = @opts[:into]
|
|
1006
|
-
sql << INTO
|
|
1058
|
+
sql << " INTO "
|
|
1007
1059
|
identifier_append(sql, i)
|
|
1008
1060
|
end
|
|
1009
1061
|
end
|
|
@@ -1022,12 +1074,12 @@ module Sequel
|
|
|
1022
1074
|
if l == LIMIT_ALL
|
|
1023
1075
|
sql << " TOP (100) PERCENT"
|
|
1024
1076
|
else
|
|
1025
|
-
sql <<
|
|
1077
|
+
sql << " TOP ("
|
|
1026
1078
|
literal_append(sql, l)
|
|
1027
|
-
sql <<
|
|
1079
|
+
sql << ')'
|
|
1028
1080
|
end
|
|
1029
1081
|
else
|
|
1030
|
-
sql << TOP
|
|
1082
|
+
sql << " TOP "
|
|
1031
1083
|
literal_append(sql, l)
|
|
1032
1084
|
end
|
|
1033
1085
|
end
|
|
@@ -1048,25 +1100,25 @@ module Sequel
|
|
|
1048
1100
|
lock_hint = for_update || dirty
|
|
1049
1101
|
|
|
1050
1102
|
if lock_hint || skip_locked
|
|
1051
|
-
sql <<
|
|
1103
|
+
sql << " WITH ("
|
|
1052
1104
|
|
|
1053
1105
|
if lock_hint
|
|
1054
1106
|
sql << if for_update
|
|
1055
|
-
UPDLOCK
|
|
1107
|
+
'UPDLOCK'
|
|
1056
1108
|
else
|
|
1057
|
-
NOLOCK
|
|
1109
|
+
'NOLOCK'
|
|
1058
1110
|
end
|
|
1059
1111
|
end
|
|
1060
1112
|
|
|
1061
1113
|
if lock_hint && skip_locked
|
|
1062
|
-
sql <<
|
|
1114
|
+
sql << ', '
|
|
1063
1115
|
end
|
|
1064
1116
|
|
|
1065
1117
|
if skip_locked
|
|
1066
|
-
sql << READPAST
|
|
1118
|
+
sql << "READPAST"
|
|
1067
1119
|
end
|
|
1068
1120
|
|
|
1069
|
-
sql <<
|
|
1121
|
+
sql << ')'
|
|
1070
1122
|
else
|
|
1071
1123
|
super
|
|
1072
1124
|
end
|
|
@@ -1078,14 +1130,14 @@ module Sequel
|
|
|
1078
1130
|
super
|
|
1079
1131
|
if is_2012_or_later? && @opts[:order]
|
|
1080
1132
|
if o = @opts[:offset]
|
|
1081
|
-
sql << OFFSET
|
|
1133
|
+
sql << " OFFSET "
|
|
1082
1134
|
literal_append(sql, o)
|
|
1083
|
-
sql << ROWS
|
|
1135
|
+
sql << " ROWS"
|
|
1084
1136
|
|
|
1085
1137
|
if l = @opts[:limit]
|
|
1086
|
-
sql <<
|
|
1138
|
+
sql << " FETCH NEXT "
|
|
1087
1139
|
literal_append(sql, l)
|
|
1088
|
-
sql <<
|
|
1140
|
+
sql << " ROWS ONLY"
|
|
1089
1141
|
end
|
|
1090
1142
|
end
|
|
1091
1143
|
end
|
|
@@ -1102,21 +1154,21 @@ module Sequel
|
|
|
1102
1154
|
end
|
|
1103
1155
|
|
|
1104
1156
|
def output_list_sql(sql, output)
|
|
1105
|
-
sql << OUTPUT
|
|
1157
|
+
sql << " OUTPUT "
|
|
1106
1158
|
column_list_append(sql, output[:select_list])
|
|
1107
1159
|
if into = output[:into]
|
|
1108
|
-
sql << INTO
|
|
1160
|
+
sql << " INTO "
|
|
1109
1161
|
identifier_append(sql, into)
|
|
1110
1162
|
if column_list = output[:column_list]
|
|
1111
|
-
sql <<
|
|
1163
|
+
sql << ' ('
|
|
1112
1164
|
source_list_append(sql, column_list)
|
|
1113
|
-
sql <<
|
|
1165
|
+
sql << ')'
|
|
1114
1166
|
end
|
|
1115
1167
|
end
|
|
1116
1168
|
end
|
|
1117
1169
|
|
|
1118
1170
|
def output_returning_sql(sql, type, values)
|
|
1119
|
-
sql << OUTPUT
|
|
1171
|
+
sql << " OUTPUT "
|
|
1120
1172
|
if values.empty?
|
|
1121
1173
|
literal_append(sql, SQL::ColumnAll.new(type))
|
|
1122
1174
|
else
|
|
@@ -1132,14 +1184,22 @@ module Sequel
|
|
|
1132
1184
|
end
|
|
1133
1185
|
end
|
|
1134
1186
|
|
|
1135
|
-
# MSSQL supports
|
|
1187
|
+
# MSSQL supports 100-nsec precision for time columns, but ruby by
|
|
1188
|
+
# default only supports usec precision.
|
|
1189
|
+
def sqltime_precision
|
|
1190
|
+
6
|
|
1191
|
+
end
|
|
1192
|
+
|
|
1193
|
+
# MSSQL supports millisecond timestamp precision for datetime columns.
|
|
1194
|
+
# 100-nsec precision is supported for datetime2 columns, but Sequel does
|
|
1195
|
+
# not know what the column type is when formatting values.
|
|
1136
1196
|
def timestamp_precision
|
|
1137
1197
|
3
|
|
1138
1198
|
end
|
|
1139
1199
|
|
|
1140
1200
|
# Only include the primary table in the main update clause
|
|
1141
1201
|
def update_table_sql(sql)
|
|
1142
|
-
sql <<
|
|
1202
|
+
sql << ' '
|
|
1143
1203
|
source_list_append(sql, @opts[:from][0..0])
|
|
1144
1204
|
end
|
|
1145
1205
|
|