Skip to content

Commit 0adb5b6

Browse files
committed
Sqlite, fix setting pragmas tests
1 parent dec2080 commit 0adb5b6

File tree

2 files changed

+125
-22
lines changed

2 files changed

+125
-22
lines changed

lib/arjdbc/sqlite3/adapter.rb

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
require "active_support/core_ext/class/attribute"
1919
require "arjdbc/sqlite3/column"
2020
require "arjdbc/sqlite3/adapter_hash_config"
21+
require "arjdbc/sqlite3/pragmas"
2122

2223
require "arjdbc/abstract/relation_query_attribute_monkey_patch"
2324

@@ -79,6 +80,15 @@ module SQLite3
7980
json: { name: "json" },
8081
}
8182

83+
DEFAULT_PRAGMAS = {
84+
"foreign_keys" => true,
85+
"journal_mode" => :wal,
86+
"synchronous" => :normal,
87+
"mmap_size" => 134217728, # 128 megabytes
88+
"journal_size_limit" => 67108864, # 64 megabytes
89+
"cache_size" => 2000
90+
}
91+
8292
class StatementPool < ConnectionAdapters::StatementPool # :nodoc:
8393
private
8494
def dealloc(stmt)
@@ -686,29 +696,17 @@ def configure_connection
686696
end
687697
end
688698

689-
# Enforce foreign key constraints
690-
# https://www.sqlite.org/pragma.html#pragma_foreign_keys
691-
# https://www.sqlite.org/foreignkeys.html
692-
raw_execute("PRAGMA foreign_keys = ON", "SCHEMA")
693-
unless @memory_database
694-
# Journal mode WAL allows for greater concurrency (many readers + one writer)
695-
# https://www.sqlite.org/pragma.html#pragma_journal_mode
696-
raw_execute("PRAGMA journal_mode = WAL", "SCHEMA")
697-
# Set more relaxed level of database durability
698-
# 2 = "FULL" (sync on every write), 1 = "NORMAL" (sync every 1000 written pages) and 0 = "NONE"
699-
# https://www.sqlite.org/pragma.html#pragma_synchronous
700-
raw_execute("PRAGMA synchronous = NORMAL", "SCHEMA")
701-
# Set the global memory map so all processes can share some data
702-
# https://www.sqlite.org/pragma.html#pragma_mmap_size
703-
# https://www.sqlite.org/mmap.html
704-
raw_execute("PRAGMA mmap_size = #{128.megabytes}", "SCHEMA")
699+
super
700+
701+
pragmas = @config.fetch(:pragmas, {}).stringify_keys
702+
DEFAULT_PRAGMAS.merge(pragmas).each do |pragma, value|
703+
if ::SQLite3::Pragmas.respond_to?(pragma)
704+
stmt = ::SQLite3::Pragmas.public_send(pragma, value)
705+
raw_execute(stmt, "SCHEMA")
706+
else
707+
warn "Unknown SQLite pragma: #{pragma}"
708+
end
705709
end
706-
# Impose a limit on the WAL file to prevent unlimited growth
707-
# https://www.sqlite.org/pragma.html#pragma_journal_size_limit
708-
raw_execute("PRAGMA journal_size_limit = #{64.megabytes}", "SCHEMA")
709-
# Set the local connection cache to 2000 pages
710-
# https://www.sqlite.org/pragma.html#pragma_cache_size
711-
raw_execute("PRAGMA cache_size = 2000", "SCHEMA")
712710
end
713711
end
714712
# DIFFERENCE: A registration here is moved down to concrete class so we are not registering part of an adapter.

