activerecord-sqlserver-adapter 6.0.2 → 6.1.2.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.md +33 -56
- data/README.md +28 -11
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +1 -1
- data/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +5 -10
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +9 -2
- data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +0 -4
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +27 -15
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +4 -3
- data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +22 -1
- data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +9 -3
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +8 -6
- data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +36 -7
- data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +0 -1
- data/lib/active_record/connection_adapters/sqlserver/transaction.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/date.rb +2 -1
- data/lib/active_record/connection_adapters/sqlserver/utils.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +100 -70
- data/lib/active_record/connection_adapters/sqlserver_column.rb +75 -19
- data/lib/active_record/sqlserver_base.rb +9 -15
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +17 -14
- data/lib/arel/visitors/sqlserver.rb +74 -29
- data/test/cases/adapter_test_sqlserver.rb +27 -17
- data/test/cases/change_column_collation_test_sqlserver.rb +33 -0
- data/test/cases/coerced_tests.rb +544 -77
- data/test/cases/column_test_sqlserver.rb +4 -0
- data/test/cases/disconnected_test_sqlserver.rb +39 -0
- data/test/cases/execute_procedure_test_sqlserver.rb +9 -0
- data/test/cases/fetch_test_sqlserver.rb +18 -0
- data/test/cases/in_clause_test_sqlserver.rb +27 -0
- data/test/cases/migration_test_sqlserver.rb +7 -0
- data/test/cases/order_test_sqlserver.rb +7 -0
- data/test/cases/primary_keys_test_sqlserver.rb +103 -0
- data/test/cases/rake_test_sqlserver.rb +38 -2
- data/test/cases/schema_dumper_test_sqlserver.rb +9 -0
- data/test/migrations/create_clients_and_change_column_collation.rb +19 -0
- data/test/models/sqlserver/composite_pk.rb +9 -0
- data/test/models/sqlserver/sst_string_collation.rb +3 -0
- data/test/schema/sqlserver_specific_schema.rb +25 -0
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic.dump +0 -0
- data/test/support/marshal_compatibility_fixtures/SQLServer/rails_6_0_topic_associations.dump +0 -0
- data/test/support/sql_counter_sqlserver.rb +14 -12
- metadata +23 -8
- data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +0 -28
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
|
5
5
|
module SQLServer
|
|
6
|
-
class SchemaCreation <
|
|
6
|
+
class SchemaCreation < SchemaCreation
|
|
7
7
|
private
|
|
8
8
|
|
|
9
|
+
def supports_index_using?
|
|
10
|
+
false
|
|
11
|
+
end
|
|
12
|
+
|
|
9
13
|
def visit_TableDefinition(o)
|
|
10
14
|
if_not_exists = o.if_not_exists
|
|
11
15
|
|
|
@@ -29,11 +33,28 @@ module ActiveRecord
|
|
|
29
33
|
sql
|
|
30
34
|
end
|
|
31
35
|
|
|
36
|
+
def visit_CreateIndexDefinition(o)
|
|
37
|
+
if_not_exists = o.if_not_exists
|
|
38
|
+
|
|
39
|
+
o.if_not_exists = false
|
|
40
|
+
|
|
41
|
+
sql = super
|
|
42
|
+
|
|
43
|
+
if if_not_exists
|
|
44
|
+
sql = "IF NOT EXISTS (SELECT name FROM sysindexes WHERE name = '#{o.index.name}') #{sql}"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
sql
|
|
48
|
+
end
|
|
49
|
+
|
|
32
50
|
def add_column_options!(sql, options)
|
|
33
51
|
sql << " DEFAULT #{quote_default_expression(options[:default], options[:column])}" if options_include_default?(options)
|
|
34
52
|
if options[:null] == false
|
|
35
53
|
sql << " NOT NULL"
|
|
36
54
|
end
|
|
55
|
+
if options[:collation].present?
|
|
56
|
+
sql << " COLLATE #{options[:collation]}"
|
|
57
|
+
end
|
|
37
58
|
if options[:is_identity] == true
|
|
38
59
|
sql << " IDENTITY(1,1)"
|
|
39
60
|
end
|
|
@@ -15,7 +15,7 @@ module ActiveRecord
|
|
|
15
15
|
private
|
|
16
16
|
|
|
17
17
|
def explicit_primary_key_default?(column)
|
|
18
|
-
column.
|
|
18
|
+
column.type == :integer && !column.is_identity?
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def schema_limit(column)
|
|
@@ -27,11 +27,17 @@ module ActiveRecord
|
|
|
27
27
|
def schema_collation(column)
|
|
28
28
|
return unless column.collation
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
# use inspect to ensure collation is dumped as string. Without this it's dumped as
|
|
31
|
+
# a constant ('collation: SQL_Latin1_General_CP1_CI_AS')
|
|
32
|
+
collation = column.collation.inspect
|
|
33
|
+
# use inspect to ensure string comparison
|
|
34
|
+
default_collation = @connection.collation.inspect
|
|
35
|
+
|
|
36
|
+
collation if collation != default_collation
|
|
31
37
|
end
|
|
32
38
|
|
|
33
39
|
def default_primary_key?(column)
|
|
34
|
-
super && column.
|
|
40
|
+
super && column.is_identity?
|
|
35
41
|
end
|
|
36
42
|
end
|
|
37
43
|
end
|
|
@@ -27,7 +27,7 @@ module ActiveRecord
|
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
if options[:if_exists] && @version_year < 2016
|
|
30
|
-
execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = #{quote(table_name)}) DROP TABLE #{quote_table_name(table_name)}"
|
|
30
|
+
execute "IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = #{quote(table_name)}) DROP TABLE #{quote_table_name(table_name)}", "SCHEMA"
|
|
31
31
|
else
|
|
32
32
|
super
|
|
33
33
|
end
|
|
@@ -51,7 +51,7 @@ module ActiveRecord
|
|
|
51
51
|
index[:index_keys].split(",").each do |column|
|
|
52
52
|
column.strip!
|
|
53
53
|
|
|
54
|
-
if column.
|
|
54
|
+
if column.end_with?("(-)")
|
|
55
55
|
column.gsub! "(-)", ""
|
|
56
56
|
orders[column] = :desc
|
|
57
57
|
end
|
|
@@ -84,7 +84,7 @@ module ActiveRecord
|
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
def new_column(name, default, sql_type_metadata, null, default_function = nil, collation = nil, comment = nil, sqlserver_options = {})
|
|
87
|
-
|
|
87
|
+
SQLServer::Column.new(
|
|
88
88
|
name,
|
|
89
89
|
default,
|
|
90
90
|
sql_type_metadata,
|
|
@@ -130,8 +130,9 @@ module ActiveRecord
|
|
|
130
130
|
rename_table_indexes(table_name, new_name)
|
|
131
131
|
end
|
|
132
132
|
|
|
133
|
-
def remove_column(table_name, column_name, type = nil, options
|
|
133
|
+
def remove_column(table_name, column_name, type = nil, **options)
|
|
134
134
|
raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_name.is_a? Array
|
|
135
|
+
return if options[:if_exists] == true && !column_exists?(table_name, column_name)
|
|
135
136
|
|
|
136
137
|
remove_check_constraints(table_name, column_name)
|
|
137
138
|
remove_default_constraint(table_name, column_name)
|
|
@@ -156,6 +157,7 @@ module ActiveRecord
|
|
|
156
157
|
end
|
|
157
158
|
sql_commands << "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_expression(options[:default], column_object)} WHERE #{quote_column_name(column_name)} IS NULL" if !options[:null].nil? && options[:null] == false && !options[:default].nil?
|
|
158
159
|
alter_command = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, limit: options[:limit], precision: options[:precision], scale: options[:scale])}"
|
|
160
|
+
alter_command += " COLLATE #{options[:collation]}" if options[:collation].present?
|
|
159
161
|
alter_command += " NOT NULL" if !options[:null].nil? && options[:null] == false
|
|
160
162
|
sql_commands << alter_command
|
|
161
163
|
if without_constraints
|
|
@@ -190,7 +192,7 @@ module ActiveRecord
|
|
|
190
192
|
end
|
|
191
193
|
|
|
192
194
|
def rename_index(table_name, old_name, new_name)
|
|
193
|
-
raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{
|
|
195
|
+
raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{index_name_length} characters" if new_name.length > index_name_length
|
|
194
196
|
|
|
195
197
|
identifier = SQLServer::Utils.extract_identifiers("#{table_name}.#{old_name}")
|
|
196
198
|
execute_procedure :sp_rename, identifier.quoted, new_name, "INDEX"
|
|
@@ -330,7 +332,7 @@ module ActiveRecord
|
|
|
330
332
|
def initialize_native_database_types
|
|
331
333
|
{
|
|
332
334
|
primary_key: "bigint NOT NULL IDENTITY(1,1) PRIMARY KEY",
|
|
333
|
-
primary_key_nonclustered: "
|
|
335
|
+
primary_key_nonclustered: "bigint NOT NULL IDENTITY(1,1) PRIMARY KEY NONCLUSTERED",
|
|
334
336
|
integer: { name: "int", limit: 4 },
|
|
335
337
|
bigint: { name: "bigint" },
|
|
336
338
|
boolean: { name: "bit" },
|
|
@@ -3,16 +3,45 @@
|
|
|
3
3
|
module ActiveRecord
|
|
4
4
|
module ConnectionAdapters
|
|
5
5
|
module SQLServer
|
|
6
|
-
class
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
class TypeMetadata < DelegateClass(SqlTypeMetadata)
|
|
7
|
+
undef to_yaml if method_defined?(:to_yaml)
|
|
8
|
+
|
|
9
|
+
include Deduplicable
|
|
10
|
+
|
|
11
|
+
attr_reader :is_identity, :is_primary, :table_name, :ordinal_position
|
|
12
|
+
|
|
13
|
+
def initialize(type_metadata, is_identity: nil, is_primary: nil, table_name: nil, ordinal_position: nil)
|
|
14
|
+
super(type_metadata)
|
|
15
|
+
@is_identity = is_identity
|
|
16
|
+
@is_primary = is_primary
|
|
17
|
+
@table_name = table_name
|
|
18
|
+
@ordinal_position = ordinal_position
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def ==(other)
|
|
22
|
+
other.is_a?(TypeMetadata) &&
|
|
23
|
+
__getobj__ == other.__getobj__ &&
|
|
24
|
+
is_identity == other.is_identity &&
|
|
25
|
+
is_primary == other.is_primary &&
|
|
26
|
+
table_name == other.table_name &&
|
|
27
|
+
ordinal_position == other.ordinal_position
|
|
28
|
+
end
|
|
29
|
+
alias eql? ==
|
|
30
|
+
|
|
31
|
+
def hash
|
|
32
|
+
TypeMetadata.hash ^
|
|
33
|
+
__getobj__.hash ^
|
|
34
|
+
is_identity.hash ^
|
|
35
|
+
is_primary.hash ^
|
|
36
|
+
table_name.hash ^
|
|
37
|
+
ordinal_position.hash
|
|
10
38
|
end
|
|
11
39
|
|
|
12
|
-
|
|
40
|
+
private
|
|
13
41
|
|
|
14
|
-
def
|
|
15
|
-
|
|
42
|
+
def deduplicated
|
|
43
|
+
__setobj__(__getobj__.deduplicate)
|
|
44
|
+
super
|
|
16
45
|
end
|
|
17
46
|
end
|
|
18
47
|
end
|
|
@@ -31,9 +31,9 @@ module ActiveRecord
|
|
|
31
31
|
module SQLServerRealTransaction
|
|
32
32
|
attr_reader :starting_isolation_level
|
|
33
33
|
|
|
34
|
-
def initialize(connection,
|
|
34
|
+
def initialize(connection, isolation: nil, joinable: true, run_commit_callbacks: false)
|
|
35
35
|
@connection = connection
|
|
36
|
-
@starting_isolation_level = current_isolation_level if
|
|
36
|
+
@starting_isolation_level = current_isolation_level if isolation
|
|
37
37
|
super
|
|
38
38
|
end
|
|
39
39
|
|
|
@@ -10,7 +10,6 @@ require "active_record/connection_adapters/sqlserver/core_ext/explain"
|
|
|
10
10
|
require "active_record/connection_adapters/sqlserver/core_ext/explain_subscriber"
|
|
11
11
|
require "active_record/connection_adapters/sqlserver/core_ext/attribute_methods"
|
|
12
12
|
require "active_record/connection_adapters/sqlserver/core_ext/finder_methods"
|
|
13
|
-
require "active_record/connection_adapters/sqlserver/core_ext/query_methods"
|
|
14
13
|
require "active_record/connection_adapters/sqlserver/core_ext/preloader"
|
|
15
14
|
require "active_record/connection_adapters/sqlserver/version"
|
|
16
15
|
require "active_record/connection_adapters/sqlserver/type"
|
|
@@ -59,13 +58,89 @@ module ActiveRecord
|
|
|
59
58
|
self.use_output_inserted = true
|
|
60
59
|
self.exclude_output_inserted_table_names = Concurrent::Map.new { false }
|
|
61
60
|
|
|
62
|
-
|
|
61
|
+
class << self
|
|
62
|
+
def new_client(config)
|
|
63
|
+
case config[:mode]
|
|
64
|
+
when :dblib
|
|
65
|
+
require "tiny_tds"
|
|
66
|
+
dblib_connect(config)
|
|
67
|
+
else
|
|
68
|
+
raise ArgumentError, "Unknown connection mode in #{config.inspect}."
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def dblib_connect(config)
|
|
73
|
+
TinyTds::Client.new(
|
|
74
|
+
dataserver: config[:dataserver],
|
|
75
|
+
host: config[:host],
|
|
76
|
+
port: config[:port],
|
|
77
|
+
username: config[:username],
|
|
78
|
+
password: config[:password],
|
|
79
|
+
database: config[:database],
|
|
80
|
+
tds_version: config[:tds_version] || "7.3",
|
|
81
|
+
appname: config_appname(config),
|
|
82
|
+
login_timeout: config_login_timeout(config),
|
|
83
|
+
timeout: config_timeout(config),
|
|
84
|
+
encoding: config_encoding(config),
|
|
85
|
+
azure: config[:azure],
|
|
86
|
+
contained: config[:contained]
|
|
87
|
+
).tap do |client|
|
|
88
|
+
if config[:azure]
|
|
89
|
+
client.execute("SET ANSI_NULLS ON").do
|
|
90
|
+
client.execute("SET ANSI_NULL_DFLT_ON ON").do
|
|
91
|
+
client.execute("SET ANSI_PADDING ON").do
|
|
92
|
+
client.execute("SET ANSI_WARNINGS ON").do
|
|
93
|
+
else
|
|
94
|
+
client.execute("SET ANSI_DEFAULTS ON").do
|
|
95
|
+
end
|
|
96
|
+
client.execute("SET QUOTED_IDENTIFIER ON").do
|
|
97
|
+
client.execute("SET CURSOR_CLOSE_ON_COMMIT OFF").do
|
|
98
|
+
client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
|
|
99
|
+
client.execute("SET TEXTSIZE 2147483647").do
|
|
100
|
+
client.execute("SET CONCAT_NULL_YIELDS_NULL ON").do
|
|
101
|
+
end
|
|
102
|
+
rescue TinyTds::Error => e
|
|
103
|
+
raise ActiveRecord::NoDatabaseError if e.message.match(/database .* does not exist/i)
|
|
104
|
+
raise e
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def config_appname(config)
|
|
108
|
+
if self.instance_methods.include?(:configure_application_name)
|
|
109
|
+
ActiveSupport::Deprecation.warn <<~MSG.squish
|
|
110
|
+
Configuring the application name used by TinyTDS by overriding the
|
|
111
|
+
`ActiveRecord::ConnectionAdapters::SQLServerAdapter#configure_application_name`
|
|
112
|
+
instance method is no longer supported. The application name should configured
|
|
113
|
+
using the `appname` setting in the `database.yml` file instead. Consult the
|
|
114
|
+
README for further information."
|
|
115
|
+
MSG
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
config[:appname] || rails_application_name
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def rails_application_name
|
|
122
|
+
return nil if Rails.application.nil?
|
|
123
|
+
|
|
124
|
+
Rails.application.class.name.split("::").first
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def config_login_timeout(config)
|
|
128
|
+
config[:login_timeout].present? ? config[:login_timeout].to_i : nil
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def config_timeout(config)
|
|
132
|
+
config[:timeout].present? ? config[:timeout].to_i / 1000 : nil
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def config_encoding(config)
|
|
136
|
+
config[:encoding].present? ? config[:encoding] : nil
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def initialize(connection, logger, _connection_options, config)
|
|
63
141
|
super(connection, logger, config)
|
|
64
|
-
# Our Responsibility
|
|
65
142
|
@connection_options = config
|
|
66
|
-
|
|
67
|
-
initialize_dateformatter
|
|
68
|
-
use_database
|
|
143
|
+
configure_connection
|
|
69
144
|
end
|
|
70
145
|
|
|
71
146
|
# === Abstract Adapter ========================================== #
|
|
@@ -226,6 +301,14 @@ module ActiveRecord
|
|
|
226
301
|
do_execute "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
|
|
227
302
|
end
|
|
228
303
|
|
|
304
|
+
def configure_connection
|
|
305
|
+
@spid = _raw_select("SELECT @@SPID", fetch: :rows).first.first
|
|
306
|
+
@version_year = version_year
|
|
307
|
+
|
|
308
|
+
initialize_dateformatter
|
|
309
|
+
use_database
|
|
310
|
+
end
|
|
311
|
+
|
|
229
312
|
# === Abstract Adapter (Misc Support) =========================== #
|
|
230
313
|
|
|
231
314
|
def tables_with_referential_integrity
|
|
@@ -375,7 +458,9 @@ module ActiveRecord
|
|
|
375
458
|
|
|
376
459
|
def translate_exception(e, message:, sql:, binds:)
|
|
377
460
|
case message
|
|
378
|
-
when /(
|
|
461
|
+
when /(SQL Server client is not connected)|(failed to execute statement)/i
|
|
462
|
+
ConnectionNotEstablished.new(message)
|
|
463
|
+
when /(cannot insert duplicate key .* with unique index) | (violation of (unique|primary) key constraint)/i
|
|
379
464
|
RecordNotUnique.new(message, sql: sql, binds: binds)
|
|
380
465
|
when /(conflicted with the foreign key constraint) | (The DELETE statement conflicted with the REFERENCE constraint)/i
|
|
381
466
|
InvalidForeignKey.new(message, sql: sql, binds: binds)
|
|
@@ -408,78 +493,16 @@ module ActiveRecord
|
|
|
408
493
|
|
|
409
494
|
# === SQLServer Specific (Connection Management) ================ #
|
|
410
495
|
|
|
411
|
-
def connect
|
|
412
|
-
config = @connection_options
|
|
413
|
-
@connection = case config[:mode]
|
|
414
|
-
when :dblib
|
|
415
|
-
dblib_connect(config)
|
|
416
|
-
end
|
|
417
|
-
@spid = _raw_select("SELECT @@SPID", fetch: :rows).first.first
|
|
418
|
-
@version_year = version_year
|
|
419
|
-
configure_connection
|
|
420
|
-
end
|
|
421
|
-
|
|
422
496
|
def connection_errors
|
|
423
497
|
@connection_errors ||= [].tap do |errors|
|
|
424
498
|
errors << TinyTds::Error if defined?(TinyTds::Error)
|
|
425
499
|
end
|
|
426
500
|
end
|
|
427
501
|
|
|
428
|
-
def dblib_connect(config)
|
|
429
|
-
TinyTds::Client.new(
|
|
430
|
-
dataserver: config[:dataserver],
|
|
431
|
-
host: config[:host],
|
|
432
|
-
port: config[:port],
|
|
433
|
-
username: config[:username],
|
|
434
|
-
password: config[:password],
|
|
435
|
-
database: config[:database],
|
|
436
|
-
tds_version: config[:tds_version] || "7.3",
|
|
437
|
-
appname: config_appname(config),
|
|
438
|
-
login_timeout: config_login_timeout(config),
|
|
439
|
-
timeout: config_timeout(config),
|
|
440
|
-
encoding: config_encoding(config),
|
|
441
|
-
azure: config[:azure],
|
|
442
|
-
contained: config[:contained]
|
|
443
|
-
).tap do |client|
|
|
444
|
-
if config[:azure]
|
|
445
|
-
client.execute("SET ANSI_NULLS ON").do
|
|
446
|
-
client.execute("SET ANSI_NULL_DFLT_ON ON").do
|
|
447
|
-
client.execute("SET ANSI_PADDING ON").do
|
|
448
|
-
client.execute("SET ANSI_WARNINGS ON").do
|
|
449
|
-
else
|
|
450
|
-
client.execute("SET ANSI_DEFAULTS ON").do
|
|
451
|
-
end
|
|
452
|
-
client.execute("SET QUOTED_IDENTIFIER ON").do
|
|
453
|
-
client.execute("SET CURSOR_CLOSE_ON_COMMIT OFF").do
|
|
454
|
-
client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
|
|
455
|
-
client.execute("SET TEXTSIZE 2147483647").do
|
|
456
|
-
client.execute("SET CONCAT_NULL_YIELDS_NULL ON").do
|
|
457
|
-
end
|
|
458
|
-
end
|
|
459
|
-
|
|
460
|
-
def config_appname(config)
|
|
461
|
-
config[:appname] || configure_application_name || Rails.application.class.name.split("::").first rescue nil
|
|
462
|
-
end
|
|
463
|
-
|
|
464
|
-
def config_login_timeout(config)
|
|
465
|
-
config[:login_timeout].present? ? config[:login_timeout].to_i : nil
|
|
466
|
-
end
|
|
467
|
-
|
|
468
|
-
def config_timeout(config)
|
|
469
|
-
config[:timeout].present? ? config[:timeout].to_i / 1000 : nil
|
|
470
|
-
end
|
|
471
|
-
|
|
472
|
-
def config_encoding(config)
|
|
473
|
-
config[:encoding].present? ? config[:encoding] : nil
|
|
474
|
-
end
|
|
475
|
-
|
|
476
|
-
def configure_connection; end
|
|
477
|
-
|
|
478
|
-
def configure_application_name; end
|
|
479
|
-
|
|
480
502
|
def initialize_dateformatter
|
|
481
503
|
@database_dateformat = user_options_dateformat
|
|
482
504
|
a, b, c = @database_dateformat.each_char.to_a
|
|
505
|
+
|
|
483
506
|
[a, b, c].each { |f| f.upcase! if f == "y" }
|
|
484
507
|
dateformat = "%#{a}-%#{b}-%#{c}"
|
|
485
508
|
::Date::DATE_FORMATS[:_sqlserver_dateformat] = dateformat
|
|
@@ -502,6 +525,13 @@ module ActiveRecord
|
|
|
502
525
|
def sqlserver_version
|
|
503
526
|
@sqlserver_version ||= _raw_select("SELECT @@version", fetch: :rows).first.first.to_s
|
|
504
527
|
end
|
|
528
|
+
|
|
529
|
+
private
|
|
530
|
+
|
|
531
|
+
def connect
|
|
532
|
+
@connection = self.class.new_client(@connection_options)
|
|
533
|
+
configure_connection
|
|
534
|
+
end
|
|
505
535
|
end
|
|
506
536
|
end
|
|
507
537
|
end
|