Class: ActiveRecord::ConnectionAdapters::SQLServerAdapter
  
  
  
  
    
      Constant Summary
      collapse
    
    
      
        - ADAPTER_NAME =
          
        
 
        "SQLServer".freeze
 
      
        - DEFAULT_TIME_PRECISION =
          
  
         
        7
 
      
        - TYPE_MAP =
          
        
 
        Type::TypeMap.new.tap { |m| initialize_type_map(m) } 
      
    
  
  
  
  
  ActiveRecord::ConnectionAdapters::SQLServer::Version::VERSION
  
  
  
  ActiveRecord::ConnectionAdapters::SQLServer::Quoting::QUOTED_FALSE, ActiveRecord::ConnectionAdapters::SQLServer::Quoting::QUOTED_STRING_PREFIX, ActiveRecord::ConnectionAdapters::SQLServer::Quoting::QUOTED_TRUE
  
  
  
  ActiveRecord::ConnectionAdapters::SQLServer::Showplan::OPTIONS, ActiveRecord::ConnectionAdapters::SQLServer::Showplan::OPTION_ALL, ActiveRecord::ConnectionAdapters::SQLServer::Showplan::OPTION_TEXT, ActiveRecord::ConnectionAdapters::SQLServer::Showplan::OPTION_XML
  Instance Attribute Summary collapse
  
  
    
      Class Method Summary
      collapse
    
    
  
    
      Instance Method Summary
      collapse
    
    
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  #column_name_matcher, #column_name_with_order_matcher, #fetch_type_metadata, #quote, #quote_column_name, #quote_default_expression, #quote_string, #quote_string_single, #quote_string_single_national, #quoted_date, #quoted_false, #quoted_true, #type_cast, #unquoted_false, #unquoted_true
  
  
  
  
  
  
  
  
  
  #begin_db_transaction, #begin_isolated_db_transaction, #build_insert_sql, #case_sensitive_comparison, #commit_db_transaction, #create_savepoint, #exec_delete, #exec_insert, #exec_query, #exec_rollback_db_transaction, #exec_rollback_to_savepoint, #exec_update, #execute, #execute_procedure, #insert_fixtures_set, #newid_function, #newsequentialid_function, #release_savepoint, #set_transaction_isolation_level, #transaction_isolation_levels, #use_database, #user_options, #user_options_dateformat, #user_options_isolation_level, #user_options_language, #with_identity_insert_enabled, #write_query?
  
  
  
  
  
  
  
  
  
  
  #explain
  
  
  
  
  
  
  
  
  
  #change_column, #change_column_default, #change_column_null, #change_table_schema, #columns, #columns_for_distinct, #create_schema, #create_schema_dumper, #create_table, #drop_schema, #drop_table, #extract_foreign_key_action, #foreign_keys, #indexes, #native_database_types, #new_column, #primary_keys, #primary_keys_select, #remove_column, #remove_index!, #rename_column, #rename_index, #rename_table, #type_to_sql, #update_table_definition
  
  
  
  
  
  
  
  
  
  #column_name_length, #columns_per_multicolumn_index, #columns_per_table, #index_name_length, #indexes_per_table, #joins_per_query, #sql_query_length, #table_alias_length, #table_name_length
  
  
  
  
  
  
  
  
  
  #charset, #collation, #create_database, #current_database, #drop_database
  
  Constructor Details
  
    
  
  
    #initialize(connection, logger, _connection_options, config)  ⇒ SQLServerAdapter 
  
  
  
  
    
Returns a new instance of SQLServerAdapter.
   
 
  
  
    
      
140
141
142
143
144 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 140
def initialize(connection, logger, _connection_options, config)
  super(connection, logger, config)
  @connection_options = config
  configure_connection
end 
     | 
  
 
  
 
  
    Instance Attribute Details
    
      
      
      
  
  
    #spid  ⇒ Object  
  
  
  
  
    
Returns the value of attribute spid.
   
 
  
  
    
      
49
50
51 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 49
def spid
  @spid
end 
     | 
  
 
    
   
  
    Class Method Details
    
      
  
  
    .config_appname(config)  ⇒ Object 
  
  
  
  
    
      
107
108
109
110
111
112
113
114
115
116
117
118
119 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 107
def config_appname(config)
  if instance_methods.include?(:configure_application_name)
    ActiveSupport::Deprecation.warn <<~MSG.squish
    Configuring the application name used by TinyTDS by overriding the
    `ActiveRecord::ConnectionAdapters::SQLServerAdapter#configure_application_name`
    instance method is no longer supported. The application name should configured
    using the `appname` setting in the `database.yml` file instead. Consult the
    README for further information."
    MSG
  end
  config[:appname] || rails_application_name