lib/arjdbc/sqlite3/pragmas.rb

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# frozen_string_literal: true
2+
3+
module SQLite3
4+
# defines methods to de generate pragma statements
5+
module Pragmas
6+
class << self
7+
# The enumeration of valid synchronous modes.
8+
SYNCHRONOUS_MODES = [["full", 2], ["normal", 1], ["off", 0]].freeze
9+
10+
# The enumeration of valid temp store modes.
11+
TEMP_STORE_MODES = [["default", 0], ["file", 1], ["memory", 2]].freeze
12+
13+
# The enumeration of valid auto vacuum modes.
14+
AUTO_VACUUM_MODES = [["none", 0], ["full", 1], ["incremental", 2]].freeze
15+
16+
# The list of valid journaling modes.
17+
JOURNAL_MODES = [["delete"], ["truncate"], ["persist"], ["memory"], ["wal"], ["off"]].freeze
18+
19+
# The list of valid locking modes.
20+
LOCKING_MODES = [["normal"], ["exclusive"]].freeze
21+
22+
# The list of valid encodings.
23+
ENCODINGS = [["utf-8"], ["utf-16"], ["utf-16le"], ["utf-16be"]].freeze
24+
25+
# The list of valid WAL checkpoints.
26+
WAL_CHECKPOINTS = [["passive"], ["full"], ["restart"], ["truncate"]].freeze
27+
28+
# Enforce foreign key constraints
29+
# https://www.sqlite.org/pragma.html#pragma_foreign_keys
30+
# https://www.sqlite.org/foreignkeys.html
31+
def foreign_keys(value)
32+
gen_boolean_pragma(:foreign_keys, value)
33+
end
34+
35+
# Journal mode WAL allows for greater concurrency (many readers + one writer)
36+
# https://www.sqlite.org/pragma.html#pragma_journal_mode
37+
def journal_mode(value)
38+
gen_enum_pragma(:journal_mode, value, JOURNAL_MODES)
39+
end
40+
41+
# Set more relaxed level of database durability
42+
# 2 = "FULL" (sync on every write), 1 = "NORMAL" (sync every 1000 written pages) and 0 = "NONE"
43+
# https://www.sqlite.org/pragma.html#pragma_synchronous
44+
def synchronous(value)
45+
gen_enum_pragma(:synchronous, value, SYNCHRONOUS_MODES)
46+
end
47+
48+
def temp_store(value)
49+
gen_enum_pragma(:temp_store, value, TEMP_STORE_MODES)
50+
end
51+
52+
# Set the global memory map so all processes can share some data
53+
# https://www.sqlite.org/pragma.html#pragma_mmap_size
54+
# https://www.sqlite.org/mmap.html
55+
def mmap_size(value)
56+
"PRAGMA mmap_size = #{value.to_i}"
57+
end
58+
59+
# Impose a limit on the WAL file to prevent unlimited growth
60+
# https://www.sqlite.org/pragma.html#pragma_journal_size_limit
61+
def journal_size_limit(value)
62+
"PRAGMA journal_size_limit = #{value.to_i}"
63+
end
64+
65+
# Set the local connection cache to 2000 pages
66+
# https://www.sqlite.org/pragma.html#pragma_cache_size
67+
def cache_size(value)
68+
"PRAGMA cache_size = #{value.to_i}"
69+
end
70+
71+
private
72+
73+
def gen_boolean_pragma(name, mode)
74+
case mode
75+
when String
76+
case mode.downcase
77+
when "on", "yes", "true", "y", "t" then mode = "'ON'"
78+
when "off", "no", "false", "n", "f" then mode = "'OFF'"
79+
else
80+
raise ActiveRecord::JDBCError, "unrecognized pragma parameter #{mode.inspect}"
81+
end
82+
when true, 1
83+
mode = "ON"
84+
when false, 0, nil
85+
mode = "OFF"
86+
else
87+
raise ActiveRecord::JDBCError, "unrecognized pragma parameter #{mode.inspect}"
88+
end
89+
90+
"PRAGMA #{name} = #{mode}"
91+
end
92+
93+
def gen_enum_pragma(name, mode, enums)
94+
match = enums.find { |p| p.find { |i| i.to_s.downcase == mode.to_s.downcase } }
95+
96+
unless match
97+
# Unknown pragma value
98+
raise ActiveRecord::JDBCError, "unrecognized #{name} #{mode.inspect}"
99+
end
100+
101+
"PRAGMA #{name} = '#{match.first.upcase}'"
102+
end
103+
end
104+
end
105+
end

0 commit comments

Comments
 (0)