module Sequel::MSSQL::DatabaseMethods

Constants

DATABASE_ERROR_REGEXPS
FOREIGN_KEY_ACTION_MAP

Attributes

like_without_collate[RW]

Whether to use LIKE without COLLATE Latin1_General_CS_AS. Skipping the COLLATE can significantly increase performance in some cases.

mssql_unicode_strings[RW]

Whether to use N” to quote strings, which allows unicode characters inside the strings. True by default for compatibility, can be set to false for a possible performance increase. This sets the default for all datasets created from this Database object.

Public Instance Methods

call_mssql_sproc(name, opts=OPTS) click to toggle source

Execute the given stored procedure with the given name.

Options:

:args

Arguments to stored procedure. For named arguments, this should be a hash keyed by argument name. For unnamed arguments, this should be an array. Output parameters to the function are specified using :output. You can also name output parameters and provide a type by using an array containing :output, the type name, and the parameter name.

:server

The server/shard on which to execute the procedure.

This method returns a single hash with the following keys:

:result

The result code of the stored procedure

:numrows

The number of rows affected by the stored procedure

output params

Values for any output paramters, using the name given for the output parameter

Because Sequel datasets only support a single result set per query, and retrieving the result code and number of rows requires a query, this does not support stored procedures which also return result sets. To handle such stored procedures, you should drop down to the connection/driver level by using Sequel::Database#synchronize to get access to the underlying connection object.

Examples:

DB.call_mssql_sproc(:SequelTest, {args: ['input arg', :output]})
DB.call_mssql_sproc(:SequelTest, {args: ['input arg', [:output, 'int', 'varname']]})

named params:
DB.call_mssql_sproc(:SequelTest, args: {
  'input_arg1_name' => 'input arg1 value',
  'input_arg2_name' => 'input arg2 value',
  'output_arg_name' => [:output, 'int', 'varname']
})
    # File lib/sequel/adapters/shared/mssql.rb
 64 def call_mssql_sproc(name, opts=OPTS)
 65   args = opts[:args] || []
 66   names = ['@RC AS RESULT', '@@ROWCOUNT AS NUMROWS']
 67   declarations = ['@RC int']
 68   values = []
 69 
 70   if args.is_a?(Hash)
 71     named_args = true
 72     args = args.to_a
 73     method = :each
 74   else
 75     method = :each_with_index
 76   end
 77 
 78   args.public_send(method) do |v, i|
 79     if named_args
 80       k = v
 81       v, type, select = i
 82       raise Error, "must provide output parameter name when using output parameters with named arguments" if v == :output && !select
 83     else
 84       v, type, select = v
 85     end
 86 
 87     if v == :output
 88       type ||= "nvarchar(max)"
 89       if named_args
 90         varname = select
 91       else
 92         varname = "var#{i}"
 93         select ||= varname
 94       end
 95       names << "@#{varname} AS #{quote_identifier(select)}"
 96       declarations << "@#{varname} #{type}"
 97       value = "@#{varname} OUTPUT"
 98     else
 99       value = literal(v)
100     end
101 
102     if named_args
103       value = "@#{k}=#{value}"
104     end
105 
106     values << value
107   end
108 
109   sql = "DECLARE #{declarations.join(', ')}; EXECUTE @RC = #{name} #{values.join(', ')}; SELECT #{names.join(', ')}"
110 
111   ds = dataset.with_sql(sql)
112   ds = ds.server(opts[:server]) if opts[:server]
113   ds.first
114 end
database_type() click to toggle source
    # File lib/sequel/adapters/shared/mssql.rb
116 def database_type
117   :mssql
118 end
foreign_key_list(table, opts=OPTS) click to toggle source

Return foreign key information using the system views, including :name, :on_delete, and :on_update entries in the hashes.

    # File lib/sequel/adapters/shared/mssql.rb
