Module: TransactionIsolation::ActiveRecord::ConnectionAdapters::SQLite3Adapter

Defined in:
lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb

Constant Summary collapse

VENDOR_ISOLATION_LEVEL =
{
    :read_uncommitted => 'read_uncommitted = 1',
    :read_committed => 'read_uncommitted = 0',
    :repeatable_read => 'read_uncommitted = 0',
    :serializable => 'read_uncommitted = 0'
}
ANSI_ISOLATION_LEVEL =
{
    'read_uncommitted = 1' => :read_uncommitted,
    'read_uncommitted = 0' => :serializable
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



8
9
10
11
12
13
# File 'lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb', line 8

def self.included( base )
  base.class_eval do
    alias_method :translate_exception_without_transaction_isolation_conflict, :translate_exception
    alias_method :translate_exception, :translate_exception_with_transaction_isolation_conflict
  end
end

Instance Method Details

#current_isolation_levelObject



31
32
33
# File 'lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb', line 31

def current_isolation_level
  ANSI_ISOLATION_LEVEL[current_vendor_isolation_level]
end

#current_vendor_isolation_levelObject



35
36
37
# File 'lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb', line 35

def current_vendor_isolation_level
  "read_uncommitted = #{select_value( "PRAGMA read_uncommitted" )}"
end

#isolation_conflict?(exception) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
65
66
67
68
# File 'lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb', line 62

def isolation_conflict?( exception )
  [ "The database file is locked",
    "A table in the database is locked",
    "Database lock protocol error"].any? do |error_message|
    exception.message =~ /#{Regexp.escape( error_message )}/i
  end
end

#isolation_level(level) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb', line 39

def isolation_level( level )
  validate_isolation_level( level )

  original_vendor_isolation_level = current_vendor_isolation_level if block_given?

  execute "PRAGMA #{VENDOR_ISOLATION_LEVEL[level]}"

  begin
    yield
  ensure
    execute "PRAGMA #{original_vendor_isolation_level}"
  end if block_given?
end

#supports_isolation_levels?Boolean

Returns:

  • (Boolean)


15
16
17
# File 'lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb', line 15

def supports_isolation_levels?
  true
end

#translate_exception_with_transaction_isolation_conflict(exception, **args) ⇒ Object



53
54
55
56
57
58
59
# File 'lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb', line 53

def translate_exception_with_transaction_isolation_conflict( exception, **args )
  if isolation_conflict?( exception )
    ::ActiveRecord::TransactionIsolationConflict.new( "Transaction isolation conflict detected: #{exception.message}" )
  else
    translate_exception_without_transaction_isolation_conflict( exception, **args )
  end
end