end
     | 
  
 
    
      
  
  
    .config_encoding(config)  ⇒ Object 
  
  
  
  
    
      
135
136
137 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 135
def config_encoding(config)
  config[:encoding].present? ? config[:encoding] : nil
end 
     | 
  
 
    
      
  
  
    .config_login_timeout(config)  ⇒ Object 
  
  
  
  
    
      
127
128
129 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 127
def config_login_timeout(config)
  config[:login_timeout].present? ? config[:login_timeout].to_i : nil
end 
     | 
  
 
    
      
  
  
    .config_timeout(config)  ⇒ Object 
  
  
  
  
    
      
131
132
133 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 131
def config_timeout(config)
  config[:timeout].present? ? config[:timeout].to_i / 1000 : nil
end 
     | 
  
 
    
      
  
  
    .database_exists?(config)  ⇒ Boolean 
  
  
  
  
    
      
160
161
162
163
164 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 160
def self.database_exists?(config)
  !!ActiveRecord::Base.sqlserver_connection(config)
rescue ActiveRecord::NoDatabaseError
  false
end 
     | 
  
 
    
      
  
  
    .dblib_connect(config)  ⇒ Object 
  
  
  
  
    
      
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 72
def dblib_connect(config)
  TinyTds::Client.new(
    dataserver:    config[:dataserver],
    host:          config[:host],
    port:          config[:port],
    username:      config[:username],
    password:      config[:password],
    database:      config[:database],
    tds_version:   config[:tds_version] || "7.3",
    appname:       config_appname(config),
    login_timeout: config_login_timeout(config),
    timeout:       config_timeout(config),
    encoding:      config_encoding(config),
    azure:         config[:azure],
    contained:     config[:contained]
  ).tap do |client|
    if config[:azure]
      client.execute("SET ANSI_NULLS ON").do
      client.execute("SET ANSI_NULL_DFLT_ON ON").do
      client.execute("SET ANSI_PADDING ON").do
      client.execute("SET ANSI_WARNINGS ON").do
    else
      client.execute("SET ANSI_DEFAULTS ON").do
    end
    client.execute("SET QUOTED_IDENTIFIER ON").do
    client.execute("SET CURSOR_CLOSE_ON_COMMIT OFF").do
    client.execute("SET IMPLICIT_TRANSACTIONS OFF").do
    client.execute("SET TEXTSIZE 2147483647").do
    client.execute("SET CONCAT_NULL_YIELDS_NULL ON").do
  end
rescue TinyTds::Error => e
  raise ActiveRecord::NoDatabaseError if e.message.match(/database .* does not exist/i)
  raise e
end
     | 
  
 
    
      
  
  
    .new_client(config)  ⇒ Object 
  
  
  
  
    
      
62
63
64
65
66
67
68
69
70 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 62
def new_client(config)
  case config[:mode]
  when :dblib
    require "tiny_tds"
    dblib_connect(config)
  else
    raise ArgumentError, "Unknown connection mode in #{config.inspect}."
  end
end
     | 
  
 
    
      
  
  
    .rails_application_name  ⇒ Object 
  
  
  
  
    
      
121
122
123
124
125 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 121
def rails_application_name
  Rails.application.class.name.split("::").first
rescue
  nil end
     | 
  
 
    
   
  
    Instance Method Details
    
      
  
  
    #active?  ⇒ Boolean 
  
  
  
  
    
Abstract Adapter (Connection Management) ================== #
  
 
  
    
      
268
269
270
271
272
273
274
275 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 268
def active?
  return false unless @connection
  raw_connection_do "SELECT 1"
  true
rescue *connection_errors
  false
end 
     | 
  
 
    
      
  
  
    #arel_visitor  ⇒ Object 
  
  
  
  
    
Abstract Adapter ========================================== #
  
 
  
  
    
      
148
149
150 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 148
def arel_visitor
  Arel::Visitors::SQLServer.new self
end 
     | 
  
 
    
      
  
  
    #clear_cache!  ⇒ Object 
  
  
  
  
    
      
294
295
296
297 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 294
def clear_cache!
  @view_information = nil
  super
end 
     | 
  
 
    
      
  
  
    #combine_bind_parameters(from_clause: [], join_clause: [], where_clause: [], having_clause: [], limit: nil, offset: nil)  ⇒ Object 
  
  
  
  
    
      
369
370
371
372
373
374 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 369
def combine_bind_parameters(from_clause: [], join_clause: [], where_clause: [], having_clause: [], limit: nil, offset: nil)
  result = from_clause + join_clause + where_clause + having_clause
  result << offset if offset
  result << limit if limit
  result
end 
     | 
  
 
    
      
  
  
    
      
304
305
306
307
308
309
310 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 304
def configure_connection
  @spid = _raw_select("SELECT @@SPID", fetch: :rows).first.first
  @version_year = version_year
  initialize_dateformatter
  use_database
