From 5fcdb3f4381de676f09cdcbd958e75b9577e01bd Mon Sep 17 00:00:00 2001 From: Matt Brictson Date: Thu, 29 Jul 2021 14:43:34 +0200 Subject: [PATCH 1/2] Apply monkey patches for SQL Server connections only (#933) Recent versions of Rails support multiple database connections within the same app. It is possible for these connections to use different adapters. For example, one adapter may use SQL Server, and another uses PostgreSQL. This gem applies some monkey patches to ActiveRecord for SQL Server compatibility. These patches could break other adapters, though, in a multiple-database scenario. This commit modifies the patches so that they are applied only if the connection is SQL Server. If not, the original ActiveRecord implementation (`super`) is used instead. Fixes #929 --- CHANGELOG.md | 4 ++++ .../sqlserver/core_ext/attribute_methods.rb | 2 ++ .../connection_adapters/sqlserver/core_ext/calculations.rb | 4 ++++ .../connection_adapters/sqlserver/core_ext/explain.rb | 2 ++ .../connection_adapters/sqlserver/core_ext/finder_methods.rb | 2 ++ .../connection_adapters/sqlserver/core_ext/preloader.rb | 2 ++ 6 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96913e3cc..f731dff76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## Unreleased + +[#933](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/933) Conditionally apply SQL Server monkey patches to ActiveRecord so that it is safe to use this gem alongside other database adapters (e.g. PostgreSQL) in a multi-database Rails app + ## v6.0.2 #### Fixed diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb index 1becf129b..af0e6a4e7 100644 --- a/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/attribute_methods.rb @@ -10,6 +10,8 @@ module AttributeMethods private def attributes_for_update(attribute_names) + return super unless self.class.connection.adapter_name == "SQLServer" + super.reject do |name| column = self.class.columns_hash[name] column && column.respond_to?(:is_identity?) && column.is_identity? diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb index d02e6a302..254fa3c99 100644 --- a/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/calculations.rb @@ -10,6 +10,8 @@ module CoreExt module Calculations # Same as original except we don't perform PostgreSQL hack that removes ordering. def calculate(operation, column_name) + return super unless klass.connection.adapter_name == "SQLServer" + if has_include?(column_name) relation = apply_join_dependency @@ -29,6 +31,8 @@ def calculate(operation, column_name) private def build_count_subquery(relation, column_name, distinct) + return super unless klass.connection.adapter_name == "SQLServer" + super(relation.unscope(:order), column_name, distinct) end diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb index 89e1d6bb1..9a6a9a775 100644 --- a/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/explain.rb @@ -9,6 +9,8 @@ module Explain SQLSERVER_STATEMENT_REGEXP = /N'(.+)', N'(.+)', (.+)/ def exec_explain(queries) + return super unless connection.adapter_name == "SQLServer" + unprepared_queries = queries.map do |(sql, binds)| [unprepare_sqlserver_statement(sql, binds), binds] end diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb index ccfa32620..03932d492 100644 --- a/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/finder_methods.rb @@ -12,6 +12,8 @@ module FinderMethods # Same as original except we order by values in distinct select if present. def construct_relation_for_exists(conditions) + return super unless klass.connection.adapter_name == "SQLServer" + conditions = sanitize_forbidden_attributes(conditions) if distinct_value && offset_value diff --git a/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb b/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb index 0171f4c65..9d64c99e8 100644 --- a/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb +++ b/lib/active_record/connection_adapters/sqlserver/core_ext/preloader.rb @@ -10,6 +10,8 @@ module Preloader private def records_for(ids) + return super unless klass.connection.adapter_name == "SQLServer" + ids.each_slice(in_clause_length).flat_map do |slice| scope.where(association_key_name => slice).load do |record| # Processing only the first owner From b8dab588638ea562d684a961d7aa6a31c5f2c8a0 Mon Sep 17 00:00:00 2001 From: Aidan Haran Date: Tue, 23 May 2023 16:57:14 +0100 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f731dff76..658b1176b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ ## Unreleased -[#933](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/933) Conditionally apply SQL Server monkey patches to ActiveRecord so that it is safe to use this gem alongside other database adapters (e.g. PostgreSQL) in a multi-database Rails app +#### Fixed + +[#1054](https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/pull/1054) Conditionally apply SQL Server monkey patches to ActiveRecord so that it is safe to use this gem alongside other database adapters (e.g. PostgreSQL) in a multi-database Rails app ## v6.0.2