127 def foreign_key_list(table, opts=OPTS)
128   m = output_identifier_meth
129   im = input_identifier_meth
130   schema, table = schema_and_table(table)
131   current_schema = m.call(get(Sequel.function('schema_name')))
132   fk_action_map = FOREIGN_KEY_ACTION_MAP
133   fk = Sequel[:fk]
134   fkc = Sequel[:fkc]
135   ds = metadata_dataset.from(Sequel.lit('[sys].[foreign_keys]').as(:fk)).
136     join(Sequel.lit('[sys].[foreign_key_columns]').as(:fkc), :constraint_object_id => :object_id).
137     join(Sequel.lit('[sys].[all_columns]').as(:pc), :object_id => fkc[:parent_object_id],     :column_id => fkc[:parent_column_id]).
138     join(Sequel.lit('[sys].[all_columns]').as(:rc), :object_id => fkc[:referenced_object_id], :column_id => fkc[:referenced_column_id]).
139     where{{object_schema_name(fk[:parent_object_id]) => im.call(schema || current_schema)}}.
140     where{{object_name(fk[:parent_object_id]) => im.call(table)}}.
141     select{[fk[:name], 
142             fk[:delete_referential_action], 
143             fk[:update_referential_action], 
144             pc[:name].as(:column), 
145             rc[:name].as(:referenced_column), 
146             object_schema_name(fk[:referenced_object_id]).as(:schema), 
147             object_name(fk[:referenced_object_id]).as(:table)]}.
148     order(fk[:name], fkc[:constraint_column_id])
149   h = {}
150   ds.each do |row|
151     if r = h[row[:name]]
152       r[:columns] << m.call(row[:column])
153       r[:key] << m.call(row[:referenced_column])
154     else
155       referenced_schema = m.call(row[:schema])
156       referenced_table = m.call(row[:table])
157       h[row[:name]] = { :name      => m.call(row[:name]), 
158                         :table     => (referenced_schema == current_schema) ? referenced_table : Sequel.qualify(referenced_schema, referenced_table),
159                         :columns   => [m.call(row[:column])], 
160                         :key       => [m.call(row[:referenced_column])], 
161                         :on_update => fk_action_map[row[:update_referential_action]], 
162                         :on_delete => fk_action_map[row[:delete_referential_action]] }
163     end
164   end
165   h.values
166 end
freeze() click to toggle source
Calls superclass method
    # File lib/sequel/adapters/shared/mssql.rb
168 def freeze
169   server_version
170   super
171 end
global_index_namespace?() click to toggle source

Microsoft SQL Server namespaces indexes per table.

    # File lib/sequel/adapters/shared/mssql.rb
121 def global_index_namespace?
122   false
123 end
indexes(table, opts=OPTS) click to toggle source

Use the system tables to get index information

    # File lib/sequel/adapters/shared/mssql.rb
174 def indexes(table, opts=OPTS)
175   m = output_identifier_meth
176   im = input_identifier_meth
177   indexes = {}
178   table = table.value if table.is_a?(Sequel::SQL::Identifier)
179   i = Sequel[:i]
180   ds = metadata_dataset.from(Sequel.lit('[sys].[tables]').as(:t)).
181    join(Sequel.lit('[sys].[indexes]').as(:i), :object_id=>:object_id).
182    join(Sequel.lit('[sys].[index_columns]').as(:ic), :object_id=>:object_id, :index_id=>:index_id).
183    join(Sequel.lit('[sys].[columns]').as(:c), :object_id=>:object_id, :column_id=>:column_id).
184    select(i[:name], i[:is_unique], Sequel[:c][:name].as(:column)).
185    where{{t[:name]=>im.call(table)}}.
186    where(i[:is_primary_key]=>0, i[:is_disabled]=>0).
187    order(i[:name], Sequel[:ic][:index_column_id])
188 
189   if supports_partial_indexes?
190     ds = ds.where(i[:has_filter]=>0)
191   end
192 
193   ds.each do |r|
194     index = indexes[m.call(r[:name])] ||= {:columns=>[], :unique=>(r[:is_unique] && r[:is_unique]!=0)}
195     index[:columns] << m.call(r[:column])
196   end
197   indexes
198 end
server_version(server=nil) click to toggle source