end
     | 
  
 
    
      
  
  
    #database_prefix  ⇒ Object 
  
  
  
  
    
      
349
350
351 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 349
def database_prefix
  @connection_options[:database_prefix]
end 
     | 
  
 
    
      
  
  
    #database_prefix_identifier(name)  ⇒ Object 
  
  
  
  
    
      
353
354
355
356
357
358
359 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 353
def database_prefix_identifier(name)
  if database_prefix_remote_server?
    SQLServer::Utils.("#{database_prefix}#{name}")
  else
    SQLServer::Utils.(name)
  end
end
     | 
  
 
    
      
  
  
    #database_prefix_remote_server?  ⇒ Boolean 
  
  
  
  
    
      
342
343
344
345
346
347 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 342
def database_prefix_remote_server?
  return false if database_prefix.blank?
  name = SQLServer::Utils.(database_prefix)
  name.fully_qualified? && name.object.blank?
end 
     | 
  
 
    
      
  
  
    #disable_referential_integrity  ⇒ Object 
  
  
  
  
    
      
258
259
260
261
262
263
264 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 258
def disable_referential_integrity
  tables = tables_with_referential_integrity
  tables.each { |t| do_execute "ALTER TABLE #{quote_table_name(t)} NOCHECK CONSTRAINT ALL" }
  yield
ensure
  tables.each { |t| do_execute "ALTER TABLE #{quote_table_name(t)} CHECK CONSTRAINT ALL" }
end
     | 
  
 
    
      
  
  
    #disconnect!  ⇒ Object 
  
  
  
  
    
      
283
284
285
286
287
288
289
290
291
292 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 283
def disconnect!
  super
  case @connection_options[:mode]
  when :dblib
    @connection.close rescue nil
  end
  @connection = nil
  @spid = nil
  @collation = nil
end
     | 
  
 
    
      
  
  
    #get_database_version  ⇒ Object 
  
  
  
  
  
    
      
376
377
378 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 376
def get_database_version   version_year
end 
     | 
  
 
    
      
  
  
    #inspect  ⇒ Object 
  
  
  
  
    
      
365
366
367 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 365
def inspect
  "#<#{self.class} version: #{version}, mode: #{@connection_options[:mode]}, azure: #{sqlserver_azure?.inspect}>"
end
     | 
  
 
    
      
  
  
    #pk_and_sequence_for(table_name)  ⇒ Object 
  
  
  
  
    
      
327
328
329
330 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 327
def pk_and_sequence_for(table_name)
  pk = primary_key(table_name)
  pk ? [pk, nil] : nil
end 
     | 
  
 
    
      
  
  
    #reconnect!  ⇒ Object 
  
  
  
  
    
      
277
278
279
280
281 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 277
def reconnect!
  super
  disconnect!
  connect
end 
     | 
  
 
    
      
  
  
    #reset!  ⇒ Object 
  
  
  
  
    
      
299
300
301
302 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 299
def reset!
  reset_transaction
  do_execute "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
end 
     | 
  
 
    
      
  
  
    #schema_creation  ⇒ Object 
  
  
  
  
    
      
156
157
158 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 156
def schema_creation
  SQLServer::SchemaCreation.new self
end 
     | 
  
 
    
      
  
  
    #sqlserver?  ⇒ Boolean 
  
  
  
  
    
SQLServer Specific (DB Reflection) ======================== #
  
 
  
    
      
334
335
336 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 334
def sqlserver?
  true
end 
     | 
  
 
    
      
  
  
    #sqlserver_azure?  ⇒ Boolean 
  
  
  
  
    
      
338
339
340 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 338
def sqlserver_azure?
  !!(sqlserver_version =~ /Azure/i)
end 
     | 
  
 
    
      
  
  
    #supports_advisory_locks?  ⇒ Boolean 
  
  
  
  
    
      
174
175
176 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 174
def supports_advisory_locks?
  false
end 
     | 
  
 
    
      
  
  
    #supports_bulk_alter?  ⇒ Boolean 
  
  
  
  
    
      
170
171
172 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 170
def supports_bulk_alter?
  false
end 
     | 
  
 
    
      
  
  
    
      
218
219
220 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 218
def 
  false
end 
     | 
  
 
    
      
  
  
    
      
222
223
224 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 222
def 
  false
end 
     | 
  
 
    
      
  
  
    #supports_datetime_with_precision?  ⇒ Boolean 
  
  
  
  
    
      
210
211
212 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 210
def supports_datetime_with_precision?
  true
end 
     | 
  
 
    
      
  
  
    #supports_ddl_transactions?  ⇒ Boolean 
  
  
  
  
    
      
166
167
168 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 166
def supports_ddl_transactions?
  true
