Skip to content

Commit

Permalink
Merge with some older changes I made but forgot to push :(
Browse files Browse the repository at this point in the history
  • Loading branch information
enebo committed Jan 18, 2024
2 parents fa0b3d3 + 78175ec commit 339d62d
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 41 deletions.
16 changes: 11 additions & 5 deletions lib/arjdbc/abstract/database_statements.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,7 @@ def execute(sql, name = nil, async: false, allow_retry: false, materialize_trans

mark_transaction_written_if_write(sql)

log(sql, name, async: async) do
with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
conn.execute(sql)
end
end
raw_execute(sql, name, async: async, allow_retry: allow_retry, materialize_transactions: materialize_transactions)
end

# overridden to support legacy binds
Expand All @@ -108,6 +104,16 @@ def convert_legacy_binds_to_attributes(binds)
end
end

def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: false)
log(sql, name, async: async) do
with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
# We sometimes return an ActiveRecord::Result and sometimes a raw, so force to raw
result = conn.execute(sql)
result.is_a?(ActiveRecord::Result) ? result.to_a : result
end
end
end

end
end
end
81 changes: 45 additions & 36 deletions lib/arjdbc/sqlite3/adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,38 +90,6 @@ def dealloc(stmt)
end
end

def initialize(...)
super

@memory_database = false
case @config[:database].to_s
when ""
raise ArgumentError, "No database file specified. Missing argument: database"
when ":memory:"
@memory_database = true
when /\Afile:/
else
# Otherwise we have a path relative to Rails.root
@config[:database] = File.expand_path(@config[:database], Rails.root) if defined?(Rails.root)
dirname = File.dirname(@config[:database])
unless File.directory?(dirname)
begin
Dir.mkdir(dirname)
rescue Errno::ENOENT => error
if error.message.include?("No such file or directory")
raise ActiveRecord::NoDatabaseError.new(connection_pool: @pool)
else
raise
end
end
end
end

@config[:strict] = ConnectionAdapters::SQLite3Adapter.strict_strings_by_default unless @config.key?(:strict)
@connection_parameters = @config.merge(database: @config[:database].to_s, results_as_hash: true)
@use_insert_returning = @config.key?(:insert_returning) ? self.class.type_cast_config_to_boolean(@config[:insert_returning]) : true
end

def self.database_exists?(config)
@config[:database] == ":memory:" || File.exist?(@config[:database].to_s)
end
Expand Down Expand Up @@ -321,7 +289,7 @@ def change_column_default(table_name, column_name, default_or_changes) #:nodoc:

def change_column_null(table_name, column_name, null, default = nil) #:nodoc:
validate_change_column_null_argument!(null)

unless null || default.nil?
internal_exec_query("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
end
Expand Down Expand Up @@ -635,6 +603,11 @@ def translate_exception(exception, message:, sql:, binds:)
elsif exception.message.match?(/called on a closed database/i)
# DIFFERENCE: FQN
::ActiveRecord::ConnectionNotEstablished.new(exception, connection_pool: @pool)
elsif exception.message.match?(/sql error/i)
::ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds, connection_pool: @pool)
elsif exception.message.match?(/write a readonly database/i)
message = message.sub('org.sqlite.SQLiteException', 'SQLite3::ReadOnlyException')
::ActiveRecord::StatementInvalid.new(message, sql: sql, binds: binds, connection_pool: @pool)
else
super
end
Expand Down Expand Up @@ -710,6 +683,44 @@ def reconnect
end
end

def configure_connection
if @config[:timeout] && @config[:retries]
raise ArgumentError, "Cannot specify both timeout and retries arguments"
elsif @config[:timeout]
# FIXME: missing from adapter
# @raw_connection.busy_timeout(self.class.type_cast_config_to_integer(@config[:timeout]))
elsif @config[:retries]
retries = self.class.type_cast_config_to_integer(@config[:retries])
raw_connection.busy_handler do |count|
count <= retries
end
end

# Enforce foreign key constraints
# https://www.sqlite.org/pragma.html#pragma_foreign_keys
# https://www.sqlite.org/foreignkeys.html
raw_execute("PRAGMA foreign_keys = ON", "SCHEMA")
unless @memory_database
# Journal mode WAL allows for greater concurrency (many readers + one writer)
# https://www.sqlite.org/pragma.html#pragma_journal_mode
raw_execute("PRAGMA journal_mode = WAL", "SCHEMA")
# Set more relaxed level of database durability
# 2 = "FULL" (sync on every write), 1 = "NORMAL" (sync every 1000 written pages) and 0 = "NONE"
# https://www.sqlite.org/pragma.html#pragma_synchronous
raw_execute("PRAGMA synchronous = NORMAL", "SCHEMA")
# Set the global memory map so all processes can share some data
# https://www.sqlite.org/pragma.html#pragma_mmap_size
# https://www.sqlite.org/mmap.html
raw_execute("PRAGMA mmap_size = #{128.megabytes}", "SCHEMA")
end
# Impose a limit on the WAL file to prevent unlimited growth
# https://www.sqlite.org/pragma.html#pragma_journal_size_limit
raw_execute("PRAGMA journal_size_limit = #{64.megabytes}", "SCHEMA")
# Set the local connection cache to 2000 pages
# https://www.sqlite.org/pragma.html#pragma_cache_size
raw_execute("PRAGMA cache_size = 2000", "SCHEMA")
end

def configure_connection
if @config[:timeout] && @config[:retries]
raise ArgumentError, "Cannot specify both timeout and retries arguments"
Expand Down Expand Up @@ -775,9 +786,7 @@ class SQLite3Adapter < AbstractAdapter
# If you wish to enable this mode you can add the following line to your application.rb file:
#
# config.active_record.sqlite3_adapter_strict_strings_by_default = true
class_attribute :strict_strings_by_default, default: false


class_attribute :strict_strings_by_default, default: false # Does not actually do anything right now

def self.represent_boolean_as_integer=(value) # :nodoc:
if value == false
Expand Down

0 comments on commit 339d62d

Please sign in to comment.