Module: ActiveRecord::ConnectionAdapters::Sqlserver::DatabaseStatements

Included in:
ActiveRecord::ConnectionAdapters::SQLServerAdapter
Defined in:
lib/active_record/connection_adapters/sqlserver/database_statements.rb

Instance Method Summary collapse

Instance Method Details

#add_limit_offset!(sql, options) ⇒ Object

Raises:

  • (NotImplementedError)


71
72
73
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 71

def add_limit_offset!(sql, options)
  raise NotImplementedError, 'This has been moved to the SQLServerCompiler in Arel.'
end

#begin_db_transactionObject



48
49
50
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 48

def begin_db_transaction
  do_execute "BEGIN TRANSACTION"
end

#case_sensitive_modifier(node) ⇒ Object



79
80
81
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 79

def case_sensitive_modifier(node)
  node.acts_like?(:string) ? Arel::Nodes::Bin.new(node) : node
end

#charsetObject



198
199
200
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 198

def charset
  select_value "SELECT SERVERPROPERTY('SqlCharSetName')"
end

#commit_db_transactionObject



52
53
54
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 52

def commit_db_transaction
  do_execute "COMMIT TRANSACTION"
end

#create_database(database) ⇒ Object



190
191
192
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 190

def create_database(database)
  do_execute "CREATE DATABASE #{quote_table_name(database)}"
end

#create_savepointObject



60
61
62
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 60

def create_savepoint
  do_execute "SAVE TRANSACTION #{current_savepoint_name}"
end

#current_databaseObject



194
195
196
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 194

def current_database
  select_value 'SELECT DB_NAME()'
end

#drop_database(database) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 171

def drop_database(database)
  retry_count = 0
  max_retries = 1
  begin
    do_execute "DROP DATABASE #{quote_table_name(database)}"
  rescue ActiveRecord::StatementInvalid => err
    if err.message =~ /because it is currently in use/i
      raise if retry_count >= max_retries
      retry_count += 1
      remove_database_connections_and_rollback(database)
      retry
    elsif err.message =~ /does not exist/i
      nil
    else
      raise
    end
  end
end

#empty_insert_statement_valueObject



75
76
77
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 75

def empty_insert_statement_value
  "DEFAULT VALUES"
end

#exec_delete(sql, name, binds) ⇒ Object



30
31
32
33
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 30

def exec_delete(sql, name, binds)
  sql << "; SELECT @@ROWCOUNT AS AffectedRows"
  super.rows.first.first
end

#exec_insert(sql, name, binds) ⇒ Object



26
27
28
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 26

def exec_insert(sql, name, binds)
  exec_query sql, name, binds, :insert => true
end

#exec_query(sql, name = 'SQL', binds = [], sqlserver_options = {}) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 18

def exec_query(sql, name = 'SQL', binds = [], sqlserver_options = {})
  if id_insert_table_name = sqlserver_options[:insert] ? query_requires_identity_insert?(sql) : nil
    with_identity_insert_enabled(id_insert_table_name) { do_exec_query(sql, name, binds) }
  else
    do_exec_query(sql, name, binds)
  end
end

#exec_update(sql, name, binds) ⇒ Object



35
36
37
38
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 35

def exec_update(sql, name, binds)
  sql << "; SELECT @@ROWCOUNT AS AffectedRows"
  super.rows.first.first
end

#execute(sql, name = nil) ⇒ Object



10
11
12
13
14
15
16
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 10

def execute(sql, name = nil)
  if id_insert_table_name = query_requires_identity_insert?(sql)
    with_identity_insert_enabled(id_insert_table_name) { do_execute(sql,name) }
  else
    do_execute(sql,name)
  end
end

#execute_procedure(proc_name, *variables) ⇒ Object

SQLServer Specific ======================================== #



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 85

