Skip to content

fix(db import): query each PRAGMA individually so checks survive sqlite3 format changes#1037

Open
ada-powerful wants to merge 1 commit into
tursodatabase:mainfrom
ada-powerful:fix/issue-1030-pragma-per-query
Open

fix(db import): query each PRAGMA individually so checks survive sqlite3 format changes#1037
ada-powerful wants to merge 1 commit into
tursodatabase:mainfrom
ada-powerful:fix/issue-1030-pragma-per-query

Conversation

@ada-powerful
Copy link
Copy Markdown

Fixes #1030.

Problem

turso db import runs sqliteFileIntegrityChecks, which executes one .mode line query and string-matches the resulting text for j = wal / j: wal etc. The dual-separator check covers today's = vs : split, but it depends entirely on whatever line formatter sqlite3 happens to emit. When sqlite3 changes that format again, the check breaks again — and it has already broken once, between 3.49 and 3.50.

Fix

Query each pragma with its own short statement:

sqlite3 -batch -noheader -list <file> "select * from pragma_journal_mode;"

That returns just wal — no key, no separator, no column header — regardless of how .mode line is formatted in any future sqlite3 version. Compare the trimmed value against the expected literal.

Added a readPragma(file, pragma) helper next to runQuickCheck and refactored sqliteFileIntegrityChecks to call it four times. Same error messages, same exit conditions, format-independent.

Tests

$ go test -v ./internal/cmd/...
=== RUN   TestReadPragma
--- PASS: TestReadPragma (0.09s)
    --- PASS: TestReadPragma/journal_mode_returns_wal
    --- PASS: TestReadPragma/page_size_returns_4096
    --- PASS: TestReadPragma/auto_vacuum_returns_0
    --- PASS: TestReadPragma/encoding_returns_UTF-8
    --- PASS: TestReadPragma/nonexistent_file_errors
=== RUN   TestSqliteFileIntegrityChecks
--- PASS: TestSqliteFileIntegrityChecks (0.10s)
    --- PASS: TestSqliteFileIntegrityChecks/valid_WAL_database_passes_all_settings_checks
    --- PASS: TestSqliteFileIntegrityChecks/non-WAL_database_returns_WAL_error
    --- PASS: TestSqliteFileIntegrityChecks/wrong_page_size_returns_page-size_error
=== RUN   TestRunQuickCheck
--- PASS: TestRunQuickCheck (0.12s)
    [all existing subtests pass]
PASS
ok      github.com/tursodatabase/turso-cli/internal/cmd 0.328s

Verified against system sqlite3 3.46.1 in golang:1.25 CI image. Existing TestRunQuickCheck continues to pass.

Disclosure

This PR was prepared by an AI agent (Claude Opus 4.7) under direct human review. Happy to address any feedback.

…te3 output-format changes (tursodatabase#1030)

`sqliteFileIntegrityChecks` ran one `.mode line` query and string-matched the
result for `j = wal` / `j: wal` etc. The dual-separator check works today, but
it depends on whatever line formatter sqlite3 happens to emit, and breaks again
the next time that format moves (which is exactly what tursodatabase#1030 reports for
sqlite3 3.50).

Switch to one short query per pragma using `-batch -noheader -list "select * from pragma_X"`,
which returns just the value with no surrounding key, separator, or column header.
Compare the trimmed value to the expected literal. Robust to any future sqlite3
output mode changes.

Adds:
- `readPragma(file, pragma)` helper next to `runQuickCheck`.
- `TestReadPragma` covering journal_mode, page_size, auto_vacuum, encoding,
  and the nonexistent-file error path.
- `TestSqliteFileIntegrityChecks` covering the happy path and two failure
  modes (non-WAL DB, 8KB page size).

Verified against system sqlite3 3.46.1 in CI Docker image; passes existing
`TestRunQuickCheck` suite.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

db import: WAL check fails on sqlite3 ≥ 3.50 ("j: wal" vs "j = wal")

1 participant