Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
- [#892](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/892) Add support for if_exists on remove_column
- [#883](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/885) Fix quoting of ActiveRecord::Relation::QueryAttribute and ActiveModel::Attributes
- [#893](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/893) Add Active Record Marshal forward compatibility tests
- [#903](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/903) Raise ActiveRecord::ConnectionNotEstablished on calls to execute with a disconnected connection

#### Changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def execute_procedure(proc_name, *variables)
log(sql, name) do
case @connection_options[:mode]
when :dblib
result = @connection.execute(sql)
result = ensure_established_connection! { @connection.execute(sql) }
options = { as: :hash, cache_rows: true, timezone: ActiveRecord::Base.default_timezone || :utc }
result.each(options) do |row|
r = row.with_indifferent_access
Expand Down Expand Up @@ -357,7 +357,7 @@ def sp_executesql_sql(sql, types, params, name)
def raw_connection_do(sql)
case @connection_options[:mode]
when :dblib
result = @connection.execute(sql)
result = ensure_established_connection! { @connection.execute(sql) }

# TinyTDS returns false instead of raising an exception if connection fails.
# Getting around this by raising an exception ourselves while this PR
Expand Down Expand Up @@ -428,7 +428,7 @@ def _raw_select(sql, options = {})
def raw_connection_run(sql)
case @connection_options[:mode]
when :dblib
@connection.execute(sql)
ensure_established_connection! { @connection.execute(sql) }
end
end

Expand Down Expand Up @@ -462,6 +462,12 @@ def finish_statement_handle(handle)
end
handle
end

def ensure_established_connection!
raise ActiveRecord::ConnectionNotEstablished, 'SQL Server client is not connected' unless @connection

yield
end
end
end
end
Expand Down
2 changes: 2 additions & 0 deletions lib/active_record/connection_adapters/sqlserver_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ def initialize_type_map(m = type_map)
end

def translate_exception(e, message:, sql:, binds:)
return e if e.is_a?(ActiveRecord::ConnectionNotEstablished)

case message
when /(cannot insert duplicate key .* with unique index) | (violation of unique key constraint)/i
RecordNotUnique.new(message, sql: sql, binds: binds)
Expand Down
39 changes: 39 additions & 0 deletions test/cases/disconnected_test_sqlserver.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

require "cases/helper_sqlserver"

class TestDisconnectedAdapter < ActiveRecord::TestCase
self.use_transactional_tests = false

def setup
@connection = ActiveRecord::Base.connection
end

teardown do
return if in_memory_db?
db_config = ActiveRecord::Base.connection_db_config
ActiveRecord::Base.establish_connection(db_config)
end

test "can't execute procuderes while disconnected" do
@connection.execute_procedure :sp_tables, "sst_datatypes"
@connection.disconnect!
assert_raises(ActiveRecord::ConnectionNotEstablished, 'SQL Server client is not connected') do
@connection.execute_procedure :sp_tables, "sst_datatypes"
end
end

test "can't execute query while disconnected" do
sql = "SELECT count(*) from products WHERE id IN(@0, @1)"
binds = [
ActiveRecord::Relation::QueryAttribute.new("id", 2, ActiveRecord::Type::BigInteger.new),
ActiveRecord::Relation::QueryAttribute.new("id", 2, ActiveRecord::Type::BigInteger.new)
]

@connection.exec_query sql, "TEST", binds
@connection.disconnect!
assert_raises(ActiveRecord::ConnectionNotEstablished, 'SQL Server client is not connected') do
@connection.exec_query sql, "TEST", binds
end
end
end