The version of the MSSQL server, as an integer (e.g. 10001600 for SQL Server 2008 Express).

    # File lib/sequel/adapters/shared/mssql.rb
202 def server_version(server=nil)
203   return @server_version if @server_version
204   if @opts[:server_version]
205     return @server_version = Integer(@opts[:server_version])
206   end
207   @server_version = synchronize(server) do |conn|
208     (conn.server_version rescue nil) if conn.respond_to?(:server_version)
209   end
210   unless @server_version
211     m = /^(\d+)\.(\d+)\.(\d+)/.match(fetch("SELECT CAST(SERVERPROPERTY('ProductVersion') AS varchar)").single_value.to_s)
212     @server_version = (m[1].to_i * 1000000) + (m[2].to_i * 10000) + m[3].to_i
213   end
214   @server_version
215 end
supports_partial_indexes?() click to toggle source

MSSQL 2008+ supports partial indexes.

    # File lib/sequel/adapters/shared/mssql.rb
218 def supports_partial_indexes?
219   dataset.send(:is_2008_or_later?)
220 end
supports_savepoints?() click to toggle source

MSSQL supports savepoints, though it doesn’t support releasing them

    # File lib/sequel/adapters/shared/mssql.rb
223 def supports_savepoints?
224   true
225 end
supports_transaction_isolation_levels?() click to toggle source

MSSQL supports transaction isolation levels

    # File lib/sequel/adapters/shared/mssql.rb
228 def supports_transaction_isolation_levels?
229   true
230 end
supports_transactional_ddl?() click to toggle source

MSSQL supports transaction DDL statements.

    # File lib/sequel/adapters/shared/mssql.rb
233 def supports_transactional_ddl?
234   true
235 end
tables(opts=OPTS) click to toggle source

Microsoft SQL Server supports using the INFORMATION_SCHEMA to get information on tables.

    # File lib/sequel/adapters/shared/mssql.rb
239 def tables(opts=OPTS)
240   information_schema_tables('BASE TABLE', opts)
241 end
views(opts=OPTS) click to toggle source

Microsoft SQL Server supports using the INFORMATION_SCHEMA to get information on views.

    # File lib/sequel/adapters/shared/mssql.rb
245 def views(opts=OPTS)
246   information_schema_tables('VIEW', opts)
247 end
with_advisory_lock(lock_id, opts=OPTS) { || ... } click to toggle source

Attempt to acquire an exclusive advisory lock with the given lock_id (which will be converted to a string). If successful, yield to the block, then release the advisory lock when the block exits. If unsuccessful, raise a Sequel::AdvisoryLockError.

Options:

:wait

Do not raise an error, instead, wait until the advisory lock can be acquired.

    # File lib/sequel/adapters/shared/mssql.rb
255 def with_advisory_lock(lock_id, opts=OPTS)
256   lock_id = lock_id.to_s
257   timeout = opts[:wait] ? -1 : 0
258   server = opts[:server]
259 
260   synchronize(server) do
261     begin
262       res = call_mssql_sproc(:sp_getapplock, :server=>server, :args=>{'Resource'=>lock_id, 'LockTimeout'=>timeout, 'LockMode'=>'Exclusive', 'LockOwner'=>'Session'})
263 
264       unless locked = res[:result] >= 0
265           raise AdvisoryLockError, "unable to acquire advisory lock #{lock_id.inspect}"
266       end
267 
268       yield
269     ensure
270       if locked
271         call_mssql_sproc(:sp_releaseapplock, :server=>server, :args=>{'Resource'=>lock_id, 'LockOwner'=>'Session'})
272       end
273     end
274   end
275 end

Private Instance Methods

_metadata_dataset() click to toggle source

Always quote identifiers in the metadata_dataset, so schema parsing works.

Calls superclass method
    # File lib/sequel/adapters/shared/mssql.rb
