Skip to content

Commit c5d1d5c

Browse files
authored
Merge pull request #572 from alexcwatt/pragma-optimize
Add convenience wrapper for pragma optimize
2 parents 88628ac + d975892 commit c5d1d5c

File tree

4 files changed

+87
-1
lines changed

4 files changed

+87
-1
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# sqlite3-ruby Changelog
22

3+
## next / unreleased
4+
5+
### Added
6+
7+
- `Database#optimize` which wraps the `pragma optimize;` statement. Also added `Constants::Optimize` to allow advanced users to pass a bitmask of options. See https://www.sqlite.org/pragma.html#pragma_optimize. [#572] @alexcwatt @flavorjones
8+
9+
310
## 2.2.0 / 2024-10-30
411

512
### Added

lib/sqlite3/constants.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,5 +170,29 @@ module Status
170170
# This parameter records the number of separate memory allocations currently checked out.
171171
MALLOC_COUNT = 9
172172
end
173+
174+
module Optimize
175+
# Debugging mode. Do not actually perform any optimizations but instead return one line of
176+
# text for each optimization that would have been done. Off by default.
177+
DEBUG = 0x00001
178+
179+
# Run ANALYZE on tables that might benefit. On by default.
180+
ANALYZE_TABLES = 0x00002
181+
182+
# When running ANALYZE, set a temporary PRAGMA analysis_limit to prevent excess run-time. On
183+
# by default.
184+
LIMIT_ANALYZE = 0x00010
185+
186+
# Check the size of all tables, not just tables that have not been recently used, to see if
187+
# any have grown and shrunk significantly and hence might benefit from being re-analyzed. Off
188+
# by default.
189+
CHECK_ALL_TABLES = 0x10000
190+
191+
# Useful for adding a bit to the default behavior, for example
192+
#
193+
# db.optimize(Optimize::DEFAULT | Optimize::CHECK_ALL_TABLES)
194+
#
195+
DEFAULT = ANALYZE_TABLES | LIMIT_ANALYZE
196+
end
173197
end
174198
end

lib/sqlite3/pragmas.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,20 @@ def mmap_size=(size)
338338
set_int_pragma "mmap_size", size
339339
end
340340

341+
# Attempt to optimize the database.
342+
#
343+
# To customize the optimization options, pass +bitmask+ with a combination
344+
# of the Constants::Optimize masks.
345+
#
346+
# See https://www.sqlite.org/pragma.html#pragma_optimize for more information.
347+
def optimize(bitmask = nil)
348+
if bitmask
349+
set_int_pragma "optimize", bitmask
350+
else
351+
execute("PRAGMA optimize")
352+
end
353+
end
354+
341355
def page_count
342356
get_int_pragma "page_count"
343357
end

test/test_pragmas.rb

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,27 @@
22

33
module SQLite3
44
class TestPragmas < SQLite3::TestCase
5+
class DatabaseTracker < SQLite3::Database
6+
attr_reader :test_statements
7+
8+
def initialize(...)
9+
@test_statements = []
10+
super
11+
end
12+
13+
def execute(sql, bind_vars = [], &block)
14+
@test_statements << sql
15+
super
16+
end
17+
end
18+
519
def setup
620
super
7-
@db = SQLite3::Database.new(":memory:")
21+
@db = DatabaseTracker.new(":memory:")
22+
end
23+
24+
def teardown
25+
@db.close
826
end
927

1028
def test_pragma_errors
@@ -32,5 +50,28 @@ def test_set_boolean_pragma
3250
ensure
3351
@db.set_boolean_pragma("read_uncommitted", 0)
3452
end
53+
54+
def test_optimize_with_no_args
55+
@db.optimize
56+
57+
assert_equal(["PRAGMA optimize"], @db.test_statements)
58+
end
59+
60+
def test_optimize_with_args
61+
@db.optimize(Constants::Optimize::DEFAULT)
62+
@db.optimize(Constants::Optimize::ANALYZE_TABLES | Constants::Optimize::LIMIT_ANALYZE)
63+
@db.optimize(Constants::Optimize::ANALYZE_TABLES | Constants::Optimize::DEBUG)
64+
@db.optimize(Constants::Optimize::DEFAULT | Constants::Optimize::CHECK_ALL_TABLES)
65+
66+
assert_equal(
67+
[
68+
"PRAGMA optimize=18",
69+
"PRAGMA optimize=18",
70+
"PRAGMA optimize=3",
71+
"PRAGMA optimize=65554"
72+
],
73+
@db.test_statements
74+
)
75+
end
3576
end
3677
end

0 commit comments

Comments
 (0)