module ActiveRecord::ConnectionAdapters::SQLServer::JDBCOverrides
Public Instance Methods
@Override Needed to reapply this since the jdbc abstract versions don't do the check and end up overriding the sqlserver gem's version
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 9 def exec_insert(sql, name, binds, pk = nil, _sequence_name = nil) if id_insert_table_name = exec_insert_requires_identity?(sql, pk, binds) with_identity_insert_enabled(id_insert_table_name) { super } else super end end
@Override Needed to reapply this since the jdbc abstract versions don't do the check and end up overriding the sqlserver gem's version
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 20 def execute(sql, name = nil) if id_insert_table_name = query_requires_identity_insert?(sql) with_identity_insert_enabled(id_insert_table_name) { super } else super end end
TODO Move to java for potential perf boost
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 29 def execute_procedure(proc_name, *variables, &block) 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 result = @connection.execute(sql) return [] unless result if result.is_a?(Array) result.map! do |res| process_execute_procedure_result(res, &block) end else result = process_execute_procedure_result(result, &block) end result end end
@Override MSSQL does not return query plans for prepared statements, so we have to unprepare them SQLServer
gem handles this by overridding exec_explain but that doesn't correctly unprepare them for our needs
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 56 def explain(arel, binds = []) arel = ActiveRecord::Base.send(:replace_bind_variables, arel, binds.map(&:value_for_database)) sql = to_sql(arel) result = with_showplan_on { execute(sql, 'EXPLAIN') } if result.is_a?(Array) # We got back multiple result sets but the printer expects them to all be in one main_result = result[0] result.each_with_index do |result_obj, i| next if i == 0 main_result.rows.concat(result_obj.rows) end result = main_result end printer = showplan_printer.new(result) printer.pp end
@see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 74 def jdbc_connection_class(_spec) ::ActiveRecord::ConnectionAdapters::MSSQLJdbcConnection end
Override Since we aren't passing dates/times around as strings we need to process them here, just making sure they are a string
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 81 def quoted_date(value) super.to_s end
@Override
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 86 def reset! clear_cache! reset_transaction @connection.rollback # Have to deal with rollbacks differently than the SQLServer gem @connection.configure_connection end
Have to reset this because the default arjdbc functionality is to return false unless a level is passed in
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 94 def supports_transaction_isolation? true end
Protected Instance Methods
Called to set any connection specific settings that aren't defined ahead of time
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 101 def configure_connection # For sql server 2008+ we want it to send an actual time otherwise comparisons with time columns don't work @connection.connection.setSendTimeAsDatetime(false) end
@Overwrite Makes a connection before configuring it @connection actually gets defined and then the connect method in the sqlserver gem overrides it This can probably be fixed with a patch to the main gem
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 110 def connect @spid = @connection.execute('SELECT @@SPID').first.values.first @version_year = version_year # Not sure if this is necessary but kept it this way because the gem has it this way configure_connection end
@Overwrite This ends up as a no-op without the override
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 118 def do_execute(sql, name = 'SQL') execute(sql, name) end
@Overwrite Overriding this in case it gets used in places that we don't override by default
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 124 def raw_connection_do(sql) @connection.execute(sql) ensure @update_sql = false end
@Overwrite
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 131 def sp_executesql(sql, name, binds, _options = {}) exec_query(sql, name, binds) end
@Overwrite Prevents turning an insert statement into a query with results Slightly adjusted since we know there should always be a table name in the sql
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 138 def sql_for_insert(sql, pk, id_value, sequence_name, binds) pk = primary_key(get_table_name(sql)) if pk.nil? [sql, binds, pk, sequence_name] end
@Override original version uses driver specific query command
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 144 def sqlserver_version @sqlserver_version ||= select_value('SELECT @@version').to_s end
@Override
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 149 def translate_exception(exception, message) return ActiveRecord::ValueTooLong.new(message) if exception.message.include?('java.sql.DataTruncation') super end
Private Instance Methods
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 156 def _quote(value) return value.quoted if value.is_a?(SQLServer::CoreExt::Time) || value.is_a?(SQLServer::CoreExt::DateTime) super end
# File lib/active_record/connection_adapters/sqlserver/jdbc_overrides.rb, line 161 def process_execute_procedure_result(result) result.map do |row| obj = row.with_indifferent_access yield(obj) if block_given? obj end end