@@ -59,13 +59,73 @@ class SQLServerAdapter < AbstractAdapter
5959 self . use_output_inserted = true
6060 self . exclude_output_inserted_table_names = Concurrent ::Map . new { false }
6161
62- def initialize ( connection , logger = nil , config = { } )
62+ class << self
63+ def new_client ( config )
64+ case config [ :mode ]
65+ when :dblib
66+ require "tiny_tds"
67+ dblib_connect ( config )
68+ else
69+ raise ArgumentError , "Unknown connection mode in #{ config . inspect } ."
70+ end
71+ end
72+
73+ def dblib_connect ( config )
74+ TinyTds ::Client . new (
75+ dataserver : config [ :dataserver ] ,
76+ host : config [ :host ] ,
77+ port : config [ :port ] ,
78+ username : config [ :username ] ,
79+ password : config [ :password ] ,
80+ database : config [ :database ] ,
81+ tds_version : config [ :tds_version ] || "7.3" ,
82+ appname : config_appname ( config ) ,
83+ login_timeout : config_login_timeout ( config ) ,
84+ timeout : config_timeout ( config ) ,
85+ encoding : config_encoding ( config ) ,
86+ azure : config [ :azure ] ,
87+ contained : config [ :contained ]
88+ ) . tap do |client |
89+ if config [ :azure ]
90+ client . execute ( "SET ANSI_NULLS ON" ) . do
91+ client . execute ( "SET ANSI_NULL_DFLT_ON ON" ) . do
92+ client . execute ( "SET ANSI_PADDING ON" ) . do
93+ client . execute ( "SET ANSI_WARNINGS ON" ) . do
94+ else
95+ client . execute ( "SET ANSI_DEFAULTS ON" ) . do
96+ end
97+ client . execute ( "SET QUOTED_IDENTIFIER ON" ) . do
98+ client . execute ( "SET CURSOR_CLOSE_ON_COMMIT OFF" ) . do
99+ client . execute ( "SET IMPLICIT_TRANSACTIONS OFF" ) . do
100+ client . execute ( "SET TEXTSIZE 2147483647" ) . do
101+ client . execute ( "SET CONCAT_NULL_YIELDS_NULL ON" ) . do
102+ end
103+ rescue TinyTds ::Error => e
104+ raise ActiveRecord ::NoDatabaseError if e . message . match ( /database .* does not exist/i )
105+ raise e
106+ end
107+
108+ def config_appname ( config )
109+ config [ :appname ] || configure_application_name || Rails . application . class . name . split ( "::" ) . first rescue nil
110+ end
111+
112+ def config_login_timeout ( config )
113+ config [ :login_timeout ] . present? ? config [ :login_timeout ] . to_i : nil
114+ end
115+
116+ def config_timeout ( config )
117+ config [ :timeout ] . present? ? config [ :timeout ] . to_i / 1000 : nil
118+ end
119+
120+ def config_encoding ( config )
121+ config [ :encoding ] . present? ? config [ :encoding ] : nil
122+ end
123+ end
124+
125+ def initialize ( connection , logger , _connection_options , config )
63126 super ( connection , logger , config )
64- # Our Responsibility
65127 @connection_options = config
66- connect
67- initialize_dateformatter
68- use_database
128+ configure_connection
69129 end
70130
71131 # === Abstract Adapter ========================================== #
@@ -226,6 +286,14 @@ def reset!
226286 do_execute "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
227287 end
228288
289+ def configure_connection
290+ @spid = _raw_select ( "SELECT @@SPID" , fetch : :rows ) . first . first
291+ @version_year = version_year
292+
293+ initialize_dateformatter
294+ use_database
295+ end
296+
229297 # === Abstract Adapter (Misc Support) =========================== #
230298
231299 def tables_with_referential_integrity
@@ -408,78 +476,18 @@ def translate_exception(e, message:, sql:, binds:)
408476
409477 # === SQLServer Specific (Connection Management) ================ #
410478
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-
422479 def connection_errors
423480 @connection_errors ||= [ ] . tap do |errors |
424481 errors << TinyTds ::Error if defined? ( TinyTds ::Error )
425482 end
426483 end
427484
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-
478485 def configure_application_name ; end
479486
480487 def initialize_dateformatter
481488 @database_dateformat = user_options_dateformat
482489 a , b , c = @database_dateformat . each_char . to_a
490+
483491 [ a , b , c ] . each { |f | f . upcase! if f == "y" }
484492 dateformat = "%#{ a } -%#{ b } -%#{ c } "
485493 ::Date ::DATE_FORMATS [ :_sqlserver_dateformat ] = dateformat
@@ -502,6 +510,13 @@ def version_year
502510 def sqlserver_version
503511 @sqlserver_version ||= _raw_select ( "SELECT @@version" , fetch : :rows ) . first . first . to_s
504512 end
513+
514+ private
515+
516+ def connect
517+ @connection = self . class . new_client ( @connection_options )
518+ configure_connection
519+ end
505520 end
506521 end
507522end
0 commit comments