459 def _metadata_dataset
460   super.with_quote_identifiers(true)
461 end
add_clustered_sql_fragment(sql, opts) click to toggle source

Add CLUSTERED or NONCLUSTERED as needed

    # File lib/sequel/adapters/shared/mssql.rb
280 def add_clustered_sql_fragment(sql, opts)
281   clustered = opts[:clustered]
282   unless clustered.nil?
283     sql += " #{'NON' unless clustered}CLUSTERED"
284   end
285 
286   sql
287 end
add_drop_default_constraint_sql(sqls, table, column) click to toggle source

Add dropping of the default constraint to the list of SQL queries. This is necessary before dropping the column or changing its type.

    # File lib/sequel/adapters/shared/mssql.rb
291 def add_drop_default_constraint_sql(sqls, table, column)
292   if constraint = default_constraint_name(table, column)
293     sqls << "ALTER TABLE #{quote_schema_table(table)} DROP CONSTRAINT #{constraint}"
294   end
295 end
alter_table_sql(table, op) click to toggle source
Calls superclass method
    # File lib/sequel/adapters/shared/mssql.rb
302 def alter_table_sql(table, op)
303   case op[:op]
304   when :add_column
305     "ALTER TABLE #{quote_schema_table(table)} ADD #{column_definition_sql(op)}"
306   when :drop_column
307     sqls = []
308     add_drop_default_constraint_sql(sqls, table, op[:name])
309     sqls << super
310   when :rename_column
311     "sp_rename #{literal("#{quote_schema_table(table)}.#{quote_identifier(op[:name])}")}, #{literal(metadata_dataset.with_quote_identifiers(false).quote_identifier(op[:new_name]))}, 'COLUMN'"
312   when :set_column_type
313     sqls = []
314     if sch = schema(table)
315       if cs = sch.each{|k, v| break v if k == op[:name]; nil}
316         cs = cs.dup
317         add_drop_default_constraint_sql(sqls, table, op[:name])
318         cs[:default] = cs[:ruby_default]
319         op = cs.merge!(op)
320         default = op.delete(:default)
321       end
322     end
323     sqls << "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{column_definition_sql(op)}"
324     sqls << alter_table_sql(table, op.merge(:op=>:set_column_default, :default=>default, :skip_drop_default=>true)) if default
325     sqls
326   when :set_column_null
327     sch = schema(table).find{|k,v| k.to_s == op[:name].to_s}.last
328     type = sch[:db_type]
329     if [:string, :decimal, :blob].include?(sch[:type]) && !["text", "ntext"].include?(type) && (size = (sch[:max_chars] || sch[:column_size]))
330       size = "MAX" if size == -1
331       type += "(#{size}#{", #{sch[:scale]}" if sch[:scale] && sch[:scale].to_i > 0})"
332     end
333     "ALTER TABLE #{quote_schema_table(table)} ALTER COLUMN #{quote_identifier(op[:name])} #{type_literal(:type=>type)} #{'NOT ' unless op[:null]}NULL"
334   when :set_column_default
335     sqls = []
336     add_drop_default_constraint_sql(sqls, table, op[:name]) unless op[:skip_drop_default]
337     sqls << "ALTER TABLE #{quote_schema_table(table)} ADD CONSTRAINT #{quote_identifier("sequel_#{table}_#{op[:name]}_def")} DEFAULT #{literal(op[:default])} FOR #{quote_identifier(op[:name])}"
338   else
339     super(table, op)
340   end
341 end
auto_increment_sql() click to toggle source

MSSQL uses the IDENTITY(1,1) column for autoincrementing columns.

    # File lib/sequel/adapters/shared/mssql.rb
298 def auto_increment_sql
299   'IDENTITY(1,1)'
300 end
begin_savepoint_sql(depth) click to toggle source
    # File lib/sequel/adapters/shared/mssql.rb