end 
     | 
  
 
    
      
  
  
    #supports_explain?  ⇒ Boolean 
  
  
  
  
    
      
190
191
192 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 190
def supports_explain?
  true
end 
     | 
  
 
    
      
  
  
    #supports_expression_index?  ⇒ Boolean 
  
  
  
  
    
      
186
187
188 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 186
def supports_expression_index?
  false
end 
     | 
  
 
    
      
  
  
    #supports_foreign_keys?  ⇒ Boolean 
  
  
  
  
    
      
202
203
204 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 202
def supports_foreign_keys?
  true
end 
     | 
  
 
    
      
  
  
    #supports_in_memory_oltp?  ⇒ Boolean 
  
  
  
  
    
      
238
239
240 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 238
def supports_in_memory_oltp?
  @version_year >= 2014
end 
     | 
  
 
    
      
  
  
    #supports_index_sort_order?  ⇒ Boolean 
  
  
  
  
    
      
178
179
180 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 178
def supports_index_sort_order?
  true
end 
     | 
  
 
    
      
  
  
    #supports_indexes_in_create?  ⇒ Boolean 
  
  
  
  
    
      
198
199
200 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 198
def supports_indexes_in_create?
  false
end 
     | 
  
 
    
      
  
  
    #supports_insert_conflict_target?  ⇒ Boolean 
  
  
  
  
    
      
254
255
256 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 254
def supports_insert_conflict_target?
  false
end 
     | 
  
 
    
      
  
  
    #supports_insert_on_duplicate_skip?  ⇒ Boolean 
  
  
  
  
    
      
246
247
248 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 246
def supports_insert_on_duplicate_skip?
  false
end 
     | 
  
 
    
      
  
  
    #supports_insert_on_duplicate_update?  ⇒ Boolean 
  
  
  
  
    
      
250
251
252 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 250
def supports_insert_on_duplicate_update?
  false
end 
     | 
  
 
    
      
  
  
    #supports_insert_returning?  ⇒ Boolean 
  
  
  
  
    
      
242
243
244 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 242
def supports_insert_returning?
  true
end 
     | 
  
 
    
      
  
  
    #supports_json?  ⇒ Boolean 
  
  
  
  
    
      
214
215
216 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 214
def supports_json?
  @version_year >= 2016
end 
     | 
  
 
    
      
  
  
    #supports_lazy_transactions?  ⇒ Boolean 
  
  
  
  
    
      
234
235
236 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 234
def supports_lazy_transactions?
  true
end 
     | 
  
 
    
      
  
  
    #supports_optimizer_hints?  ⇒ Boolean 
  
  
  
  
    
      
230
231
232 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 230
def supports_optimizer_hints?
  true
end 
     | 
  
 
    
      
  
  
    #supports_partial_index?  ⇒ Boolean 
  
  
  
  
    
      
182
183
184 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 182
def supports_partial_index?
  true
end 
     | 
  
 
    
      
  
  
    #supports_savepoints?  ⇒ Boolean 
  
  
  
  
    
      
226
227
228 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 226
def supports_savepoints?
  true
end 
     | 
  
 
    
      
  
  
    #supports_transaction_isolation?  ⇒ Boolean 
  
  
  
  
    
      
194
195
196 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 194
def supports_transaction_isolation?
  true
end 
     | 
  
 
    
      
  
  
    #supports_views?  ⇒ Boolean 
  
  
  
  
    
      
206
207
208 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 206
def supports_views?
  true
end 
     | 
  
 
    
      
  
  
    #tables_with_referential_integrity  ⇒ Object 
  
  
  
  
    
Abstract Adapter (Misc Support) =========================== #
  
 
  
  
    
      
314
315
316
317
318
319
320
321
322
323
324
325 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 314
def tables_with_referential_integrity
  schemas_and_tables = select_rows <<~SQL.squish
    SELECT DISTINCT s.name, o.name
    FROM sys.foreign_keys i
    INNER JOIN sys.objects o ON i.parent_object_id = o.OBJECT_ID
    INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
  SQL
  schemas_and_tables.map do |schema_table|
    schema, table = schema_table
    "#{SQLServer::Utils.quoted_raw(schema)}.#{SQLServer::Utils.quoted_raw(table)}"
  end
end
     | 
  
 
    
      
  
  
    #valid_type?(type)  ⇒ Boolean 
  
  
  
  
    
      
152
153
154 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 152
def valid_type?(type)
  !native_database_types[type].nil?
end 
     | 
  
 
    
      
  
  
    #version  ⇒ Object 
  
  
  
  
    
      
361
362
363 
     | 
    
      # File 'lib/active_record/connection_adapters/sqlserver_adapter.rb', line 361
def version
  self.class::VERSION
end 
     |