Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# sqlite3-ruby Changelog

## next / unreleased

### Added

- `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


## 2.2.0 / 2024-10-30

### Added
Expand Down
24 changes: 24 additions & 0 deletions lib/sqlite3/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -170,5 +170,29 @@ module Status
# This parameter records the number of separate memory allocations currently checked out.
MALLOC_COUNT = 9
end

module Optimize
# Debugging mode. Do not actually perform any optimizations but instead return one line of
# text for each optimization that would have been done. Off by default.
DEBUG = 0x00001

# Run ANALYZE on tables that might benefit. On by default.
ANALYZE_TABLES = 0x00002

# When running ANALYZE, set a temporary PRAGMA analysis_limit to prevent excess run-time. On
# by default.
LIMIT_ANALYZE = 0x00010

# Check the size of all tables, not just tables that have not been recently used, to see if
# any have grown and shrunk significantly and hence might benefit from being re-analyzed. Off
# by default.
CHECK_ALL_TABLES = 0x10000

# Useful for adding a bit to the default behavior, for example
#
# db.optimize(Optimize::DEFAULT | Optimize::CHECK_ALL_TABLES)
#
DEFAULT = ANALYZE_TABLES | LIMIT_ANALYZE
end
end
end
14 changes: 14 additions & 0 deletions lib/sqlite3/pragmas.rb
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,20 @@ def mmap_size=(size)
set_int_pragma "mmap_size", size
end

# Attempt to optimize the database.
#
# To customize the optimization options, pass +bitmask+ with a combination
# of the Constants::Optimize masks.
#
# See https://www.sqlite.org/pragma.html#pragma_optimize for more information.
def optimize(bitmask = nil)
if bitmask
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see these bits made available as constants like many of the other sqlite bitmasks in lib/sqlite3/constants.rb

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good idea. I took a pass at this; please let me know what you think.

set_int_pragma "optimize", bitmask
else
execute("PRAGMA optimize")
end
end

def page_count
get_int_pragma "page_count"
end
Expand Down
43 changes: 42 additions & 1 deletion test/test_pragmas.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,27 @@

module SQLite3
class TestPragmas < SQLite3::TestCase
class DatabaseTracker < SQLite3::Database
attr_reader :test_statements

def initialize(...)
@test_statements = []
super
end

def execute(sql, bind_vars = [], &block)
@test_statements << sql
super
end
end

def setup
super
@db = SQLite3::Database.new(":memory:")
@db = DatabaseTracker.new(":memory:")
end

def teardown
@db.close
end

def test_pragma_errors
Expand Down Expand Up @@ -32,5 +50,28 @@ def test_set_boolean_pragma
ensure
@db.set_boolean_pragma("read_uncommitted", 0)
end

def test_optimize_with_no_args
@db.optimize

assert_equal(["PRAGMA optimize"], @db.test_statements)
end

def test_optimize_with_args
@db.optimize(Constants::Optimize::DEFAULT)
@db.optimize(Constants::Optimize::ANALYZE_TABLES | Constants::Optimize::LIMIT_ANALYZE)
@db.optimize(Constants::Optimize::ANALYZE_TABLES | Constants::Optimize::DEBUG)
@db.optimize(Constants::Optimize::DEFAULT | Constants::Optimize::CHECK_ALL_TABLES)

assert_equal(
[
"PRAGMA optimize=18",
"PRAGMA optimize=18",
"PRAGMA optimize=3",
"PRAGMA optimize=65554"
],
@db.test_statements
)
end
end
end