343 def begin_savepoint_sql(depth)
344   "SAVE TRANSACTION autopoint_#{depth}"
345 end
begin_transaction_sql() click to toggle source
    # File lib/sequel/adapters/shared/mssql.rb
347 def begin_transaction_sql
348   "BEGIN TRANSACTION"
349 end
can_add_primary_key_constraint_on_nullable_columns?() click to toggle source

MSSQL does not allow adding primary key constraints to NULLable columns.

    # File lib/sequel/adapters/shared/mssql.rb
352 def can_add_primary_key_constraint_on_nullable_columns?
353   false
354 end
column_schema_normalize_default(default, type) click to toggle source

Handle MSSQL specific default format.

Calls superclass method
    # File lib/sequel/adapters/shared/mssql.rb
362 def column_schema_normalize_default(default, type)
363   if m = /\A(?:\(N?('.*')\)|\(\((-?\d+(?:\.\d+)?)\)\))\z/.match(default)
364     default = m[1] || m[2]
365   end
366   super(default, type)
367 end
column_schema_tinyint_type_is_unsigned?() click to toggle source

MSSQL tinyint types are unsigned.

    # File lib/sequel/adapters/shared/mssql.rb
357 def column_schema_tinyint_type_is_unsigned?
358   true
359 end
commit_transaction(conn, opts=OPTS) click to toggle source

Commit the active transaction on the connection, does not release savepoints.

    # File lib/sequel/adapters/shared/mssql.rb
370 def commit_transaction(conn, opts=OPTS)
371   log_connection_execute(conn, commit_transaction_sql) unless savepoint_level(conn) > 1
372 end
commit_transaction_sql() click to toggle source
    # File lib/sequel/adapters/shared/mssql.rb
374 def commit_transaction_sql
375   "COMMIT TRANSACTION"
376 end
create_table_as(name, ds, options) click to toggle source

MSSQL doesn’t support CREATE TABLE AS, it only supports SELECT INTO. Emulating CREATE TABLE AS using SELECT INTO is only possible if a dataset is given as the argument, it can’t work with a string, so raise an Error if a string is given.

    # File lib/sequel/adapters/shared/mssql.rb
401 def create_table_as(name, ds, options)
402   raise(Error, "must provide dataset instance as value of create_table :as option on MSSQL") unless ds.is_a?(Sequel::Dataset)
403   run(ds.into(name).sql)
404 end
create_table_prefix_sql(name, options) click to toggle source

MSSQL uses the name of the table to decide the difference between a regular and temporary table, with temporary table names starting with a #.

    # File lib/sequel/adapters/shared/mssql.rb
381 def create_table_prefix_sql(name, options)
382   "CREATE TABLE #{create_table_table_name_sql(name, options)}"
383 end
create_table_temp_table_name_sql(name, _options) click to toggle source

The SQL to use for the table name for a temporary table.

    # File lib/sequel/adapters/shared/mssql.rb
386 def create_table_temp_table_name_sql(name, _options)
387   case name
388   when String, Symbol
389     "##{name}"
390   when SQL::Identifier
391     "##{name.value}"
392   else
393     raise Error, "temporary table names must be strings, symbols, or Sequel::SQL::Identifier instances on Microsoft SQL Server"
394   end
395 end
database_error_regexps() click to toggle source
    # File lib/sequel/adapters/shared/mssql.rb
414 def database_error_regexps
415   DATABASE_ERROR_REGEXPS
416 end
default_constraint_name(table, column_name) click to toggle source

The name of the constraint for setting the default value on the table and column. The SQL used to select default constraints utilizes MSSQL catalog views which were introduced in 2005. This method intentionally does not support MSSQL 2000.

    # File lib/sequel/adapters/shared/mssql.rb
421 def default_constraint_name(table, column_name)
422   if server_version >= 9000000
423     table_name = schema_and_table(table).compact.join('.')
424     self[Sequel[:sys][:default_constraints]].
425       where{{:parent_object_id => Sequel::SQL::Function.new(:object_id, table_name), col_name(:parent_object_id, :parent_column_id) => column_name.to_s}}.
426       get(:name)
427   end
428 end
drop_index_sql(table, op) click to toggle source
    # File lib/sequel/adapters/shared/mssql.rb
