activerecord-sqlserver-adapter 4.2.18 → 5.0.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 +8 -223
- data/Gemfile +18 -17
- data/RAILS5-TODO.md +36 -0
- data/README.md +27 -8
- data/RUNNING_UNIT_TESTS.md +0 -17
- data/Rakefile +2 -7
- data/VERSION +1 -1
- data/activerecord-sqlserver-adapter.gemspec +1 -1
- data/appveyor.yml +0 -2
- data/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +15 -8
- data/lib/active_record/connection_adapters/sqlserver/database_statements.rb +45 -97
- data/lib/active_record/connection_adapters/sqlserver/database_tasks.rb +1 -2
- data/lib/active_record/connection_adapters/sqlserver/quoting.rb +31 -10
- data/lib/active_record/connection_adapters/sqlserver/schema_creation.rb +0 -18
- data/lib/active_record/connection_adapters/sqlserver/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlserver/schema_statements.rb +101 -58
- data/lib/active_record/connection_adapters/sqlserver/showplan.rb +7 -7
- data/lib/active_record/connection_adapters/sqlserver/sql_type_metadata.rb +20 -0
- data/lib/active_record/connection_adapters/sqlserver/table_definition.rb +56 -32
- data/lib/active_record/connection_adapters/sqlserver/transaction.rb +1 -1
- data/lib/active_record/connection_adapters/sqlserver/type.rb +34 -32
- data/lib/active_record/connection_adapters/sqlserver/type/big_integer.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/binary.rb +6 -0
- data/lib/active_record/connection_adapters/sqlserver/type/boolean.rb +3 -0
- data/lib/active_record/connection_adapters/sqlserver/type/char.rb +9 -20
- data/lib/active_record/connection_adapters/sqlserver/type/data.rb +30 -0
- data/lib/active_record/connection_adapters/sqlserver/type/date.rb +28 -4
- data/lib/active_record/connection_adapters/sqlserver/type/datetime.rb +28 -14
- data/lib/active_record/connection_adapters/sqlserver/type/datetime2.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver/type/datetimeoffset.rb +4 -16
- data/lib/active_record/connection_adapters/sqlserver/type/decimal.rb +9 -0
- data/lib/active_record/connection_adapters/sqlserver/type/float.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/integer.rb +3 -0
- data/lib/active_record/connection_adapters/sqlserver/type/money.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/type/real.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/small_integer.rb +3 -1
- data/lib/active_record/connection_adapters/sqlserver/type/small_money.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/type/smalldatetime.rb +8 -1
- data/lib/active_record/connection_adapters/sqlserver/type/text.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/time.rb +20 -8
- data/lib/active_record/connection_adapters/sqlserver/type/time_value_fractional.rb +25 -10
- data/lib/active_record/connection_adapters/sqlserver/type/timestamp.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/tiny_integer.rb +3 -0
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_char.rb +6 -0
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_text.rb +4 -0
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar.rb +7 -1
- data/lib/active_record/connection_adapters/sqlserver/type/unicode_varchar_max.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/type/uuid.rb +15 -2
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary.rb +7 -1
- data/lib/active_record/connection_adapters/sqlserver/type/varbinary_max.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/type/varchar.rb +7 -1
- data/lib/active_record/connection_adapters/sqlserver/type/varchar_max.rb +5 -1
- data/lib/active_record/connection_adapters/sqlserver/utils.rb +10 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +71 -57
- data/lib/active_record/connection_adapters/sqlserver_column.rb +5 -30
- data/lib/active_record/sqlserver_base.rb +1 -5
- data/lib/arel/visitors/sqlserver.rb +11 -20
- data/test/bin/setup.sh +4 -6
- data/test/cases/adapter_test_sqlserver.rb +11 -20
- data/test/cases/coerced_tests.rb +233 -138
- data/test/cases/column_test_sqlserver.rb +244 -227
- data/test/cases/connection_test_sqlserver.rb +5 -76
- data/test/cases/fully_qualified_identifier_test_sqlserver.rb +7 -7
- data/test/cases/helper_sqlserver.rb +4 -15
- data/test/cases/pessimistic_locking_test_sqlserver.rb +1 -1
- data/test/cases/rake_test_sqlserver.rb +20 -14
- data/test/cases/schema_dumper_test_sqlserver.rb +94 -63
- data/test/cases/schema_test_sqlserver.rb +2 -2
- data/test/cases/showplan_test_sqlserver.rb +1 -1
- data/test/cases/specific_schema_test_sqlserver.rb +7 -14
- data/test/cases/transaction_test_sqlserver.rb +1 -1
- data/test/cases/uuid_test_sqlserver.rb +0 -1
- data/test/config.yml +0 -10
- data/test/migrations/transaction_table/1_table_will_never_be_created.rb +1 -1
- data/test/schema/sqlserver_specific_schema.rb +0 -16
- data/test/support/coerceable_test_sqlserver.rb +6 -2
- data/test/support/connection_reflection.rb +0 -4
- data/test/support/sql_counter_sqlserver.rb +17 -21
- metadata +9 -7
- data/lib/active_record/connection_adapters/sqlserver/core_ext/odbc.rb +0 -34
- data/lib/active_record/connection_adapters/sqlserver/schema_cache.rb +0 -114
@@ -7,23 +7,38 @@ module ActiveRecord
|
|
7
7
|
@native_database_types ||= initialize_native_database_types.freeze
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
tables
|
10
|
+
def tables(name = nil)
|
11
|
+
ActiveSupport::Deprecation.warn 'Passing arguments to #tables is deprecated without replacement.' if name
|
12
|
+
tables_sql('BASE TABLE')
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
-
|
15
|
+
def table_exists?(table_name)
|
16
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
17
|
+
#table_exists? currently checks both tables and views.
|
18
|
+
This behavior is deprecated and will be changed with Rails 5.1 to only check tables.
|
19
|
+
Use #data_source_exists? instead.
|
20
|
+
MSG
|
21
|
+
data_source_exists?(table_name)
|
16
22
|
end
|
17
23
|
|
18
|
-
def
|
24
|
+
def data_source_exists?(table_name)
|
19
25
|
return false if table_name.blank?
|
20
26
|
unquoted_table_name = SQLServer::Utils.extract_identifiers(table_name).object
|
21
|
-
super
|
27
|
+
super(unquoted_table_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
def views
|
31
|
+
tables_sql('VIEW')
|
32
|
+
end
|
33
|
+
|
34
|
+
def view_exists?(table_name)
|
35
|
+
identifier = SQLServer::Utils.extract_identifiers(table_name)
|
36
|
+
super(identifier.object)
|
22
37
|
end
|
23
38
|
|
24
|
-
def create_table(table_name,
|
39
|
+
def create_table(table_name, comment: nil, **options)
|
25
40
|
res = super
|
26
|
-
|
41
|
+
clear_cache!
|
27
42
|
res
|
28
43
|
end
|
29
44
|
|
@@ -47,17 +62,41 @@ module ActiveRecord
|
|
47
62
|
end
|
48
63
|
end
|
49
64
|
|
50
|
-
def columns(table_name
|
65
|
+
def columns(table_name)
|
51
66
|
return [] if table_name.blank?
|
52
67
|
column_definitions(table_name).map do |ci|
|
53
|
-
sqlserver_options = ci.slice :ordinal_position, :is_primary, :is_identity
|
54
|
-
|
55
|
-
new_column
|
68
|
+
sqlserver_options = ci.slice :ordinal_position, :is_primary, :is_identity
|
69
|
+
sql_type_metadata = fetch_type_metadata ci[:type], sqlserver_options
|
70
|
+
new_column(
|
71
|
+
ci[:name],
|
72
|
+
ci[:default_value],
|
73
|
+
sql_type_metadata,
|
74
|
+
ci[:null],
|
75
|
+
ci[:table_name],
|
76
|
+
ci[:default_function],
|
77
|
+
ci[:collation],
|
78
|
+
nil,
|
79
|
+
sqlserver_options
|
80
|
+
)
|
56
81
|
end
|
57
82
|
end
|
58
83
|
|
59
|
-
def new_column(name, default,
|
60
|
-
SQLServerColumn.new
|
84
|
+
def new_column(name, default, sql_type_metadata, null, table_name, default_function = nil, collation = nil, comment = nil, sqlserver_options = {})
|
85
|
+
SQLServerColumn.new(
|
86
|
+
name,
|
87
|
+
default,
|
88
|
+
sql_type_metadata,
|
89
|
+
null, table_name,
|
90
|
+
default_function,
|
91
|
+
collation,
|
92
|
+
comment,
|
93
|
+
sqlserver_options
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
def primary_keys(table_name)
|
98
|
+
primaries = schema_cache.columns(table_name).select(&:is_primary?).map(&:name)
|
99
|
+
primaries.present? ? primaries : identity_columns(table_name).map(&:name)
|
61
100
|
end
|
62
101
|
|
63
102
|
def rename_table(table_name, new_name)
|
@@ -82,11 +121,11 @@ module ActiveRecord
|
|
82
121
|
indexes = indexes(table_name).select { |index| index.columns.include?(column_name.to_s) }
|
83
122
|
remove_indexes(table_name, column_name)
|
84
123
|
end
|
85
|
-
sql_commands << "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{
|
124
|
+
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?
|
86
125
|
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
|
87
126
|
sql_commands[-1] << ' NOT NULL' if !options[:null].nil? && options[:null] == false
|
88
127
|
if options_include_default?(options)
|
89
|
-
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name, column_name)} DEFAULT #{
|
128
|
+
sql_commands << "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name, column_name)} DEFAULT #{quote_default_expression(options[:default], column_object)} FOR #{quote_column_name(column_name)}"
|
90
129
|
end
|
91
130
|
# Add any removed indexes back
|
92
131
|
indexes.each do |index|
|
@@ -95,21 +134,22 @@ module ActiveRecord
|
|
95
134
|
sql_commands.each { |c| do_execute(c) }
|
96
135
|
end
|
97
136
|
|
98
|
-
def change_column_default(table_name, column_name,
|
99
|
-
|
137
|
+
def change_column_default(table_name, column_name, default_or_changes)
|
138
|
+
clear_cache!
|
139
|
+
column = column_for(table_name, column_name)
|
140
|
+
return unless column
|
100
141
|
remove_default_constraint(table_name, column_name)
|
101
|
-
|
102
|
-
do_execute "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name, column_name)} DEFAULT #{
|
103
|
-
|
142
|
+
default = extract_new_default_value(default_or_changes)
|
143
|
+
do_execute "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT #{default_constraint_name(table_name, column_name)} DEFAULT #{quote_default_expression(default, column)} FOR #{quote_column_name(column_name)}"
|
144
|
+
clear_cache!
|
104
145
|
end
|
105
146
|
|
106
147
|
def rename_column(table_name, column_name, new_column_name)
|
107
|
-
|
108
|
-
detect_column_for! table_name, column_name
|
148
|
+
clear_cache!
|
109
149
|
identifier = SQLServer::Utils.extract_identifiers("#{table_name}.#{column_name}")
|
110
150
|
execute_procedure :sp_rename, identifier.quoted, new_column_name, 'COLUMN'
|
111
151
|
rename_column_indexes(table_name, column_name, new_column_name)
|
112
|
-
|
152
|
+
clear_cache!
|
113
153
|
end
|
114
154
|
|
115
155
|
def rename_index(table_name, old_name, new_name)
|
@@ -157,6 +197,16 @@ module ActiveRecord
|
|
157
197
|
when 5..8 then 'bigint'
|
158
198
|
else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
|
159
199
|
end
|
200
|
+
when 'datetime2'
|
201
|
+
column_type_sql = super
|
202
|
+
if precision
|
203
|
+
if (0..7) === precision
|
204
|
+
column_type_sql << "(#{precision})"
|
205
|
+
else
|
206
|
+
raise(ActiveRecordError, "The dattime2 type has precision of #{precision}. The allowed range of precision is from 0 to 7")
|
207
|
+
end
|
208
|
+
end
|
209
|
+
column_type_sql
|
160
210
|
else
|
161
211
|
super
|
162
212
|
end
|
@@ -171,6 +221,10 @@ module ActiveRecord
|
|
171
221
|
[super, *order_columns].join(', ')
|
172
222
|
end
|
173
223
|
|
224
|
+
def update_table_definition(table_name, base)
|
225
|
+
SQLServer::Table.new(table_name, base)
|
226
|
+
end
|
227
|
+
|
174
228
|
def change_column_null(table_name, column_name, allow_null, default = nil)
|
175
229
|
table_id = SQLServer::Utils.extract_identifiers(table_name)
|
176
230
|
column_id = SQLServer::Utils.extract_identifiers(column_name)
|
@@ -183,12 +237,6 @@ module ActiveRecord
|
|
183
237
|
do_execute sql
|
184
238
|
end
|
185
239
|
|
186
|
-
# === SQLServer Specific ======================================== #
|
187
|
-
|
188
|
-
def views
|
189
|
-
tables('VIEW')
|
190
|
-
end
|
191
|
-
|
192
240
|
|
193
241
|
protected
|
194
242
|
|
@@ -228,6 +276,12 @@ module ActiveRecord
|
|
228
276
|
}
|
229
277
|
end
|
230
278
|
|
279
|
+
def tables_sql(type)
|
280
|
+
tn = lowercase_schema_reflection_sql 'TABLE_NAME'
|
281
|
+
sql = "SELECT #{tn} FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = '#{type}' ORDER BY TABLE_NAME"
|
282
|
+
select_values sql, 'SCHEMA'
|
283
|
+
end
|
284
|
+
|
231
285
|
def column_definitions(table_name)
|
232
286
|
identifier = if database_prefix_remote_server?
|
233
287
|
SQLServer::Utils.extract_identifiers("#{database_prefix}#{table_name}")
|
@@ -235,8 +289,8 @@ module ActiveRecord
|
|
235
289
|
SQLServer::Utils.extract_identifiers(table_name)
|
236
290
|
end
|
237
291
|
database = identifier.fully_qualified_database_quoted
|
238
|
-
view_exists =
|
239
|
-
view_tblnm =
|
292
|
+
view_exists = view_exists?(table_name)
|
293
|
+
view_tblnm = view_table_name(table_name) if view_exists
|
240
294
|
sql = %{
|
241
295
|
SELECT DISTINCT
|
242
296
|
#{lowercase_schema_reflection_sql('columns.TABLE_NAME')} AS table_name,
|
@@ -246,7 +300,7 @@ module ActiveRecord
|
|
246
300
|
columns.NUMERIC_SCALE AS numeric_scale,
|
247
301
|
columns.NUMERIC_PRECISION AS numeric_precision,
|
248
302
|
columns.DATETIME_PRECISION AS datetime_precision,
|
249
|
-
columns.COLLATION_NAME AS collation,
|
303
|
+
columns.COLLATION_NAME AS [collation],
|
250
304
|
columns.ordinal_position,
|
251
305
|
CASE
|
252
306
|
WHEN columns.DATA_TYPE IN ('nchar','nvarchar','char','varchar') THEN columns.CHARACTER_MAXIMUM_LENGTH
|
@@ -264,7 +318,6 @@ module ActiveRecord
|
|
264
318
|
FROM #{database}.INFORMATION_SCHEMA.COLUMNS columns
|
265
319
|
LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
|
266
320
|
ON TC.TABLE_NAME = columns.TABLE_NAME
|
267
|
-
AND TC.TABLE_SCHEMA = columns.TABLE_SCHEMA
|
268
321
|
AND TC.CONSTRAINT_TYPE = N'PRIMARY KEY'
|
269
322
|
LEFT OUTER JOIN #{database}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
|
270
323
|
ON KCU.COLUMN_NAME = columns.COLUMN_NAME
|
@@ -282,12 +335,14 @@ module ActiveRecord
|
|
282
335
|
INNER JOIN #{database}.sys.columns AS c
|
283
336
|
ON o.object_id = c.object_id
|
284
337
|
AND c.name = columns.COLUMN_NAME
|
285
|
-
WHERE columns.TABLE_NAME = @0
|
286
|
-
AND columns.TABLE_SCHEMA = #{identifier.schema.blank? ? 'schema_name()' : '@1'}
|
338
|
+
WHERE columns.TABLE_NAME = #{prepared_statements ? '@0' : quote(identifier.object)}
|
339
|
+
AND columns.TABLE_SCHEMA = #{identifier.schema.blank? ? 'schema_name()' : (prepared_statements ? '@1' : quote(identifier.schema))}
|
287
340
|
ORDER BY columns.ordinal_position
|
288
|
-
}.gsub(/[ \t\r\n]+/, ' ')
|
289
|
-
binds = [
|
290
|
-
|
341
|
+
}.gsub(/[ \t\r\n]+/, ' ').strip
|
342
|
+
binds = []
|
343
|
+
nv128 = SQLServer::Type::UnicodeVarchar.new limit: 128
|
344
|
+
binds << Relation::QueryAttribute.new('TABLE_NAME', identifier.object, nv128)
|
345
|
+
binds << Relation::QueryAttribute.new('TABLE_SCHEMA', identifier.schema, nv128) unless identifier.schema.blank?
|
291
346
|
results = sp_executesql(sql, 'SCHEMA', binds)
|
292
347
|
results.map do |ci|
|
293
348
|
ci = ci.symbolize_keys
|
@@ -348,14 +403,6 @@ module ActiveRecord
|
|
348
403
|
end
|
349
404
|
end
|
350
405
|
|
351
|
-
def info_schema_table_name_column
|
352
|
-
@info_schema_table_name_column ||= new_column 'table_name', nil, lookup_cast_type('nvarchar(128)'), 'nvarchar(128)', true
|
353
|
-
end
|
354
|
-
|
355
|
-
def info_schema_table_schema_column
|
356
|
-
@info_schema_table_schema_column ||= new_column 'table_schema', nil, lookup_cast_type('nvarchar(128)'), 'nvarchar(128)', true
|
357
|
-
end
|
358
|
-
|
359
406
|
def remove_check_constraints(table_name, column_name)
|
360
407
|
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'
|
361
408
|
constraints.each do |constraint|
|
@@ -409,7 +456,7 @@ module ActiveRecord
|
|
409
456
|
# === SQLServer Specific (View Reflection) ====================== #
|
410
457
|
|
411
458
|
def view_table_name(table_name)
|
412
|
-
view_info =
|
459
|
+
view_info = view_information(table_name)
|
413
460
|
view_info ? get_table_name(view_info['VIEW_DEFINITION']) : table_name
|
414
461
|
end
|
415
462
|
|
@@ -430,12 +477,8 @@ module ActiveRecord
|
|
430
477
|
view_info
|
431
478
|
end
|
432
479
|
|
433
|
-
def table_name_or_views_table_name(table_name)
|
434
|
-
schema_cache.view_exists?(table_name) ? view_table_name(table_name) : table_name
|
435
|
-
end
|
436
|
-
|
437
480
|
def views_real_column_name(table_name, column_name)
|
438
|
-
view_definition =
|
481
|
+
view_definition = view_information(table_name)[:VIEW_DEFINITION]
|
439
482
|
return column_name unless view_definition
|
440
483
|
match_data = view_definition.match(/([\w-]*)\s+as\s+#{column_name}/im)
|
441
484
|
match_data ? match_data[1] : column_name
|
@@ -446,7 +489,7 @@ module ActiveRecord
|
|
446
489
|
def query_requires_identity_insert?(sql)
|
447
490
|
if insert_sql?(sql)
|
448
491
|
table_name = get_table_name(sql)
|
449
|
-
id_column =
|
492
|
+
id_column = identity_columns(table_name).first
|
450
493
|
id_column && sql =~ /^\s*(INSERT|EXEC sp_executesql N'INSERT)[^(]+\([^)]*\b(#{id_column.name})\b,?[^)]*\)/i ? quote_table_name(table_name) : false
|
451
494
|
else
|
452
495
|
false
|
@@ -457,15 +500,15 @@ module ActiveRecord
|
|
457
500
|
!(sql =~ /^\s*(INSERT|EXEC sp_executesql N'INSERT)/i).nil?
|
458
501
|
end
|
459
502
|
|
460
|
-
def
|
461
|
-
|
503
|
+
def identity_columns(table_name)
|
504
|
+
columns(table_name).select(&:is_identity?)
|
462
505
|
end
|
463
506
|
|
464
507
|
|
465
508
|
private
|
466
509
|
|
467
|
-
def create_table_definition(
|
468
|
-
SQLServer::TableDefinition.new
|
510
|
+
def create_table_definition(*args)
|
511
|
+
SQLServer::TableDefinition.new(*args)
|
469
512
|
end
|
470
513
|
|
471
514
|
end
|
@@ -28,32 +28,32 @@ module ActiveRecord
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def set_showplan_option(enable = true)
|
31
|
-
sql = "SET #{
|
31
|
+
sql = "SET #{showplan_option} #{enable ? 'ON' : 'OFF'}"
|
32
32
|
raw_connection_do(sql)
|
33
33
|
rescue Exception
|
34
|
-
raise ActiveRecordError, "#{
|
34
|
+
raise ActiveRecordError, "#{showplan_option} could not be turned #{enable ? 'ON' : 'OFF'}, perhaps you do not have SHOWPLAN permissions?"
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
37
|
+
def showplan_option
|
38
38
|
(SQLServerAdapter.showplan_option || OPTION_ALL).tap do |opt|
|
39
39
|
raise(ArgumentError, "Unknown SHOWPLAN option #{opt.inspect} found.") if OPTIONS.exclude?(opt)
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
43
|
def showplan_all?
|
44
|
-
|
44
|
+
showplan_option == OPTION_ALL
|
45
45
|
end
|
46
46
|
|
47
47
|
def showplan_text?
|
48
|
-
|
48
|
+
showplan_option == OPTION_TEXT
|
49
49
|
end
|
50
50
|
|
51
51
|
def showplan_xml?
|
52
|
-
|
52
|
+
showplan_option == OPTION_XML
|
53
53
|
end
|
54
54
|
|
55
55
|
def showplan_printer
|
56
|
-
case
|
56
|
+
case showplan_option
|
57
57
|
when OPTION_XML then PrinterXml
|
58
58
|
when OPTION_ALL, OPTION_TEXT then PrinterTable
|
59
59
|
else PrinterTable
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ConnectionAdapters
|
3
|
+
module SQLServer
|
4
|
+
class SqlTypeMetadata < ActiveRecord::ConnectionAdapters::SqlTypeMetadata
|
5
|
+
|
6
|
+
def initialize(**kwargs)
|
7
|
+
@sqlserver_options = kwargs.extract!(:sqlserver_options)
|
8
|
+
super(**kwargs)
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def attributes_for_hash
|
14
|
+
super + [@sqlserver_options]
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,76 +1,100 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module ConnectionAdapters
|
3
3
|
module SQLServer
|
4
|
-
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
|
5
4
|
|
6
|
-
|
5
|
+
module ColumnMethods
|
6
|
+
|
7
|
+
def primary_key(name, type = :primary_key, **options)
|
7
8
|
return super unless type == :uuid
|
8
9
|
options[:default] = options.fetch(:default, 'NEWID()')
|
9
10
|
options[:primary_key] = true
|
10
11
|
column name, type, options
|
11
12
|
end
|
12
13
|
|
13
|
-
def real(
|
14
|
-
column(name, :real, options)
|
14
|
+
def real(*args, **options)
|
15
|
+
args.each { |name| column(name, :real, options) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def money(*args, **options)
|
19
|
+
args.each { |name| column(name, :money, options) }
|
15
20
|
end
|
16
21
|
|
17
|
-
def
|
18
|
-
|
22
|
+
def datetime(*args, **options)
|
23
|
+
args.each do |name|
|
24
|
+
if options[:precision]
|
25
|
+
datetime2(name, options)
|
26
|
+
else
|
27
|
+
column(name, :datetime, options)
|
28
|
+
end
|
29
|
+
end
|
19
30
|
end
|
20
31
|
|
21
|
-
def datetime2(
|
22
|
-
column(name, :datetime2, options)
|
32
|
+
def datetime2(*args, **options)
|
33
|
+
args.each { |name| column(name, :datetime2, options) }
|
23
34
|
end
|
24
35
|
|
25
|
-
def datetimeoffset(
|
26
|
-
column(name, :datetimeoffset, options)
|
36
|
+
def datetimeoffset(*args, **options)
|
37
|
+
args.each { |name| column(name, :datetimeoffset, options) }
|
27
38
|
end
|
28
39
|
|
29
|
-
def smallmoney(
|
30
|
-
column(name, :smallmoney, options)
|
40
|
+
def smallmoney(*args, **options)
|
41
|
+
args.each { |name| column(name, :smallmoney, options) }
|
31
42
|
end
|
32
43
|
|
33
|
-
def char(
|
34
|
-
column(name, :char, options)
|
44
|
+
def char(*args, **options)
|
45
|
+
args.each { |name| column(name, :char, options) }
|
35
46
|
end
|
36
47
|
|
37
|
-
def varchar(
|
38
|
-
column(name, :varchar, options)
|
48
|
+
def varchar(*args, **options)
|
49
|
+
args.each { |name| column(name, :varchar, options) }
|
39
50
|
end
|
40
51
|
|
41
|
-
def varchar_max(
|
42
|
-
column(name, :varchar_max, options)
|
52
|
+
def varchar_max(*args, **options)
|
53
|
+
args.each { |name| column(name, :varchar_max, options) }
|
43
54
|
end
|
44
55
|
|
45
|
-
def text_basic(
|
46
|
-
column(name, :text_basic, options)
|
56
|
+
def text_basic(*args, **options)
|
57
|
+
args.each { |name| column(name, :text_basic, options) }
|
47
58
|
end
|
48
59
|
|
49
|
-
def nchar(
|
50
|
-
column(name, :nchar, options)
|
60
|
+
def nchar(*args, **options)
|
61
|
+
args.each { |name| column(name, :nchar, options) }
|
51
62
|
end
|
52
63
|
|
53
|
-
def ntext(
|
54
|
-
column(name, :ntext, options)
|
64
|
+
def ntext(*args, **options)
|
65
|
+
args.each { |name| column(name, :ntext, options) }
|
55
66
|
end
|
56
67
|
|
57
|
-
def binary_basic(
|
58
|
-
column(name, :binary_basic, options)
|
68
|
+
def binary_basic(*args, **options)
|
69
|
+
args.each { |name| column(name, :binary_basic, options) }
|
59
70
|
end
|
60
71
|
|
61
|
-
def varbinary(
|
62
|
-
column(name, :varbinary, options)
|
72
|
+
def varbinary(*args, **options)
|
73
|
+
args.each { |name| column(name, :varbinary, options) }
|
63
74
|
end
|
64
75
|
|
65
|
-
def uuid(
|
66
|
-
column(name, :uniqueidentifier, options)
|
76
|
+
def uuid(*args, **options)
|
77
|
+
args.each { |name| column(name, :uniqueidentifier, options) }
|
67
78
|
end
|
68
79
|
|
69
|
-
def ss_timestamp(
|
70
|
-
column(name, :ss_timestamp, options)
|
80
|
+
def ss_timestamp(*args, **options)
|
81
|
+
args.each { |name| column(name, :ss_timestamp, options) }
|
71
82
|
end
|
72
83
|
|
73
84
|
end
|
85
|
+
|
86
|
+
class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
|
87
|
+
include ColumnMethods
|
88
|
+
|
89
|
+
def new_column_definition(name, type, options)
|
90
|
+
type = :datetime2 if type == :datetime && options[:precision]
|
91
|
+
super name, type, options
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class Table < ActiveRecord::ConnectionAdapters::Table
|
96
|
+
include ColumnMethods
|
97
|
+
end
|
74
98
|
end
|
75
99
|
end
|
76
100
|
end
|