activerecord-sqlserver-adapter 6.0.0.rc1 → 6.0.0.rc2
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/.gitignore +1 -0
- data/.rubocop.yml +29 -0
- data/CHANGELOG.md +20 -0
- data/Gemfile +11 -5
- data/Guardfile +9 -8
- data/Rakefile +12 -16
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +3 -3
- data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +0 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +1 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +3 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +1 -3
- data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +35 -32
- data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +7 -12
- data/lib/active_record/connection_adapters/sqlserver/errors.rb +0 -3
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +8 -8
- data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +7 -7
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +106 -103
- data/lib/active_record/connection_adapters/sqlserver/showplan.rb +6 -8
- data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +1 -4
- data/lib/active_record/connection_adapters/sqlserver/transaction.rb +4 -8
- data/lib/active_record/connection_adapters/sqlserver/type.rb +35 -35
- data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/char.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/data.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/date.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/float.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/json.rb +0 -1
- data/lib/active_record/connection_adapters/sqlserver/type/money.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/real.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/string.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/text.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/time.rb +2 -3
- data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +6 -9
- data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +1 -3
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_string.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +1 -2
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +1 -3
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +1 -3
- data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver/utils.rb +8 -11
- data/lib/active_record/connection_adapters/sqlserver/version.rb +0 -2
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +85 -83
- data/lib/active_record/connection_adapters/sqlserver_column.rb +0 -2
- data/lib/active_record/sqlserver_base.rb +1 -1
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +26 -32
- data/lib/activerecord-sqlserver-adapter.rb +1 -1
- data/lib/arel/visitors/sqlserver.rb +18 -14
- data/lib/arel_sqlserver.rb +2 -2
- data/test/cases/adapter_test_sqlserver.rb +161 -182
- data/test/cases/change_column_null_test_sqlserver.rb +12 -12
- data/test/cases/coerced_tests.rb +88 -270
- data/test/cases/column_test_sqlserver.rb +281 -283
- data/test/cases/connection_test_sqlserver.rb +15 -20
- data/test/cases/execute_procedure_test_sqlserver.rb +18 -20
- data/test/cases/fetch_test_sqlserver.rb +14 -22
- data/test/cases/fully_qualified_identifier_test_sqlserver.rb +12 -18
- data/test/cases/helper_sqlserver.rb +13 -15
- data/test/cases/in_clause_test_sqlserver.rb +9 -9
- data/test/cases/index_test_sqlserver.rb +13 -15
- data/test/cases/json_test_sqlserver.rb +23 -25
- data/test/cases/migration_test_sqlserver.rb +22 -28
- data/test/cases/order_test_sqlserver.rb +51 -54
- data/test/cases/pessimistic_locking_test_sqlserver.rb +25 -33
- data/test/cases/rake_test_sqlserver.rb +31 -45
- data/test/cases/schema_dumper_test_sqlserver.rb +104 -108
- data/test/cases/schema_test_sqlserver.rb +18 -26
- data/test/cases/scratchpad_test_sqlserver.rb +2 -4
- data/test/cases/showplan_test_sqlserver.rb +24 -33
- data/test/cases/specific_schema_test_sqlserver.rb +66 -65
- data/test/cases/transaction_test_sqlserver.rb +16 -19
- data/test/cases/trigger_test_sqlserver.rb +12 -12
- data/test/cases/utils_test_sqlserver.rb +68 -70
- data/test/cases/uuid_test_sqlserver.rb +11 -13
- data/test/debug.rb +6 -6
- data/test/migrations/create_clients_and_change_column_null.rb +1 -1
- data/test/migrations/transaction_table/1_table_will_never_be_created.rb +2 -4
- data/test/models/sqlserver/booking.rb +1 -1
- data/test/models/sqlserver/customers_view.rb +1 -1
- data/test/models/sqlserver/dollar_table_name.rb +1 -1
- data/test/models/sqlserver/edge_schema.rb +1 -3
- data/test/models/sqlserver/fk_has_fk.rb +1 -1
- data/test/models/sqlserver/fk_has_pk.rb +1 -1
- data/test/models/sqlserver/natural_pk_data.rb +2 -2
- data/test/models/sqlserver/natural_pk_int_data.rb +1 -1
- data/test/models/sqlserver/no_pk_data.rb +1 -1
- data/test/models/sqlserver/object_default.rb +1 -1
- data/test/models/sqlserver/quoted_table.rb +2 -2
- data/test/models/sqlserver/quoted_view_1.rb +1 -1
- data/test/models/sqlserver/quoted_view_2.rb +1 -1
- data/test/models/sqlserver/sst_memory.rb +1 -1
- data/test/models/sqlserver/string_default.rb +1 -1
- data/test/models/sqlserver/string_defaults_big_view.rb +1 -1
- data/test/models/sqlserver/string_defaults_view.rb +1 -1
- data/test/models/sqlserver/tinyint_pk.rb +1 -1
- data/test/models/sqlserver/trigger.rb +2 -2
- data/test/models/sqlserver/trigger_history.rb +1 -1
- data/test/models/sqlserver/upper.rb +1 -1
- data/test/models/sqlserver/uppered.rb +1 -1
- data/test/models/sqlserver/uuid.rb +1 -1
- data/test/schema/sqlserver_specific_schema.rb +20 -22
- data/test/support/coerceable_test_sqlserver.rb +1 -4
- data/test/support/connection_reflection.rb +1 -2
- data/test/support/core_ext/query_cache.rb +1 -1
- data/test/support/load_schema_sqlserver.rb +3 -5
- data/test/support/minitest_sqlserver.rb +1 -1
- data/test/support/paths_sqlserver.rb +9 -11
- data/test/support/rake_helpers.rb +12 -10
- data/test/support/sql_counter_sqlserver.rb +0 -4
- data/test/support/test_in_memory_oltp.rb +7 -7
- metadata +5 -4
|
@@ -1,40 +1,39 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require
|
|
10
|
-
require
|
|
11
|
-
require
|
|
12
|
-
require
|
|
13
|
-
require
|
|
14
|
-
require
|
|
15
|
-
require
|
|
16
|
-
require
|
|
17
|
-
require
|
|
18
|
-
require
|
|
19
|
-
require
|
|
20
|
-
require
|
|
21
|
-
require
|
|
22
|
-
require
|
|
23
|
-
require
|
|
24
|
-
require
|
|
25
|
-
require
|
|
26
|
-
require
|
|
27
|
-
require
|
|
28
|
-
require
|
|
29
|
-
require
|
|
30
|
-
require
|
|
31
|
-
require
|
|
32
|
-
require
|
|
3
|
+
require "base64"
|
|
4
|
+
require "active_record"
|
|
5
|
+
require "arel_sqlserver"
|
|
6
|
+
require "active_record/connection_adapters/abstract_adapter"
|
|
7
|
+
require "active_record/connection_adapters/sqlserver/core_ext/active_record"
|
|
8
|
+
require "active_record/connection_adapters/sqlserver/core_ext/calculations"
|
|
9
|
+
require "active_record/connection_adapters/sqlserver/core_ext/explain"
|
|
10
|
+
require "active_record/connection_adapters/sqlserver/core_ext/explain_subscriber"
|
|
11
|
+
require "active_record/connection_adapters/sqlserver/core_ext/attribute_methods"
|
|
12
|
+
require "active_record/connection_adapters/sqlserver/core_ext/finder_methods"
|
|
13
|
+
require "active_record/connection_adapters/sqlserver/core_ext/query_methods"
|
|
14
|
+
require "active_record/connection_adapters/sqlserver/core_ext/preloader"
|
|
15
|
+
require "active_record/connection_adapters/sqlserver/version"
|
|
16
|
+
require "active_record/connection_adapters/sqlserver/type"
|
|
17
|
+
require "active_record/connection_adapters/sqlserver/database_limits"
|
|
18
|
+
require "active_record/connection_adapters/sqlserver/database_statements"
|
|
19
|
+
require "active_record/connection_adapters/sqlserver/database_tasks"
|
|
20
|
+
require "active_record/connection_adapters/sqlserver/transaction"
|
|
21
|
+
require "active_record/connection_adapters/sqlserver/errors"
|
|
22
|
+
require "active_record/connection_adapters/sqlserver/schema_creation"
|
|
23
|
+
require "active_record/connection_adapters/sqlserver/schema_dumper"
|
|
24
|
+
require "active_record/connection_adapters/sqlserver/schema_statements"
|
|
25
|
+
require "active_record/connection_adapters/sqlserver/sql_type_metadata"
|
|
26
|
+
require "active_record/connection_adapters/sqlserver/showplan"
|
|
27
|
+
require "active_record/connection_adapters/sqlserver/table_definition"
|
|
28
|
+
require "active_record/connection_adapters/sqlserver/quoting"
|
|
29
|
+
require "active_record/connection_adapters/sqlserver/utils"
|
|
30
|
+
require "active_record/sqlserver_base"
|
|
31
|
+
require "active_record/connection_adapters/sqlserver_column"
|
|
32
|
+
require "active_record/tasks/sqlserver_database_tasks"
|
|
33
33
|
|
|
34
34
|
module ActiveRecord
|
|
35
35
|
module ConnectionAdapters
|
|
36
36
|
class SQLServerAdapter < AbstractAdapter
|
|
37
|
-
|
|
38
37
|
include SQLServer::Version,
|
|
39
38
|
SQLServer::Quoting,
|
|
40
39
|
SQLServer::DatabaseStatements,
|
|
@@ -43,7 +42,7 @@ module ActiveRecord
|
|
|
43
42
|
SQLServer::DatabaseLimits,
|
|
44
43
|
SQLServer::DatabaseTasks
|
|
45
44
|
|
|
46
|
-
ADAPTER_NAME =
|
|
45
|
+
ADAPTER_NAME = "SQLServer".freeze
|
|
47
46
|
|
|
48
47
|
# Default precision for 'time' (See https://docs.microsoft.com/en-us/sql/t-sql/data-types/time-transact-sql)
|
|
49
48
|
DEFAULT_TIME_PRECISION = 7
|
|
@@ -56,7 +55,7 @@ module ActiveRecord
|
|
|
56
55
|
cattr_accessor :showplan_option, instance_accessor: false
|
|
57
56
|
cattr_accessor :lowercase_schema_reflection
|
|
58
57
|
|
|
59
|
-
self.cs_equality_operator =
|
|
58
|
+
self.cs_equality_operator = "COLLATE Latin1_General_CS_AS_WS"
|
|
60
59
|
self.use_output_inserted = true
|
|
61
60
|
self.exclude_output_inserted_table_names = Concurrent::Map.new { false }
|
|
62
61
|
|
|
@@ -189,7 +188,8 @@ module ActiveRecord
|
|
|
189
188
|
|
|
190
189
|
def active?
|
|
191
190
|
return false unless @connection
|
|
192
|
-
|
|
191
|
+
|
|
192
|
+
raw_connection_do "SELECT 1"
|
|
193
193
|
true
|
|
194
194
|
rescue *connection_errors
|
|
195
195
|
false
|
|
@@ -219,7 +219,7 @@ module ActiveRecord
|
|
|
219
219
|
|
|
220
220
|
def reset!
|
|
221
221
|
reset_transaction
|
|
222
|
-
do_execute
|
|
222
|
+
do_execute "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
|
|
223
223
|
end
|
|
224
224
|
|
|
225
225
|
# === Abstract Adapter (Misc Support) =========================== #
|
|
@@ -254,6 +254,7 @@ module ActiveRecord
|
|
|
254
254
|
|
|
255
255
|
def database_prefix_remote_server?
|
|
256
256
|
return false if database_prefix.blank?
|
|
257
|
+
|
|
257
258
|
name = SQLServer::Utils.extract_identifiers(database_prefix)
|
|
258
259
|
name.fully_qualified? && name.object.blank?
|
|
259
260
|
end
|
|
@@ -294,31 +295,31 @@ module ActiveRecord
|
|
|
294
295
|
# === Abstract Adapter (Misc Support) =========================== #
|
|
295
296
|
|
|
296
297
|
def initialize_type_map(m = type_map)
|
|
297
|
-
m.register_type %r{.*},
|
|
298
|
+
m.register_type %r{.*}, SQLServer::Type::UnicodeString.new
|
|
298
299
|
# Exact Numerics
|
|
299
|
-
register_class_with_limit m,
|
|
300
|
-
m.alias_type
|
|
301
|
-
register_class_with_limit m,
|
|
302
|
-
m.alias_type
|
|
303
|
-
m.alias_type
|
|
304
|
-
register_class_with_limit m,
|
|
305
|
-
m.alias_type
|
|
306
|
-
register_class_with_limit m,
|
|
307
|
-
m.alias_type
|
|
308
|
-
m.register_type
|
|
300
|
+
register_class_with_limit m, "bigint(8)", SQLServer::Type::BigInteger
|
|
301
|
+
m.alias_type "bigint", "bigint(8)"
|
|
302
|
+
register_class_with_limit m, "int(4)", SQLServer::Type::Integer
|
|
303
|
+
m.alias_type "integer", "int(4)"
|
|
304
|
+
m.alias_type "int", "int(4)"
|
|
305
|
+
register_class_with_limit m, "smallint(2)", SQLServer::Type::SmallInteger
|
|
306
|
+
m.alias_type "smallint", "smallint(2)"
|
|
307
|
+
register_class_with_limit m, "tinyint(1)", SQLServer::Type::TinyInteger
|
|
308
|
+
m.alias_type "tinyint", "tinyint(1)"
|
|
309
|
+
m.register_type "bit", SQLServer::Type::Boolean.new
|
|
309
310
|
m.register_type %r{\Adecimal}i do |sql_type|
|
|
310
311
|
scale = extract_scale(sql_type)
|
|
311
312
|
precision = extract_precision(sql_type)
|
|
312
313
|
SQLServer::Type::Decimal.new precision: precision, scale: scale
|
|
313
314
|
end
|
|
314
|
-
m.alias_type %r{\Anumeric}i,
|
|
315
|
-
m.register_type
|
|
316
|
-
m.register_type
|
|
315
|
+
m.alias_type %r{\Anumeric}i, "decimal"
|
|
316
|
+
m.register_type "money", SQLServer::Type::Money.new
|
|
317
|
+
m.register_type "smallmoney", SQLServer::Type::SmallMoney.new
|
|
317
318
|
# Approximate Numerics
|
|
318
|
-
m.register_type
|
|
319
|
-
m.register_type
|
|
319
|
+
m.register_type "float", SQLServer::Type::Float.new
|
|
320
|
+
m.register_type "real", SQLServer::Type::Real.new
|
|
320
321
|
# Date and Time
|
|
321
|
-
m.register_type
|
|
322
|
+
m.register_type "date", SQLServer::Type::Date.new
|
|
322
323
|
m.register_type %r{\Adatetime} do |sql_type|
|
|
323
324
|
precision = extract_precision(sql_type)
|
|
324
325
|
if precision
|
|
@@ -327,11 +328,11 @@ module ActiveRecord
|
|
|
327
328
|
SQLServer::Type::DateTime.new
|
|
328
329
|
end
|
|
329
330
|
end
|
|
330
|
-
m.register_type
|
|
331
|
+
m.register_type %r{\Adatetimeoffset}i do |sql_type|
|
|
331
332
|
precision = extract_precision(sql_type)
|
|
332
333
|
SQLServer::Type::DateTimeOffset.new precision: precision
|
|
333
334
|
end
|
|
334
|
-
m.register_type
|
|
335
|
+
m.register_type "smalldatetime", SQLServer::Type::SmallDateTime.new
|
|
335
336
|
m.register_type %r{\Atime}i do |sql_type|
|
|
336
337
|
precision = extract_precision(sql_type) || DEFAULT_TIME_PRECISION
|
|
337
338
|
SQLServer::Type::Time.new precision: precision
|
|
@@ -339,22 +340,22 @@ module ActiveRecord
|
|
|
339
340
|
# Character Strings
|
|
340
341
|
register_class_with_limit m, %r{\Achar}i, SQLServer::Type::Char
|
|
341
342
|
register_class_with_limit m, %r{\Avarchar}i, SQLServer::Type::Varchar
|
|
342
|
-
m.register_type
|
|
343
|
-
m.register_type
|
|
343
|
+
m.register_type "varchar(max)", SQLServer::Type::VarcharMax.new
|
|
344
|
+
m.register_type "text", SQLServer::Type::Text.new
|
|
344
345
|
# Unicode Character Strings
|
|
345
346
|
register_class_with_limit m, %r{\Anchar}i, SQLServer::Type::UnicodeChar
|
|
346
347
|
register_class_with_limit m, %r{\Anvarchar}i, SQLServer::Type::UnicodeVarchar
|
|
347
|
-
m.alias_type
|
|
348
|
-
m.register_type
|
|
349
|
-
m.register_type
|
|
350
|
-
m.register_type
|
|
348
|
+
m.alias_type "string", "nvarchar(4000)"
|
|
349
|
+
m.register_type "nvarchar(max)", SQLServer::Type::UnicodeVarcharMax.new
|
|
350
|
+
m.register_type "nvarchar(max)", SQLServer::Type::UnicodeVarcharMax.new
|
|
351
|
+
m.register_type "ntext", SQLServer::Type::UnicodeText.new
|
|
351
352
|
# Binary Strings
|
|
352
353
|
register_class_with_limit m, %r{\Abinary}i, SQLServer::Type::Binary
|
|
353
354
|
register_class_with_limit m, %r{\Avarbinary}i, SQLServer::Type::Varbinary
|
|
354
|
-
m.register_type
|
|
355
|
+
m.register_type "varbinary(max)", SQLServer::Type::VarbinaryMax.new
|
|
355
356
|
# Other Data Types
|
|
356
|
-
m.register_type
|
|
357
|
-
m.register_type
|
|
357
|
+
m.register_type "uniqueidentifier", SQLServer::Type::Uuid.new
|
|
358
|
+
m.register_type "timestamp", SQLServer::Type::Timestamp.new
|
|
358
359
|
end
|
|
359
360
|
|
|
360
361
|
def translate_exception(e, message:, sql:, binds:)
|
|
@@ -398,7 +399,7 @@ module ActiveRecord
|
|
|
398
399
|
when :dblib
|
|
399
400
|
dblib_connect(config)
|
|
400
401
|
end
|
|
401
|
-
@spid = _raw_select(
|
|
402
|
+
@spid = _raw_select("SELECT @@SPID", fetch: :rows).first.first
|
|
402
403
|
@version_year = version_year
|
|
403
404
|
configure_connection
|
|
404
405
|
end
|
|
@@ -417,32 +418,32 @@ module ActiveRecord
|
|
|
417
418
|
username: config[:username],
|
|
418
419
|
password: config[:password],
|
|
419
420
|
database: config[:database],
|
|
420
|
-
tds_version: config[:tds_version] ||
|
|
421
|
+
tds_version: config[:tds_version] || "7.3",
|
|
421
422
|
appname: config_appname(config),
|
|
422
423
|
login_timeout: config_login_timeout(config),
|
|
423
424
|
timeout: config_timeout(config),
|
|
424
|
-
encoding:
|
|
425
|
+
encoding: config_encoding(config),
|
|
425
426
|
azure: config[:azure],
|
|
426
427
|
contained: config[:contained]
|
|
427
428
|
).tap do |client|
|
|
428
429
|
if config[:azure]
|
|
429
|
-
client.execute(
|
|
430
|
-
client.execute(
|
|
431
|
-
client.execute(
|
|
432
|
-
client.execute(
|
|
430
|
+
client.execute("SET ANSI_NULLS ON").do
|
|
431
|
+
client.execute("SET ANSI_NULL_DFLT_ON ON").do
|
|
432
|
+
client.execute("SET ANSI_PADDING ON").do
|
|
433
|
+
client.execute("SET ANSI_WARNINGS ON").do
|
|
433
434
|
else
|
|
434
|
-
client.execute(
|
|
435
|
+
client.execute("SET ANSI_DEFAULTS ON").do
|
|
435
436
|
end
|
|
436
|
-
client.execute(
|
|
437
|
-
client.execute(
|
|
438
|
-
client.execute(
|
|
439
|
-
client.execute(
|
|
440
|
-
client.execute(
|
|
437
|
+
client.execute("SET QUOTED_IDENTIFIER ON").do
|
|
438
|
+
client.execute("SET CURSOR_CLOSE_ON_COMMIT OFF").do
|
|
439
|
+
client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
|
|
440
|
+
client.execute("SET TEXTSIZE 2147483647").do
|
|
441
|
+
client.execute("SET CONCAT_NULL_YIELDS_NULL ON").do
|
|
441
442
|
end
|
|
442
443
|
end
|
|
443
444
|
|
|
444
445
|
def config_appname(config)
|
|
445
|
-
config[:appname] || configure_application_name || Rails.application.class.name.split(
|
|
446
|
+
config[:appname] || configure_application_name || Rails.application.class.name.split("::").first rescue nil
|
|
446
447
|
end
|
|
447
448
|
|
|
448
449
|
def config_login_timeout(config)
|
|
@@ -457,18 +458,18 @@ module ActiveRecord
|
|
|
457
458
|
config[:encoding].present? ? config[:encoding] : nil
|
|
458
459
|
end
|
|
459
460
|
|
|
460
|
-
def configure_connection
|
|
461
|
+
def configure_connection; end
|
|
461
462
|
|
|
462
|
-
def configure_application_name
|
|
463
|
+
def configure_application_name; end
|
|
463
464
|
|
|
464
465
|
def initialize_dateformatter
|
|
465
466
|
@database_dateformat = user_options_dateformat
|
|
466
467
|
a, b, c = @database_dateformat.each_char.to_a
|
|
467
|
-
[a, b, c].each { |f| f.upcase! if f ==
|
|
468
|
+
[a, b, c].each { |f| f.upcase! if f == "y" }
|
|
468
469
|
dateformat = "%#{a}-%#{b}-%#{c}"
|
|
469
470
|
::Date::DATE_FORMATS[:_sqlserver_dateformat] = dateformat
|
|
470
471
|
::Time::DATE_FORMATS[:_sqlserver_dateformat] = dateformat
|
|
471
|
-
::Time::DATE_FORMATS[:_sqlserver_time] =
|
|
472
|
+
::Time::DATE_FORMATS[:_sqlserver_time] = "%H:%M:%S"
|
|
472
473
|
::Time::DATE_FORMATS[:_sqlserver_datetime] = "#{dateformat} %H:%M:%S"
|
|
473
474
|
::Time::DATE_FORMATS[:_sqlserver_datetimeoffset] = lambda { |time|
|
|
474
475
|
time.strftime "#{dateformat} %H:%M:%S.%9N #{time.formatted_offset}"
|
|
@@ -477,13 +478,14 @@ module ActiveRecord
|
|
|
477
478
|
|
|
478
479
|
def version_year
|
|
479
480
|
return 2016 if sqlserver_version =~ /vNext/
|
|
481
|
+
|
|
480
482
|
/SQL Server (\d+)/.match(sqlserver_version).to_a.last.to_s.to_i
|
|
481
|
-
rescue StandardError
|
|
483
|
+
rescue StandardError
|
|
482
484
|
2016
|
|
483
485
|
end
|
|
484
486
|
|
|
485
487
|
def sqlserver_version
|
|
486
|
-
@sqlserver_version ||= _raw_select(
|
|
488
|
+
@sqlserver_version ||= _raw_select("SELECT @@version", fetch: :rows).first.first.to_s
|
|
487
489
|
end
|
|
488
490
|
end
|
|
489
491
|
end
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
|
5
5
|
class SQLServerColumn < Column
|
|
6
|
-
|
|
7
6
|
def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil, **sqlserver_options)
|
|
8
7
|
@sqlserver_options = sqlserver_options
|
|
9
8
|
super
|
|
@@ -28,7 +27,6 @@ module ActiveRecord
|
|
|
28
27
|
def case_sensitive?
|
|
29
28
|
collation && collation.match(/_CS/)
|
|
30
29
|
end
|
|
31
|
-
|
|
32
30
|
end
|
|
33
31
|
end
|
|
34
32
|
end
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
3
|
+
require "active_record/tasks/database_tasks"
|
|
4
|
+
require "shellwords"
|
|
5
|
+
require "ipaddr"
|
|
6
|
+
require "socket"
|
|
7
7
|
|
|
8
8
|
module ActiveRecord
|
|
9
9
|
module Tasks
|
|
10
|
-
|
|
11
10
|
class SQLServerDatabaseTasks
|
|
12
|
-
|
|
13
|
-
DEFAULT_COLLATION = 'SQL_Latin1_General_CP1_CI_AS'
|
|
11
|
+
DEFAULT_COLLATION = "SQL_Latin1_General_CP1_CI_AS"
|
|
14
12
|
|
|
15
13
|
delegate :connection, :establish_connection, :clear_active_connections!,
|
|
16
14
|
to: ActiveRecord::Base
|
|
@@ -21,10 +19,10 @@ module ActiveRecord
|
|
|
21
19
|
|
|
22
20
|
def create(master_established = false)
|
|
23
21
|
establish_master_connection unless master_established
|
|
24
|
-
connection.create_database configuration[
|
|
22
|
+
connection.create_database configuration["database"], configuration.merge("collation" => default_collation)
|
|
25
23
|
establish_connection configuration
|
|
26
|
-
rescue ActiveRecord::StatementInvalid =>
|
|
27
|
-
if /database .* already exists/i ===
|
|
24
|
+
rescue ActiveRecord::StatementInvalid => e
|
|
25
|
+
if /database .* already exists/i === e.message
|
|
28
26
|
raise DatabaseAlreadyExists
|
|
29
27
|
else
|
|
30
28
|
raise
|
|
@@ -33,7 +31,7 @@ module ActiveRecord
|
|
|
33
31
|
|
|
34
32
|
def drop
|
|
35
33
|
establish_master_connection
|
|
36
|
-
connection.drop_database configuration[
|
|
34
|
+
connection.drop_database configuration["database"]
|
|
37
35
|
end
|
|
38
36
|
|
|
39
37
|
def charset
|
|
@@ -52,7 +50,7 @@ module ActiveRecord
|
|
|
52
50
|
|
|
53
51
|
def structure_dump(filename, extra_flags)
|
|
54
52
|
server_arg = "-S #{Shellwords.escape(configuration['host'])}"
|
|
55
|
-
server_arg += ":#{Shellwords.escape(configuration['port'])}" if configuration[
|
|
53
|
+
server_arg += ":#{Shellwords.escape(configuration['port'])}" if configuration["port"]
|
|
56
54
|
command = [
|
|
57
55
|
"defncopy-ttds",
|
|
58
56
|
server_arg,
|
|
@@ -65,13 +63,14 @@ module ActiveRecord
|
|
|
65
63
|
command.concat(table_args)
|
|
66
64
|
view_args = connection.views.map { |v| Shellwords.escape(v) }
|
|
67
65
|
command.concat(view_args)
|
|
68
|
-
raise
|
|
66
|
+
raise "Error dumping database" unless Kernel.system(command.join(" "))
|
|
67
|
+
|
|
69
68
|
dump = File.read(filename)
|
|
70
|
-
dump.gsub!(/^USE .*$\nGO\n/,
|
|
71
|
-
dump.gsub!(/^GO\n/,
|
|
72
|
-
dump.gsub!(/nvarchar\(8000\)/,
|
|
73
|
-
dump.gsub!(/nvarchar\(-1\)/,
|
|
74
|
-
dump.gsub!(/text\(\d+\)/,
|
|
69
|
+
dump.gsub!(/^USE .*$\nGO\n/, "") # Strip db USE statements
|
|
70
|
+
dump.gsub!(/^GO\n/, "") # Strip db GO statements
|
|
71
|
+
dump.gsub!(/nvarchar\(8000\)/, "nvarchar(4000)") # Fix nvarchar(8000) column defs
|
|
72
|
+
dump.gsub!(/nvarchar\(-1\)/, "nvarchar(max)") # Fix nvarchar(-1) column defs
|
|
73
|
+
dump.gsub!(/text\(\d+\)/, "text") # Fix text(16) column defs
|
|
75
74
|
File.open(filename, "w") { |file| file.puts dump }
|
|
76
75
|
end
|
|
77
76
|
|
|
@@ -79,7 +78,6 @@ module ActiveRecord
|
|
|
79
78
|
connection.execute File.read(filename)
|
|
80
79
|
end
|
|
81
80
|
|
|
82
|
-
|
|
83
81
|
private
|
|
84
82
|
|
|
85
83
|
def configuration
|
|
@@ -87,25 +85,22 @@ module ActiveRecord
|
|
|
87
85
|
end
|
|
88
86
|
|
|
89
87
|
def default_collation
|
|
90
|
-
configuration[
|
|
88
|
+
configuration["collation"] || DEFAULT_COLLATION
|
|
91
89
|
end
|
|
92
90
|
|
|
93
91
|
def establish_master_connection
|
|
94
|
-
establish_connection configuration.merge(
|
|
92
|
+
establish_connection configuration.merge("database" => "master")
|
|
95
93
|
end
|
|
96
|
-
|
|
97
94
|
end
|
|
98
95
|
|
|
99
96
|
module DatabaseTasksSQLServer
|
|
100
|
-
|
|
101
97
|
extend ActiveSupport::Concern
|
|
102
98
|
|
|
103
99
|
module ClassMethods
|
|
104
|
-
|
|
105
100
|
LOCAL_IPADDR = [
|
|
106
|
-
IPAddr.new(
|
|
107
|
-
IPAddr.new(
|
|
108
|
-
IPAddr.new(
|
|
101
|
+
IPAddr.new("192.168.0.0/16"),
|
|
102
|
+
IPAddr.new("10.0.0.0/8"),
|
|
103
|
+
IPAddr.new("172.16.0.0/12")
|
|
109
104
|
]
|
|
110
105
|
|
|
111
106
|
private
|
|
@@ -115,21 +110,20 @@ module ActiveRecord
|
|
|
115
110
|
end
|
|
116
111
|
|
|
117
112
|
def configuration_host_ip(configuration)
|
|
118
|
-
return nil unless configuration[
|
|
119
|
-
|
|
113
|
+
return nil unless configuration["host"]
|
|
114
|
+
|
|
115
|
+
Socket::getaddrinfo(configuration["host"], "echo", Socket::AF_INET)[0][3]
|
|
120
116
|
end
|
|
121
117
|
|
|
122
118
|
def local_ipaddr?(host_ip)
|
|
123
119
|
return false unless host_ip
|
|
120
|
+
|
|
124
121
|
LOCAL_IPADDR.any? { |ip| ip.include?(host_ip) }
|
|
125
122
|
end
|
|
126
|
-
|
|
127
123
|
end
|
|
128
|
-
|
|
129
124
|
end
|
|
130
125
|
|
|
131
126
|
DatabaseTasks.register_task %r{sqlserver}, SQLServerDatabaseTasks
|
|
132
127
|
DatabaseTasks.send :include, DatabaseTasksSQLServer
|
|
133
|
-
|
|
134
128
|
end
|
|
135
129
|
end
|