430 def drop_index_sql(table, op)
431   "DROP INDEX #{quote_identifier(op[:name] || default_index_name(table, op[:columns]))} ON #{quote_schema_table(table)}"
432 end
index_definition_sql(table_name, index) click to toggle source
    # File lib/sequel/adapters/shared/mssql.rb
434 def index_definition_sql(table_name, index)
435   index_name = index[:name] || default_index_name(table_name, index[:columns])
436   raise Error, "Partial indexes are not supported for this database" if index[:where] && !supports_partial_indexes?
437   if index[:type] == :full_text
438     "CREATE FULLTEXT INDEX ON #{quote_schema_table(table_name)} #{literal(index[:columns])} KEY INDEX #{literal(index[:key_index])}"
439   else
440     "CREATE #{'UNIQUE ' if index[:unique]}#{'CLUSTERED ' if index[:type] == :clustered}INDEX #{quote_identifier(index_name)} ON #{quote_schema_table(table_name)} #{literal(index[:columns])}#{" INCLUDE #{literal(index[:include])}" if index[:include]}#{" WHERE #{filter_expr(index[:where])}" if index[:where]}"
441   end
442 end
information_schema_tables(type, opts) click to toggle source

Backbone of the tables and views support.

    # File lib/sequel/adapters/shared/mssql.rb
445 def information_schema_tables(type, opts)
446   m = output_identifier_meth
447   schema = opts[:schema]||'dbo'
448   tables = metadata_dataset.from(Sequel[:information_schema][:tables].as(:t)).
449     select(:table_name).
450     where(:table_type=>type, :table_schema=>schema.to_s).
451     map{|x| m.call(x[:table_name])}
452 
453   tables.map!{|t| Sequel.qualify(m.call(schema).to_s, m.call(t).to_s)} if opts[:qualify]
454 
455   tables
456 end
primary_key_constraint_sql_fragment(opts) click to toggle source

Handle clustered and nonclustered primary keys

Calls superclass method
    # File lib/sequel/adapters/shared/mssql.rb
464 def primary_key_constraint_sql_fragment(opts)
465   add_clustered_sql_fragment(super, opts)
466 end
rename_table_sql(name, new_name) click to toggle source

Use sp_rename to rename the table

    # File lib/sequel/adapters/shared/mssql.rb
469 def rename_table_sql(name, new_name)
470   "sp_rename #{literal(quote_schema_table(name))}, #{quote_identifier(schema_and_table(new_name).pop)}"
471 end
rollback_savepoint_sql(depth) click to toggle source
    # File lib/sequel/adapters/shared/mssql.rb
473 def rollback_savepoint_sql(depth)
474   "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION autopoint_#{depth}"
475 end
rollback_transaction_sql() click to toggle source
    # File lib/sequel/adapters/shared/mssql.rb
477 def rollback_transaction_sql
478   "IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION"
479 end
schema_column_type(db_type) click to toggle source
Calls superclass method
    # File lib/sequel/adapters/shared/mssql.rb
481 def schema_column_type(db_type)
482   case db_type
483   when /\A(?:bit)\z/io
484     :boolean
485   when /\A(?:(?:small)?money)\z/io
486     :decimal
487   when /\A(timestamp|rowversion)\z/io
488     :blob
489   else
490     super
491   end
492 end
schema_parse_table(table_name, opts) click to toggle source

MSSQL uses the INFORMATION_SCHEMA to hold column information, and parses primary key information from the sysindexes, sysindexkeys, and syscolumns system tables.

    # File lib/sequel/adapters/shared/mssql.rb
