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
- #affected_rows(raw_result) ⇒ Object
- #begin_db_transaction ⇒ Object
- #begin_isolated_db_transaction(isolation) ⇒ Object
-
#build_insert_sql(insert) ⇒ Object
:nodoc:.
- #case_sensitive_comparison(attribute, value) ⇒ Object
- #cast_result(raw_result) ⇒ Object
- #commit_db_transaction ⇒ Object
- #exec_delete(sql, name = nil, binds = []) ⇒ Object
- #exec_rollback_db_transaction ⇒ Object
- #exec_update(sql, name = nil, binds = []) ⇒ Object
-
#execute_procedure(proc_name, *variables) ⇒ Object
SQLServer Specific ======================================== #.
-
#insert_fixtures_set(fixture_set, tables_to_delete = []) ⇒ Object
We should propose this change to Rails team.
- #internal_exec_sql_query(sql, conn) ⇒ Object
- #newid_function ⇒ Object
- #newsequentialid_function ⇒ Object
- #perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch:) ⇒ Object
- #raw_execute(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false, materialize_transactions: true, batch: false) ⇒ Object
- #set_transaction_isolation_level(isolation_level) ⇒ Object
- #transaction_isolation_levels ⇒ Object
- #use_database(database = nil) ⇒ Object
- #user_options ⇒ Object
- #user_options_dateformat ⇒ Object
- #user_options_isolation_level ⇒ Object
- #user_options_language ⇒ Object
- #with_identity_insert_enabled(table_name, conn) ⇒ Object
-
#write_query?(sql) ⇒ Boolean
:nodoc:.
Instance Method Details
#affected_rows(raw_result) ⇒ Object
41 42 43 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 41 def affected_rows(raw_result) raw_result.first['AffectedRows'] end |
#begin_db_transaction ⇒ Object
71 72 73 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 71 def begin_db_transaction internal_execute("BEGIN TRANSACTION", "TRANSACTION", allow_retry: true, materialize_transactions: false) end |
#begin_isolated_db_transaction(isolation) ⇒ Object
79 80 81 82 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 79 def begin_isolated_db_transaction(isolation) set_transaction_isolation_level(transaction_isolation_levels.fetch(isolation)) begin_db_transaction end |
#build_insert_sql(insert) ⇒ Object
:nodoc:
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 144 def build_insert_sql(insert) # :nodoc: sql = +"INSERT #{insert.into}" if returning = insert.send(:insert_all).returning returning_sql = if returning.is_a?(String) returning else Array(returning).map { |column| "INSERTED.#{quote_column_name(column)}" }.join(", ") end sql << " OUTPUT #{returning_sql}" end sql << " #{insert.values_list}" sql end |
#case_sensitive_comparison(attribute, value) ⇒ Object
96 97 98 99 100 101 102 103 104 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 96 def case_sensitive_comparison(attribute, value) column = column_for_attribute(attribute) if column.collation && !column.case_sensitive? attribute.eq(Arel::Nodes::Bin.new(value)) else super end end |
#cast_result(raw_result) ⇒ Object
33 34 35 36 37 38 39 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 33 def cast_result(raw_result) if raw_result.columns.empty? ActiveRecord::Result.empty else ActiveRecord::Result.new(raw_result.columns, raw_result.rows) end end |
#commit_db_transaction ⇒ Object
88 89 90 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 88 def commit_db_transaction internal_execute("COMMIT TRANSACTION", "TRANSACTION", allow_retry: false, materialize_transactions: true) end |
#exec_delete(sql, name = nil, binds = []) ⇒ Object
61 62 63 64 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 61 def exec_delete(sql, name = nil, binds = []) sql = sql.dup << "; SELECT @@ROWCOUNT AS AffectedRows" super(sql, name, binds) end |
#exec_rollback_db_transaction ⇒ Object
92 93 94 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 92 def exec_rollback_db_transaction internal_execute("IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION", "TRANSACTION", allow_retry: false, materialize_transactions: true) end |
#exec_update(sql, name = nil, binds = []) ⇒ Object
66 67 68 69 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 66 def exec_update(sql, name = nil, binds = []) sql = sql.dup << "; SELECT @@ROWCOUNT AS AffectedRows" super(sql, name, binds) end |
#execute_procedure(proc_name, *variables) ⇒ Object
SQLServer Specific ======================================== #
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 162 def execute_procedure(proc_name, *variables) vars = if variables.any? && variables.first.is_a?(Hash) variables.first.map { |k, v| "@#{k} = #{quote(v)}" } else variables.map { |v| quote(v) } end.join(", ") sql = "EXEC #{proc_name} #{vars}".strip log(sql, "Execute Procedure") do |notification_payload| with_raw_connection do |conn| result = internal_raw_execute(sql, conn) verified! = { as: :hash, cache_rows: true, timezone: ActiveRecord.default_timezone || :utc } result.each() do |row| r = row.with_indifferent_access yield(r) if block_given? end result = result.each.map { |row| row.is_a?(Hash) ? row.with_indifferent_access : row } notification_payload[:row_count] = result.count result end end end |
#insert_fixtures_set(fixture_set, tables_to_delete = []) ⇒ Object
We should propose this change to Rails team
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 107 def insert_fixtures_set(fixture_set, tables_to_delete = []) fixture_inserts = [] fixture_set.each do |table_name, fixtures| fixtures.each_slice(insert_rows_length) do |batch| fixture_inserts << build_fixture_sql(batch, table_name) end end table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name table}" } total_sqls = Array.wrap(table_deletes + fixture_inserts) disable_referential_integrity do transaction(requires_new: true) do total_sqls.each do |sql| execute sql, "Fixtures Load" yield if block_given? end end end end |
#internal_exec_sql_query(sql, conn) ⇒ Object
54 55 56 57 58 59 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 54 def internal_exec_sql_query(sql, conn) handle = internal_raw_execute(sql, conn) handle_to_names_and_values(handle, ar_result: true) ensure finish_statement_handle(handle) end |
#newid_function ⇒ Object
254 255 256 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 254 def newid_function select_value "SELECT NEWID()" end |
#newsequentialid_function ⇒ Object
258 259 260 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 258 def newsequentialid_function select_value "SELECT NEWSEQUENTIALID()" end |
#perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch:) ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 16 def perform_query(raw_connection, sql, binds, type_casted_binds, prepare:, notification_payload:, batch:) result = if id_insert_table_name = query_requires_identity_insert?(sql) # If the table name is a view, we need to get the base table name for enabling identity insert. id_insert_table_name = view_table_name(id_insert_table_name) if view_exists?(id_insert_table_name) with_identity_insert_enabled(id_insert_table_name, raw_connection) do internal_exec_sql_query(sql, raw_connection) end else internal_exec_sql_query(sql, raw_connection) end verified! notification_payload[:row_count] = result.count result end |
#raw_execute(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false, materialize_transactions: true, batch: false) ⇒ Object
45 46 47 48 49 50 51 52 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 45 def raw_execute(sql, name = nil, binds = [], prepare: false, async: false, allow_retry: false, materialize_transactions: true, batch: false) unless binds.nil? || binds.empty? types, params = sp_executesql_types_and_parameters(binds) sql = sp_executesql_sql(sql, types, params, name) end super end |
#set_transaction_isolation_level(isolation_level) ⇒ Object
84 85 86 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 84 def set_transaction_isolation_level(isolation_level) internal_execute("SET TRANSACTION ISOLATION LEVEL #{isolation_level}", "TRANSACTION", allow_retry: true, materialize_transactions: false) end |
#transaction_isolation_levels ⇒ Object
75 76 77 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 75 def transaction_isolation_levels super.merge snapshot: "SNAPSHOT" end |
#use_database(database = nil) ⇒ Object
196 197 198 199 200 201 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 196 def use_database(database = nil) return if sqlserver_azure? name = SQLServer::Utils.extract_identifiers(database || @connection_parameters[:database]).quoted execute("USE #{name}", "SCHEMA") unless name.blank? end |
#user_options ⇒ Object
203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 203 def return {} if sqlserver_azure? rows = select_rows("DBCC USEROPTIONS WITH NO_INFOMSGS", "SCHEMA") rows = rows.first if rows.size == 2 && rows.last.empty? rows.reduce(HashWithIndifferentAccess.new) do |values, row| if row.instance_of? Hash set_option = row.values[0].gsub(/\s+/, "_") user_value = row.values[1] elsif row.instance_of? Array set_option = row[0].gsub(/\s+/, "_") user_value = row[1] end values[set_option] = user_value values end end |
#user_options_dateformat ⇒ Object
221 222 223 224 225 226 227 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 221 def if sqlserver_azure? select_value "SELECT [dateformat] FROM [sys].[syslanguages] WHERE [langid] = @@LANGID", "SCHEMA" else ["dateformat"] end end |
#user_options_isolation_level ⇒ Object
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 229 def if sqlserver_azure? sql = %(SELECT CASE [transaction_isolation_level] WHEN 0 THEN NULL WHEN 1 THEN 'READ UNCOMMITTED' WHEN 2 THEN 'READ COMMITTED' WHEN 3 THEN 'REPEATABLE READ' WHEN 4 THEN 'SERIALIZABLE' WHEN 5 THEN 'SNAPSHOT' END AS [isolation_level] FROM [sys].[dm_exec_sessions] WHERE [session_id] = @@SPID).squish select_value sql, "SCHEMA" else ["isolation_level"] end end |
#user_options_language ⇒ Object
246 247 248 249 250 251 252 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 246 def if sqlserver_azure? select_value "SELECT @@LANGUAGE AS [language]", "SCHEMA" else ["language"] end end |
#with_identity_insert_enabled(table_name, conn) ⇒ Object
188 189 190 191 192 193 194 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 188 def with_identity_insert_enabled(table_name, conn) table_name = quote_table_name(table_name) set_identity_insert(table_name, conn, true) yield ensure set_identity_insert(table_name, conn, false) end |
#write_query?(sql) ⇒ Boolean
:nodoc:
10 11 12 13 14 |
# File 'lib/active_record/connection_adapters/sqlserver/database_statements.rb', line 10 def write_query?(sql) # :nodoc: !READ_QUERY.match?(sql) rescue ArgumentError # Invalid encoding !READ_QUERY.match?(sql.b) end |