class Sequel::TinyTDS::Database
Public Instance Methods
Transfer the :user option to the :username option.
# File lib/sequel/adapters/tinytds.rb 13 def connect(server) 14 opts = server_opts(server) 15 opts[:username] = opts[:user] 16 c = TinyTds::Client.new(opts) 17 c.query_options.merge!(:cache_rows=>false) 18 19 # SEQUEL6: Default to ansi: true 20 if opts[:ansi] 21 sql = %w( 22 ANSI_NULLS 23 ANSI_PADDING 24 ANSI_WARNINGS 25 ANSI_NULL_DFLT_ON 26 QUOTED_IDENTIFIER 27 CONCAT_NULL_YIELDS_NULL 28 ).map{|v| "SET #{v} ON"}.join(";") 29 log_connection_yield(sql, c){c.execute(sql)} 30 end 31 32 if (ts = opts[:textsize]) 33 sql = "SET TEXTSIZE #{typecast_value_integer(ts)}" 34 log_connection_yield(sql, c){c.execute(sql)} 35 end 36 37 c 38 end
Execute the given sql
on the server. If the :return option is present, its value should be a method symbol that is called on the TinyTds::Result object returned from executing the sql
. The value of such a method is returned to the caller. Otherwise, if a block is given, it is yielded the result object. If no block is given and a :return is not present, nil
is returned.
# File lib/sequel/adapters/tinytds.rb 46 def execute(sql, opts=OPTS) 47 synchronize(opts[:server]) do |c| 48 begin 49 m = opts[:return] 50 r = nil 51 if (args = opts[:arguments]) && !args.empty? 52 types = [] 53 values = [] 54 args.each_with_index do |(k, v), i| 55 v, type = ps_arg_type(v) 56 types << "@#{k} #{type}" 57 values << "@#{k} = #{v}" 58 end 59 case m 60 when :do 61 sql = "#{sql}; SELECT @@ROWCOUNT AS AffectedRows" 62 single_value = true 63 when :insert 64 sql = "#{sql}; SELECT CAST(SCOPE_IDENTITY() AS bigint) AS Ident" 65 single_value = true 66 end 67 sql = "EXEC sp_executesql N'#{c.escape(sql)}', N'#{c.escape(types.join(', '))}', #{values.join(', ')}" 68 log_connection_yield(sql, c) do 69 r = c.execute(sql) 70 r.each{|row| return row.values.first} if single_value 71 end 72 else 73 log_connection_yield(sql, c) do 74 r = c.execute(sql) 75 return r.public_send(m) if m 76 end 77 end 78 yield(r) if defined?(yield) 79 rescue TinyTds::Error => e 80 raise_error(e, :disconnect=>!c.active?) 81 ensure 82 r.cancel if r && c.sqlsent? && c.active? 83 end 84 end 85 end
# File lib/sequel/adapters/tinytds.rb 99 def execute_ddl(sql, opts=OPTS) 100 opts = Hash[opts] 101 opts[:return] = :each 102 execute(sql, opts) 103 nil 104 end
# File lib/sequel/adapters/tinytds.rb 87 def execute_dui(sql, opts=OPTS) 88 opts = Hash[opts] 89 opts[:return] = :do 90 execute(sql, opts) 91 end
# File lib/sequel/adapters/tinytds.rb 93 def execute_insert(sql, opts=OPTS) 94 opts = Hash[opts] 95 opts[:return] = :insert 96 execute(sql, opts) 97 end
Private Instance Methods
Choose whether to use unicode strings on initialization
# File lib/sequel/adapters/tinytds.rb 109 def adapter_initialize 110 set_mssql_unicode_strings 111 end
For some reason, unless you specify a column can be NULL, it assumes NOT NULL, so turn NULL on by default unless the column is a primary key column.
Sequel::Database#column_list_sql
# File lib/sequel/adapters/tinytds.rb 116 def column_list_sql(g) 117 pks = [] 118 g.constraints.each{|c| pks = c[:columns] if c[:type] == :primary_key} 119 g.columns.each{|c| c[:null] = true if !pks.include?(c[:name]) && !c[:primary_key] && !c.has_key?(:null) && !c.has_key?(:allow_null)} 120 super 121 end
tiny_tds uses TinyTds::Error as the base error class.
# File lib/sequel/adapters/tinytds.rb 124 def database_error_classes 125 [TinyTds::Error] 126 end
Stupid MSSQL
maps foreign key and check constraint violations to the same error code, and doesn’t expose the sqlstate. Use database error numbers if present and unambiguous, otherwise fallback to the regexp mapping.
Sequel::Database#database_specific_error_class
# File lib/sequel/adapters/tinytds.rb 132 def database_specific_error_class(exception, opts) 133 case exception.db_error_number 134 when 515 135 NotNullConstraintViolation 136 when 2627 137 UniqueConstraintViolation 138 else 139 super 140 end 141 end
# File lib/sequel/adapters/tinytds.rb 143 def dataset_class_default 144 Dataset 145 end
Return true if the :conn argument is present and not active.
Sequel::Database#disconnect_error?
# File lib/sequel/adapters/tinytds.rb 148 def disconnect_error?(e, opts) 149 super || (opts[:conn] && !opts[:conn].active?) || ((e.is_a?(::TinyTds::Error) && /\A(Attempt to initiate a new Adaptive Server operation with results pending|The request failed to run because the batch is aborted, this can be caused by abort signal sent from client|Adaptive Server connection timed out|DBPROCESS is dead or not enabled)/.match(e.message))) 150 end
Dispose of any possible results of execution.
# File lib/sequel/adapters/tinytds.rb 153 def log_connection_execute(conn, sql) 154 log_connection_yield(sql, conn){conn.execute(sql).each} 155 end
Return a 2 element array with the literal value and type to use in the prepared statement call for the given value and connection.
# File lib/sequel/adapters/tinytds.rb 159 def ps_arg_type(v) 160 case v 161 when Integer 162 [v, 'bigint'] 163 when Float 164 [v, 'double precision'] 165 when Numeric 166 [v, 'numeric'] 167 when Time 168 if v.is_a?(SQLTime) 169 [literal(v), 'time'] 170 else 171 [literal(v), 'datetime'] 172 end 173 when DateTime 174 [literal(v), 'datetime'] 175 when Date 176 [literal(v), 'date'] 177 when nil 178 ['NULL', 'nvarchar(max)'] 179 when true 180 ['1', 'int'] 181 when false 182 ['0', 'int'] 183 when SQL::Blob 184 [literal(v), 'varbinary(max)'] 185 else 186 [literal(v), 'nvarchar(max)'] 187 end 188 end