497 def schema_parse_table(table_name, opts)
498   m = output_identifier_meth(opts[:dataset])
499   m2 = input_identifier_meth(opts[:dataset])
500   tn = m2.call(table_name.to_s)
501   info_sch_sch = opts[:information_schema_schema]
502   inf_sch_qual = lambda{|s| info_sch_sch ? Sequel.qualify(info_sch_sch, s) : Sequel[s]}
503   table_id = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:objects])).where(:name => tn).select_map(:object_id).first
504 
505   identity_cols = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:columns])).
506     where(:object_id=>table_id, :is_identity=>true).
507     select_map(:name)
508 
509   pk_index_id = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:sysindexes])).
510     where(:id=>table_id, :indid=>1..254){{(status & 2048)=>2048}}.
511     get(:indid)
512   pk_cols = metadata_dataset.from(inf_sch_qual.call(Sequel[:sys][:sysindexkeys]).as(:sik)).
513     join(inf_sch_qual.call(Sequel[:sys][:syscolumns]).as(:sc), :id=>:id, :colid=>:colid).
514     where{{sik[:id]=>table_id, sik[:indid]=>pk_index_id}}.
515     select_order_map{sc[:name]}
516 
517   ds = metadata_dataset.from(inf_sch_qual.call(Sequel[:information_schema][:tables]).as(:t)).
518    join(inf_sch_qual.call(Sequel[:information_schema][:columns]).as(:c), :table_catalog=>:table_catalog,
519         :table_schema => :table_schema, :table_name => :table_name).
520    select{[column_name.as(:column), data_type.as(:db_type), character_maximum_length.as(:max_chars), column_default.as(:default), is_nullable.as(:allow_null), numeric_precision.as(:column_size), numeric_scale.as(:scale)]}.
521    where{{c[:table_name]=>tn}}
522 
523   if schema = opts[:schema]
524     ds = ds.where{{c[:table_schema]=>schema}}
525   end
526 
527   ds.map do |row|
528     if row[:primary_key] = pk_cols.include?(row[:column])
529       row[:auto_increment] = identity_cols.include?(row[:column])
530     end
531     row[:allow_null] = row[:allow_null] == 'YES' ? true : false
532     row[:default] = nil if blank_object?(row[:default])
533     row[:type] = if row[:db_type] =~ /number|numeric|decimal/i && row[:scale] == 0
534       :integer
535     else
536       schema_column_type(row[:db_type])
537     end
538     row[:max_length] = row[:max_chars] if row[:type] == :string && row[:max_chars] >= 0
539     [m.call(row.delete(:column)), row]
540   end
541 end
set_mssql_unicode_strings() click to toggle source

Set the mssql_unicode_strings settings from the given options.

    # File lib/sequel/adapters/shared/mssql.rb
544 def set_mssql_unicode_strings
545   @mssql_unicode_strings = typecast_value_boolean(@opts.fetch(:mssql_unicode_strings, true))
546 end
type_literal_generic_datetime(column) click to toggle source

MSSQL has both datetime and timestamp classes, most people are going to want datetime

    # File lib/sequel/adapters/shared/mssql.rb
550 def type_literal_generic_datetime(column)
551   :datetime
552 end
type_literal_generic_file(column) click to toggle source

MSSQL uses varbinary(max) type for blobs

    # File lib/sequel/adapters/shared/mssql.rb
560 def type_literal_generic_file(column)
561   :'varbinary(max)'
562 end
type_literal_generic_trueclass(column) click to toggle source

MSSQL doesn’t have a true boolean class, so it uses bit

    # File lib/sequel/adapters/shared/mssql.rb
555 def type_literal_generic_trueclass(column)
556   :bit
557 end
unique_constraint_sql_fragment(opts) click to toggle source

Handle clustered and nonclustered unique constraints

Calls superclass method
    # File lib/sequel/adapters/shared/mssql.rb
565 def unique_constraint_sql_fragment(opts)
566   add_clustered_sql_fragment(super, opts)
567 end
view_with_check_option_support() click to toggle source

MSSQL supports views with check option, but not local.

    # File lib/sequel/adapters/shared/mssql.rb
570 def view_with_check_option_support
571   true
572 end