activerecord-sqlserver-adapter 5.2.1 → 6.0.0.rc1
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/.editorconfig +9 -0
- data/.github/issue_template.md +23 -0
- data/.travis.yml +6 -8
- data/CHANGELOG.md +22 -32
- data/{Dockerfile → Dockerfile.ci} +1 -1
- data/Gemfile +42 -41
- data/README.md +9 -30
- data/RUNNING_UNIT_TESTS.md +3 -0
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +25 -14
- data/appveyor.yml +24 -17
- data/docker-compose.ci.yml +7 -5
- data/guides/RELEASING.md +11 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/active_record.rb +2 -0
- 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 +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain_subscriber.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +6 -4
- data/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +36 -0
- data/lib/active_record/connection_adapters/sqlserver/core_ext/query_methods.rb +4 -1
- data/lib/active_record/connection_adapters/sqlserver/database_limits.rb +9 -0
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +55 -14
- data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/errors.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +38 -0
- data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +16 -3
- data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +93 -70
- data/lib/active_record/connection_adapters/sqlserver/showplan.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/showplan/printer_table.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/showplan/printer_xml.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +42 -40
- data/lib/active_record/connection_adapters/sqlserver/transaction.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +5 -2
- data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/char.rb +5 -2
- data/lib/active_record/connection_adapters/sqlserver/type/data.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/type/date.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +7 -6
- data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +5 -2
- data/lib/active_record/connection_adapters/sqlserver/type/float.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/json.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/type/money.rb +4 -2
- data/lib/active_record/connection_adapters/sqlserver/type/real.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +4 -2
- data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/string.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/type/text.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/time.rb +5 -4
- data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +5 -2
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_string.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +6 -3
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +4 -2
- data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +6 -3
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +4 -2
- data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +6 -3
- data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +4 -2
- data/lib/active_record/connection_adapters/sqlserver/utils.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver/version.rb +2 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +44 -10
- data/lib/active_record/connection_adapters/sqlserver_column.rb +9 -3
- data/lib/active_record/sqlserver_base.rb +8 -0
- data/lib/active_record/tasks/sqlserver_database_tasks.rb +2 -0
- data/lib/activerecord-sqlserver-adapter.rb +2 -0
- data/lib/arel/visitors/sqlserver.rb +40 -10
- data/lib/arel_sqlserver.rb +2 -0
- data/test/appveyor/dbsetup.ps1 +4 -4
- data/test/cases/adapter_test_sqlserver.rb +65 -1
- data/test/cases/change_column_null_test_sqlserver.rb +2 -0
- data/test/cases/coerced_tests.rb +644 -187
- data/test/cases/column_test_sqlserver.rb +2 -1
- data/test/cases/connection_test_sqlserver.rb +2 -0
- data/test/cases/execute_procedure_test_sqlserver.rb +2 -0
- data/test/cases/fetch_test_sqlserver.rb +2 -0
- data/test/cases/fully_qualified_identifier_test_sqlserver.rb +4 -2
- data/test/cases/helper_sqlserver.rb +2 -0
- data/test/cases/in_clause_test_sqlserver.rb +36 -0
- data/test/cases/index_test_sqlserver.rb +2 -0
- data/test/cases/json_test_sqlserver.rb +2 -0
- data/test/cases/migration_test_sqlserver.rb +4 -2
- data/test/cases/order_test_sqlserver.rb +2 -0
- data/test/cases/pessimistic_locking_test_sqlserver.rb +2 -0
- data/test/cases/rake_test_sqlserver.rb +2 -0
- data/test/cases/schema_dumper_test_sqlserver.rb +3 -1
- data/test/cases/schema_test_sqlserver.rb +2 -0
- data/test/cases/scratchpad_test_sqlserver.rb +2 -0
- data/test/cases/showplan_test_sqlserver.rb +4 -2
- data/test/cases/specific_schema_test_sqlserver.rb +2 -0
- data/test/cases/transaction_test_sqlserver.rb +2 -1
- data/test/cases/trigger_test_sqlserver.rb +2 -1
- data/test/cases/utils_test_sqlserver.rb +2 -0
- data/test/cases/uuid_test_sqlserver.rb +2 -1
- data/test/debug.rb +2 -0
- data/test/migrations/create_clients_and_change_column_null.rb +2 -0
- data/test/migrations/transaction_table/1_table_will_never_be_created.rb +2 -0
- data/test/models/sqlserver/booking.rb +2 -0
- data/test/models/sqlserver/customers_view.rb +2 -0
- data/test/models/sqlserver/datatype.rb +2 -0
- data/test/models/sqlserver/datatype_migration.rb +2 -0
- data/test/models/sqlserver/dollar_table_name.rb +2 -0
- data/test/models/sqlserver/edge_schema.rb +2 -0
- data/test/models/sqlserver/fk_has_fk.rb +2 -0
- data/test/models/sqlserver/fk_has_pk.rb +2 -0
- data/test/models/sqlserver/natural_pk_data.rb +2 -0
- data/test/models/sqlserver/natural_pk_int_data.rb +2 -0
- data/test/models/sqlserver/no_pk_data.rb +2 -0
- data/test/models/sqlserver/object_default.rb +2 -0
- data/test/models/sqlserver/quoted_table.rb +2 -0
- data/test/models/sqlserver/quoted_view_1.rb +2 -0
- data/test/models/sqlserver/quoted_view_2.rb +2 -0
- data/test/models/sqlserver/sst_memory.rb +2 -0
- data/test/models/sqlserver/string_default.rb +2 -0
- data/test/models/sqlserver/string_defaults_big_view.rb +2 -0
- data/test/models/sqlserver/string_defaults_view.rb +2 -0
- data/test/models/sqlserver/tinyint_pk.rb +2 -0
- data/test/models/sqlserver/trigger.rb +2 -0
- data/test/models/sqlserver/trigger_history.rb +2 -0
- data/test/models/sqlserver/upper.rb +2 -0
- data/test/models/sqlserver/uppered.rb +2 -0
- data/test/models/sqlserver/uuid.rb +2 -0
- data/test/schema/sqlserver_specific_schema.rb +2 -0
- data/test/support/coerceable_test_sqlserver.rb +14 -5
- data/test/support/connection_reflection.rb +2 -0
- data/test/support/core_ext/query_cache.rb +3 -0
- data/test/support/load_schema_sqlserver.rb +2 -0
- data/test/support/minitest_sqlserver.rb +2 -0
- data/test/support/paths_sqlserver.rb +2 -0
- data/test/support/rake_helpers.rb +1 -0
- data/test/support/sql_counter_sqlserver.rb +3 -0
- data/test/support/test_in_memory_oltp.rb +2 -0
- metadata +18 -9
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveRecord
|
|
2
4
|
module ConnectionAdapters
|
|
3
5
|
module SQLServer
|
|
@@ -7,13 +9,13 @@ module ActiveRecord
|
|
|
7
9
|
@native_database_types ||= initialize_native_database_types.freeze
|
|
8
10
|
end
|
|
9
11
|
|
|
10
|
-
def create_table(table_name,
|
|
12
|
+
def create_table(table_name, **options)
|
|
11
13
|
res = super
|
|
12
14
|
clear_cache!
|
|
13
15
|
res
|
|
14
16
|
end
|
|
15
17
|
|
|
16
|
-
def drop_table(table_name, options
|
|
18
|
+
def drop_table(table_name, **options)
|
|
17
19
|
# Mimic CASCADE option as best we can.
|
|
18
20
|
if options[:force] == :cascade
|
|
19
21
|
execute_procedure(:sp_fkeys, pktable_name: table_name).each do |fkdata|
|
|
@@ -66,14 +68,13 @@ module ActiveRecord
|
|
|
66
68
|
def columns(table_name)
|
|
67
69
|
return [] if table_name.blank?
|
|
68
70
|
column_definitions(table_name).map do |ci|
|
|
69
|
-
sqlserver_options = ci.slice :ordinal_position, :is_primary, :is_identity
|
|
71
|
+
sqlserver_options = ci.slice :ordinal_position, :is_primary, :is_identity, :table_name
|
|
70
72
|
sql_type_metadata = fetch_type_metadata ci[:type], sqlserver_options
|
|
71
73
|
new_column(
|
|
72
74
|
ci[:name],
|
|
73
75
|
ci[:default_value],
|
|
74
76
|
sql_type_metadata,
|
|
75
77
|
ci[:null],
|
|
76
|
-
ci[:table_name],
|
|
77
78
|
ci[:default_function],
|
|
78
79
|
ci[:collation],
|
|
79
80
|
nil,
|
|
@@ -82,16 +83,16 @@ module ActiveRecord
|
|
|
82
83
|
end
|
|
83
84
|
end
|
|
84
85
|
|
|
85
|
-
def new_column(name, default, sql_type_metadata, null,
|
|
86
|
+
def new_column(name, default, sql_type_metadata, null, default_function = nil, collation = nil, comment = nil, sqlserver_options = {})
|
|
86
87
|
SQLServerColumn.new(
|
|
87
88
|
name,
|
|
88
89
|
default,
|
|
89
90
|
sql_type_metadata,
|
|
90
|
-
null,
|
|
91
|
+
null,
|
|
91
92
|
default_function,
|
|
92
|
-
collation,
|
|
93
|
-
comment,
|
|
94
|
-
sqlserver_options
|
|
93
|
+
collation: collation,
|
|
94
|
+
comment: comment,
|
|
95
|
+
**sqlserver_options
|
|
95
96
|
)
|
|
96
97
|
end
|
|
97
98
|
|
|
@@ -153,8 +154,9 @@ module ActiveRecord
|
|
|
153
154
|
remove_indexes(table_name, column_name)
|
|
154
155
|
end
|
|
155
156
|
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?
|
|
156
|
-
|
|
157
|
-
|
|
157
|
+
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])}"
|
|
158
|
+
alter_command += ' NOT NULL' if !options[:null].nil? && options[:null] == false
|
|
159
|
+
sql_commands << alter_command
|
|
158
160
|
if without_constraints
|
|
159
161
|
default = quote_default_expression(default, column_object || column_for(table_name, column_name))
|
|
160
162
|
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name, column_name)} DEFAULT #{default} FOR #{quote_column_name(column_name)}"
|
|
@@ -237,7 +239,7 @@ module ActiveRecord
|
|
|
237
239
|
if (0..7) === precision
|
|
238
240
|
column_type_sql << "(#{precision})"
|
|
239
241
|
else
|
|
240
|
-
raise(ActiveRecordError, "The
|
|
242
|
+
raise(ActiveRecordError, "The datetime2 type has precision of #{precision}. The allowed range of precision is from 0 to 7")
|
|
241
243
|
end
|
|
242
244
|
end
|
|
243
245
|
column_type_sql
|
|
@@ -268,7 +270,7 @@ module ActiveRecord
|
|
|
268
270
|
do_execute("UPDATE #{table_id} SET #{column_id}=#{quote(default)} WHERE #{column_id} IS NULL")
|
|
269
271
|
end
|
|
270
272
|
sql = "ALTER TABLE #{table_id} ALTER COLUMN #{column_id} #{type_to_sql column.type, limit: column.limit, precision: column.precision, scale: column.scale}"
|
|
271
|
-
sql
|
|
273
|
+
sql += ' NOT NULL' if !allow_null.nil? && allow_null == false
|
|
272
274
|
do_execute sql
|
|
273
275
|
end
|
|
274
276
|
|
|
@@ -282,12 +284,12 @@ module ActiveRecord
|
|
|
282
284
|
scope = quoted_scope name, type: type
|
|
283
285
|
table_name = lowercase_schema_reflection_sql 'TABLE_NAME'
|
|
284
286
|
sql = "SELECT #{table_name}"
|
|
285
|
-
sql
|
|
286
|
-
sql
|
|
287
|
-
sql
|
|
288
|
-
sql
|
|
289
|
-
sql
|
|
290
|
-
sql
|
|
287
|
+
sql += ' FROM INFORMATION_SCHEMA.TABLES WITH (NOLOCK)'
|
|
288
|
+
sql += ' WHERE TABLE_CATALOG = DB_NAME()'
|
|
289
|
+
sql += " AND TABLE_SCHEMA = #{quote(scope[:schema])}"
|
|
290
|
+
sql += " AND TABLE_NAME = #{quote(scope[:name])}" if scope[:name]
|
|
291
|
+
sql += " AND TABLE_TYPE = #{quote(scope[:type])}" if scope[:type]
|
|
292
|
+
sql += " ORDER BY #{table_name}"
|
|
291
293
|
sql
|
|
292
294
|
end
|
|
293
295
|
|
|
@@ -343,55 +345,9 @@ module ActiveRecord
|
|
|
343
345
|
database = identifier.fully_qualified_database_quoted
|
|
344
346
|
view_exists = view_exists?(table_name)
|
|
345
347
|
view_tblnm = view_table_name(table_name) if view_exists
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
#{lowercase_schema_reflection_sql('columns.COLUMN_NAME')} AS name,
|
|
350
|
-
columns.DATA_TYPE AS type,
|
|
351
|
-
columns.COLUMN_DEFAULT AS default_value,
|
|
352
|
-
columns.NUMERIC_SCALE AS numeric_scale,
|
|
353
|
-
columns.NUMERIC_PRECISION AS numeric_precision,
|
|
354
|
-
columns.DATETIME_PRECISION AS datetime_precision,
|
|
355
|
-
columns.COLLATION_NAME AS [collation],
|
|
356
|
-
columns.ordinal_position,
|
|
357
|
-
CASE
|
|
358
|
-
WHEN columns.DATA_TYPE IN ('nchar','nvarchar','char','varchar') THEN columns.CHARACTER_MAXIMUM_LENGTH
|
|
359
|
-
ELSE COL_LENGTH('#{database}.'+columns.TABLE_SCHEMA+'.'+columns.TABLE_NAME, columns.COLUMN_NAME)
|
|
360
|
-
END AS [length],
|
|
361
|
-
CASE
|
|
362
|
-
WHEN columns.IS_NULLABLE = 'YES' THEN 1
|
|
363
|
-
ELSE NULL
|
|
364
|
-
END AS [is_nullable],
|
|
365
|
-
CASE
|
|
366
|
-
WHEN KCU.COLUMN_NAME IS NOT NULL AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY' THEN 1
|
|
367
|
-
ELSE NULL
|
|
368
|
-
END AS [is_primary],
|
|
369
|
-
c.is_identity AS [is_identity]
|
|
370
|
-
FROM #{database}.INFORMATION_SCHEMA.COLUMNS columns
|
|
371
|
-
LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
|
|
372
|
-
ON TC.TABLE_NAME = columns.TABLE_NAME
|
|
373
|
-
AND TC.TABLE_SCHEMA = columns.TABLE_SCHEMA
|
|
374
|
-
AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY'
|
|
375
|
-
LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
|
|
376
|
-
ON KCU.COLUMN_NAME = columns.COLUMN_NAME
|
|
377
|
-
AND KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
|
|
378
|
-
AND KCU.CONSTRAINT_CATALOG = TC.CONSTRAINT_CATALOG
|
|
379
|
-
AND KCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA
|
|
380
|
-
INNER JOIN #{database}.sys.schemas AS s
|
|
381
|
-
ON s.name = columns.TABLE_SCHEMA
|
|
382
|
-
AND s.schema_id = s.schema_id
|
|
383
|
-
INNER JOIN #{database}.sys.objects AS o
|
|
384
|
-
ON s.schema_id = o.schema_id
|
|
385
|
-
AND o.is_ms_shipped = 0
|
|
386
|
-
AND o.type IN ('U', 'V')
|
|
387
|
-
AND o.name = columns.TABLE_NAME
|
|
388
|
-
INNER JOIN #{database}.sys.columns AS c
|
|
389
|
-
ON o.object_id = c.object_id
|
|
390
|
-
AND c.name = columns.COLUMN_NAME
|
|
391
|
-
WHERE columns.TABLE_NAME = #{prepared_statements ? '@0' : quote(identifier.object)}
|
|
392
|
-
AND columns.TABLE_SCHEMA = #{identifier.schema.blank? ? 'schema_name()' : (prepared_statements ? '@1' : quote(identifier.schema))}
|
|
393
|
-
ORDER BY columns.ordinal_position
|
|
394
|
-
}.gsub(/[ \t\r\n]+/, ' ').strip
|
|
348
|
+
|
|
349
|
+
sql = column_definitions_sql(database, identifier)
|
|
350
|
+
|
|
395
351
|
binds = []
|
|
396
352
|
nv128 = SQLServer::Type::UnicodeVarchar.new limit: 128
|
|
397
353
|
binds << Relation::QueryAttribute.new('TABLE_NAME', identifier.object, nv128)
|
|
@@ -458,6 +414,73 @@ module ActiveRecord
|
|
|
458
414
|
end
|
|
459
415
|
end
|
|
460
416
|
|
|
417
|
+
def column_definitions_sql(database, identifier)
|
|
418
|
+
object_name = prepared_statements ? '@0' : quote(identifier.object)
|
|
419
|
+
schema_name = if identifier.schema.blank?
|
|
420
|
+
'schema_name()'
|
|
421
|
+
else
|
|
422
|
+
prepared_statements ? '@1' : quote(identifier.schema)
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
%{
|
|
426
|
+
SELECT
|
|
427
|
+
#{lowercase_schema_reflection_sql('o.name')} AS [table_name],
|
|
428
|
+
#{lowercase_schema_reflection_sql('c.name')} AS [name],
|
|
429
|
+
t.name AS [type],
|
|
430
|
+
d.definition AS [default_value],
|
|
431
|
+
CASE
|
|
432
|
+
WHEN t.name IN ('decimal', 'bigint', 'int', 'money', 'numeric', 'smallint', 'smallmoney', 'tinyint')
|
|
433
|
+
THEN c.scale
|
|
434
|
+
END AS [numeric_scale],
|
|
435
|
+
CASE
|
|
436
|
+
WHEN t.name IN ('decimal', 'bigint', 'int', 'money', 'numeric', 'smallint', 'smallmoney', 'tinyint', 'real', 'float')
|
|
437
|
+
THEN c.precision
|
|
438
|
+
END AS [numeric_precision],
|
|
439
|
+
CASE
|
|
440
|
+
WHEN t.name IN ('date', 'datetime', 'datetime2', 'datetimeoffset', 'smalldatetime', 'time')
|
|
441
|
+
THEN c.scale
|
|
442
|
+
END AS [datetime_precision],
|
|
443
|
+
c.collation_name AS [collation],
|
|
444
|
+
ROW_NUMBER() OVER (ORDER BY c.column_id) AS [ordinal_position],
|
|
445
|
+
CASE
|
|
446
|
+
WHEN t.name IN ('nchar', 'nvarchar') AND c.max_length > 0
|
|
447
|
+
THEN c.max_length / 2
|
|
448
|
+
ELSE c.max_length
|
|
449
|
+
END AS [length],
|
|
450
|
+
CASE c.is_nullable
|
|
451
|
+
WHEN 1
|
|
452
|
+
THEN 1
|
|
453
|
+
END AS [is_nullable],
|
|
454
|
+
CASE
|
|
455
|
+
WHEN ic.object_id IS NOT NULL
|
|
456
|
+
THEN 1
|
|
457
|
+
END AS [is_primary],
|
|
458
|
+
c.is_identity AS [is_identity]
|
|
459
|
+
FROM #{database}.sys.columns c
|
|
460
|
+
INNER JOIN #{database}.sys.objects o
|
|
461
|
+
ON c.object_id = o.object_id
|
|
462
|
+
INNER JOIN #{database}.sys.schemas s
|
|
463
|
+
ON o.schema_id = s.schema_id
|
|
464
|
+
INNER JOIN #{database}.sys.types t
|
|
465
|
+
ON c.system_type_id = t.system_type_id
|
|
466
|
+
AND c.user_type_id = t.user_type_id
|
|
467
|
+
LEFT OUTER JOIN #{database}.sys.default_constraints d
|
|
468
|
+
ON c.object_id = d.parent_object_id
|
|
469
|
+
AND c.default_object_id = d.object_id
|
|
470
|
+
LEFT OUTER JOIN #{database}.sys.key_constraints k
|
|
471
|
+
ON c.object_id = k.parent_object_id
|
|
472
|
+
LEFT OUTER JOIN #{database}.sys.index_columns ic
|
|
473
|
+
ON k.parent_object_id = ic.object_id
|
|
474
|
+
AND k.unique_index_id = ic.index_id
|
|
475
|
+
AND c.column_id = ic.column_id
|
|
476
|
+
WHERE
|
|
477
|
+
o.name = #{object_name}
|
|
478
|
+
AND s.name = #{schema_name}
|
|
479
|
+
ORDER BY
|
|
480
|
+
c.column_id
|
|
481
|
+
}.gsub(/[ \t\r\n]+/, ' ').strip
|
|
482
|
+
end
|
|
483
|
+
|
|
461
484
|
def remove_check_constraints(table_name, column_name)
|
|
462
485
|
constraints = select_values "SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE where TABLE_NAME = '#{quote_string(table_name)}' and COLUMN_NAME = '#{quote_string(column_name)}'", 'SCHEMA'
|
|
463
486
|
constraints.each do |constraint|
|
|
@@ -535,8 +558,8 @@ module ActiveRecord
|
|
|
535
558
|
match_data ? match_data[1] : column_name
|
|
536
559
|
end
|
|
537
560
|
|
|
538
|
-
def create_table_definition(*args)
|
|
539
|
-
SQLServer::TableDefinition.new(*args)
|
|
561
|
+
def create_table_definition(*args, **options)
|
|
562
|
+
SQLServer::TableDefinition.new(self, *args, **options)
|
|
540
563
|
end
|
|
541
564
|
|
|
542
565
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActiveRecord
|
|
2
4
|
module ConnectionAdapters
|
|
3
5
|
module SQLServer
|
|
@@ -14,86 +16,86 @@ module ActiveRecord
|
|
|
14
16
|
super
|
|
15
17
|
end
|
|
16
18
|
|
|
17
|
-
def primary_key_nonclustered(*
|
|
18
|
-
|
|
19
|
+
def primary_key_nonclustered(*names, **options)
|
|
20
|
+
names.each { |name| column(name, :primary_key_nonclustered, **options) }
|
|
19
21
|
end
|
|
20
22
|
|
|
21
|
-
def real(*
|
|
22
|
-
|
|
23
|
+
def real(*names, **options)
|
|
24
|
+
names.each { |name| column(name, :real, **options) }
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
def money(*
|
|
26
|
-
|
|
27
|
+
def money(*names, **options)
|
|
28
|
+
names.each { |name| column(name, :money, **options) }
|
|
27
29
|
end
|
|
28
30
|
|
|
29
|
-
def smalldatetime(*
|
|
30
|
-
|
|
31
|
+
def smalldatetime(*names, **options)
|
|
32
|
+
names.each { |name| column(name, :smalldatetime, **options) }
|
|
31
33
|
end
|
|
32
34
|
|
|
33
|
-
def datetime(*
|
|
34
|
-
|
|
35
|
+
def datetime(*names, **options)
|
|
36
|
+
names.each do |name|
|
|
35
37
|
if options[:precision]
|
|
36
|
-
datetime2(name, options)
|
|
38
|
+
datetime2(name, **options)
|
|
37
39
|
else
|
|
38
|
-
column(name, :datetime, options)
|
|
40
|
+
column(name, :datetime, **options)
|
|
39
41
|
end
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
|
|
43
|
-
def datetime2(*
|
|
44
|
-
|
|
45
|
+
def datetime2(*names, **options)
|
|
46
|
+
names.each { |name| column(name, :datetime2, **options) }
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
def datetimeoffset(*
|
|
48
|
-
|
|
49
|
+
def datetimeoffset(*names, **options)
|
|
50
|
+
names.each { |name| column(name, :datetimeoffset, **options) }
|
|
49
51
|
end
|
|
50
52
|
|
|
51
|
-
def smallmoney(*
|
|
52
|
-
|
|
53
|
+
def smallmoney(*names, **options)
|
|
54
|
+
names.each { |name| column(name, :smallmoney, **options) }
|
|
53
55
|
end
|
|
54
56
|
|
|
55
|
-
def char(*
|
|
56
|
-
|
|
57
|
+
def char(*names, **options)
|
|
58
|
+
names.each { |name| column(name, :char, **options) }
|
|
57
59
|
end
|
|
58
60
|
|
|
59
|
-
def varchar(*
|
|
60
|
-
|
|
61
|
+
def varchar(*names, **options)
|
|
62
|
+
names.each { |name| column(name, :varchar, **options) }
|
|
61
63
|
end
|
|
62
64
|
|
|
63
|
-
def varchar_max(*
|
|
64
|
-
|
|
65
|
+
def varchar_max(*names, **options)
|
|
66
|
+
names.each { |name| column(name, :varchar_max, **options) }
|
|
65
67
|
end
|
|
66
68
|
|
|
67
|
-
def text_basic(*
|
|
68
|
-
|
|
69
|
+
def text_basic(*names, **options)
|
|
70
|
+
names.each { |name| column(name, :text_basic, **options) }
|
|
69
71
|
end
|
|
70
72
|
|
|
71
|
-
def nchar(*
|
|
72
|
-
|
|
73
|
+
def nchar(*names, **options)
|
|
74
|
+
names.each { |name| column(name, :nchar, **options) }
|
|
73
75
|
end
|
|
74
76
|
|
|
75
|
-
def ntext(*
|
|
76
|
-
|
|
77
|
+
def ntext(*names, **options)
|
|
78
|
+
names.each { |name| column(name, :ntext, **options) }
|
|
77
79
|
end
|
|
78
80
|
|
|
79
|
-
def binary_basic(*
|
|
80
|
-
|
|
81
|
+
def binary_basic(*names, **options)
|
|
82
|
+
names.each { |name| column(name, :binary_basic, **options) }
|
|
81
83
|
end
|
|
82
84
|
|
|
83
|
-
def varbinary(*
|
|
84
|
-
|
|
85
|
+
def varbinary(*names, **options)
|
|
86
|
+
names.each { |name| column(name, :varbinary, **options) }
|
|
85
87
|
end
|
|
86
88
|
|
|
87
|
-
def uuid(*
|
|
88
|
-
|
|
89
|
+
def uuid(*names, **options)
|
|
90
|
+
names.each { |name| column(name, :uniqueidentifier, **options) }
|
|
89
91
|
end
|
|
90
92
|
|
|
91
|
-
def ss_timestamp(*
|
|
92
|
-
|
|
93
|
+
def ss_timestamp(*names, **options)
|
|
94
|
+
names.each { |name| column(name, :ss_timestamp, **options) }
|
|
93
95
|
end
|
|
94
96
|
|
|
95
|
-
def json(*
|
|
96
|
-
|
|
97
|
+
def json(*names, **options)
|
|
98
|
+
names.each { |name| column(name, :text, **options) }
|
|
97
99
|
end
|
|
98
100
|
|
|
99
101
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'active_record/connection_adapters/abstract/transaction'
|
|
2
4
|
|
|
3
5
|
module ActiveRecord
|
|
@@ -32,7 +34,7 @@ module ActiveRecord
|
|
|
32
34
|
|
|
33
35
|
attr_reader :starting_isolation_level
|
|
34
36
|
|
|
35
|
-
def initialize(connection, options,
|
|
37
|
+
def initialize(connection, options, **args)
|
|
36
38
|
@connection = connection
|
|
37
39
|
@starting_isolation_level = current_isolation_level if options[:isolation]
|
|
38
40
|
super
|