aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/abstract_adapter.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_adapter.rb59
1 files changed, 47 insertions, 12 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
index fa10f18cb7..f7d75e6748 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
@@ -76,7 +76,7 @@ module ActiveRecord
SIMPLE_INT = /\A\d+\z/
- attr_accessor :visitor, :pool
+ attr_accessor :visitor, :pool, :prevent_writes
attr_reader :schema_cache, :owner, :logger, :prepared_statements, :lock
alias :in_use? :owner
@@ -100,6 +100,11 @@ module ActiveRecord
end
end
+ def self.build_read_query_regexp(*parts) # :nodoc:
+ parts = parts.map { |part| /\A\s*#{part}/i }
+ Regexp.union(*parts)
+ end
+
def initialize(connection, logger = nil, config = {}) # :nodoc:
super()
@@ -125,12 +130,35 @@ module ActiveRecord
@advisory_locks_enabled = self.class.type_cast_config_to_boolean(
config.fetch(:advisory_locks, true)
)
+
+ check_version
end
def replica?
@config[:replica] || false
end
+ # Determines whether writes are currently being prevents.
+ #
+ # Returns true if the connection is a replica, or if +prevent_writes+
+ # is set to true.
+ def preventing_writes?
+ replica? || prevent_writes
+ end
+
+ # Prevent writing to the database regardless of role.
+ #
+ # In some cases you may want to prevent writes to the database
+ # even if you are on a database that can write. `while_preventing_writes`
+ # will prevent writes to the database for the duration of the block.
+ def while_preventing_writes
+ original = self.prevent_writes
+ self.prevent_writes = true
+ yield
+ ensure
+ self.prevent_writes = original
+ end
+
def migrations_paths # :nodoc:
@config[:migrations_paths] || Migrator.migrations_paths
end
@@ -312,6 +340,11 @@ module ActiveRecord
false
end
+ # Does this adapter support materialized views?
+ def supports_materialized_views?
+ false
+ end
+
# Does this adapter support datetime with precision?
def supports_datetime_with_precision?
false
@@ -502,6 +535,9 @@ module ActiveRecord
end
private
+ def check_version
+ end
+
def type_map
@type_map ||= Type::TypeMap.new.tap do |mapping|
initialize_type_map(mapping)
@@ -575,14 +611,12 @@ module ActiveRecord
$1.to_i if sql_type =~ /\((.*)\)/
end
- def translate_exception_class(e, sql)
- begin
- message = "#{e.class.name}: #{e.message}: #{sql}"
- rescue Encoding::CompatibilityError
- message = "#{e.class.name}: #{e.message.force_encoding sql.encoding}: #{sql}"
- end
+ def translate_exception_class(e, sql, binds)
+ message = "#{e.class.name}: #{e.message}"
- exception = translate_exception(e, message)
+ exception = translate_exception(
+ e, message: message, sql: sql, binds: binds
+ )
exception.set_backtrace e.backtrace
exception
end
@@ -595,24 +629,25 @@ module ActiveRecord
binds: binds,
type_casted_binds: type_casted_binds,
statement_name: statement_name,
- connection_id: object_id) do
+ connection_id: object_id,
+ connection: self) do
begin
@lock.synchronize do
yield
end
rescue => e
- raise translate_exception_class(e, sql)
+ raise translate_exception_class(e, sql, binds)
end
end
end
- def translate_exception(exception, message)
+ def translate_exception(exception, message:, sql:, binds:)
# override in derived class
case exception
when RuntimeError
exception
else
- ActiveRecord::StatementInvalid.new(message)
+ ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds)
end
end