def execute_procedure(proc_name, *variables)
  vars = variables.map{ |v| quote(v) }.join(', ')
  sql = "EXEC #{proc_name} #{vars}".strip
  name = 'Execute Procedure'
  log(sql, name) do
    case @connection_options[:mode]
    when :dblib
      result = @connection.execute(sql)
      result.each(:as => :hash, :cache_rows => true) do |row|
        r = row.with_indifferent_access
        yield(r) if block_given?
      end
      result.each.map{ |row| row.is_a?(Hash) ? row.with_indifferent_access : row }
    when :odbc
      results = []
      raw_connection_run(sql) do |handle|
        get_rows = lambda {
          rows = handle_to_names_and_values handle, :fetch => :all
          rows.each_with_index { |r,i| rows[i] = r.with_indifferent_access }
          results << rows
        }
        get_rows.call
        while handle_more_results?(handle)
          get_rows.call
        end
      end
      results.many? ? results : results.first
    end
  end
end

#newid_functionObject



144
145
146
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 144

def newid_function
  select_value "SELECT NEWID()"
end

#newsequentialid_functionObject



148
149
150
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 148

def newsequentialid_function
  select_value "SELECT NEWSEQUENTIALID()"
end

#outside_transaction?Boolean

Returns:

  • (Boolean)


40
41
42
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 40

def outside_transaction?
  info_schema_query { select_value("SELECT @@TRANCOUNT") == 0 }
end

#recreate_databaseObject

SQLServer Specific (Rake/Test Helpers) ==================== #



154
155
156
157
158
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 154

def recreate_database
  remove_database_connections_and_rollback do
    do_execute "EXEC sp_MSforeachtable 'DROP TABLE ?'"
  end
end

#recreate_database!(database = nil) ⇒ Object



160
161
162
163
164
165
166
167
168
169
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 160

def recreate_database!(database=nil)
  current_db = current_database
  database ||= current_db
  this_db = database.to_s == current_db
  do_execute 'USE master' if this_db
  drop_database(database)
  create_database(database)
ensure
  use_database(current_db) if this_db
end

#release_savepointObject



64
65
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 64

def release_savepoint
end

#rollback_db_transactionObject



56
57
58
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 56

def rollback_db_transaction
  do_execute "ROLLBACK TRANSACTION" rescue nil
end

#rollback_to_savepointObject



67
68
69
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 67

def rollback_to_savepoint
  do_execute "ROLLBACK TRANSACTION #{current_savepoint_name}"
end

#run_with_isolation_level(isolation_level) ⇒ Object

Raises:

  • (ArgumentError)


133
134
135
136
137
138
139
140
141
142
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 133

def run_with_isolation_level(isolation_level)
  raise ArgumentError, "Invalid isolation level, #{isolation_level}. Supported levels include #{valid_isolation_levels.to_sentence}." if !valid_isolation_levels.include?(isolation_level.upcase)
  initial_isolation_level = user_options[:isolation_level] || "READ COMMITTED"
  do_execute "SET TRANSACTION ISOLATION LEVEL #{isolation_level}"
  begin
    yield 
  ensure
    do_execute "SET TRANSACTION ISOLATION LEVEL #{initial_isolation_level}"
  end if block_given?
end

#select_rows(sql, name = nil) ⇒ Object



6
7
8
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 6

def select_rows(sql, name = nil)
  raw_select sql, name, [], :fetch => :rows
end

#supports_statement_cache?Boolean

Returns:

  • (Boolean)


44
45
46
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 44

def supports_statement_cache?
  true
end

#use_database(database = nil) ⇒ Object



116
117
118
119
120
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 116

def use_database(database=nil)
  return if sqlserver_azure?
  database ||= @connection_options[:database]
  do_execute "USE #{quote_table_name(database)}" unless database.blank?
end

#user_optionsObject



122
123
124
125
126
127
128
129
130
131
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 122

def user_options
  info_schema_query do
    select_rows("dbcc useroptions").inject(HashWithIndifferentAccess.new) do |values,row| 
      set_option = row[0].gsub(/\s+/,'_')
      user_value = row[1]
      values[set_option] = user_value
      values
    end
  end
end