Skip to content

Add complete local SQLite snapshots - #1884

Merged
stefan-burke merged 9 commits into
mainfrom
feature/database-snapshot
Jul 22, 2026
Merged

Add complete local SQLite snapshots#1884
stefan-burke merged 9 commits into
mainfrom
feature/database-snapshot

Conversation

@stefan-burke

@stefan-burke stefan-burke commented Jul 22, 2026

Copy link
Copy Markdown
Member

Summary

  • add deno task snapshot --out <path.sqlite> for developer machines
  • read DB_URL and DB_TOKEN from .env, preferring them over existing shell values
  • show the source, destination, numbered stages, live elapsed time, final size, and total time
  • copy the whole remote database through libSQL page-level sync, including schema objects, BLOBs, 64-bit integers, and sequence state
  • checkpoint and verify the local database before publishing one standalone SQLite file
  • reject bad arguments, missing credentials, plaintext remote connections, missing output directories, and existing SQLite main/WAL/SHM files
  • document how the snapshot differs from stored application backups

Safety

Remote connections must use TLS. Plain HTTP and libsql: URLs with a final tls=0 value are accepted only for exact loopback hosts. The task builds its replica in a temporary directory beside the requested output. It closes the syncing client, reopens the file locally, requires a fully truncated WAL and a clean integrity check, sets the database to owner-only 0600, then publishes through an atomic no-replace hard link. It checks the destination main file and its WAL/SHM sidecars before syncing and again before publication. The temporary replica and every sidecar are removed on success or failure. Existing files and files created during sync are never overwritten or deleted.

Interactive terminals refresh the active stage with elapsed time once per second. Redirected output stays as stable one-line events. The progress timer is stopped on both success and failure.

Verification

  • nix develop -c deno task precommit
  • snapshot implementation and progress output have 100% line and branch coverage
  • ran the finished task against the real .env; it published a complete 110 MB SQLite file and passed its built-in integrity check

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a deno task snapshot --out <path.sqlite> workflow that validates remote database credentials, syncs a temporary libSQL replica, verifies SQLite integrity and WAL state, atomically publishes the snapshot, and cleans up temporary resources.

Changes

Database snapshot workflow

Layer / File(s) Summary
Snapshot options and request validation
scripts/database-snapshot-lib.ts, test/scripts/database-snapshot-options.test.ts
Defines snapshot types, CLI parsing, environment and remote URL validation, output-path checks, and corresponding tests.
Replica sync, verification, and publication
scripts/database-snapshot-lib.ts, test/scripts/database-snapshot*.test.ts, test/test-utils/files.ts, test/lib/test-utils/files.test.ts
Synchronizes a temporary replica, checkpoints and validates integrity, rejects non-empty WAL files, publishes atomically, cleans up resources, and tests success, race, error, permission, and cleanup paths.
Executable task and developer documentation
scripts/database-snapshot.ts, deno.json, AGENTS.md, README.md, .gitignore
Adds the executable and Deno task wiring, dotenv support, type checking, SQLite ignore rules, and documentation for snapshot usage and contents.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Developer
  participant SnapshotScript
  participant createDatabaseSnapshot
  participant RemoteReplica
  participant SQLiteSnapshot
  Developer->>SnapshotScript: run snapshot with output path
  SnapshotScript->>createDatabaseSnapshot: pass validated request
  createDatabaseSnapshot->>RemoteReplica: synchronize temporary replica
  RemoteReplica-->>createDatabaseSnapshot: return synchronized database
  createDatabaseSnapshot->>SQLiteSnapshot: checkpoint and integrity-check database
  SQLiteSnapshot-->>createDatabaseSnapshot: return verification and WAL results
  createDatabaseSnapshot-->>Developer: publish snapshot and report output path
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a task to create complete local SQLite snapshots.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/database-snapshot
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch feature/database-snapshot

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c9badf5f8b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/database-snapshot-lib.ts Outdated
Comment thread scripts/database-snapshot-lib.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/database-snapshot-lib.ts`:
- Around line 104-109: Update requireRemoteDatabaseUrl to allow http only for
loopback hostnames (localhost, 127.0.0.1, and ::1), while requiring https for
all other remote hosts. Preserve acceptance of existing supported secure
protocols and reject non-loopback plain-HTTP URLs before returning the value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 54620bfd-631e-40de-9ba0-2f44773c186e

📥 Commits

Reviewing files that changed from the base of the PR and between 0077485 and c9badf5.

📒 Files selected for processing (7)
  • AGENTS.md
  • README.md
  • deno.json
  • scripts/database-snapshot-lib.ts
  • scripts/database-snapshot.ts
  • test/scripts/database-snapshot-options.test.ts
  • test/scripts/database-snapshot.test.ts

Comment thread scripts/database-snapshot-lib.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/database-snapshot-lib.ts (1)

251-257: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Sensitive Data Exposure (CWE-732): Incorrect Permission Assignment for Critical Resource

Reachability: External
● Entry
  scripts/database-snapshot.ts:15
  createDatabaseSnapshot
│
▼
● Sink
  scripts/database-snapshot-lib.ts

Set the temp database to 0600 before Deno.link The hard link preserves the temporary inode’s mode, so a default umask can publish the snapshot as group/world-readable on a shared host. Add a regression test that asserts the published file is owner-only.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/database-snapshot-lib.ts` around lines 251 - 257, Update
publishSnapshot to set the temporary database file’s permissions to owner-only
(0600) before calling Deno.link, ensuring the published hard link inherits the
restricted mode. Add a regression test covering publishSnapshot that verifies
the resulting output file is not group- or world-readable.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@scripts/database-snapshot-lib.ts`:
- Around line 251-257: Update publishSnapshot to set the temporary database
file’s permissions to owner-only (0600) before calling Deno.link, ensuring the
published hard link inherits the restricted mode. Add a regression test covering
publishSnapshot that verifies the resulting output file is not group- or
world-readable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b699d070-7903-4d3f-a57b-7fe4090066e0

📥 Commits

Reviewing files that changed from the base of the PR and between c9badf5 and a33a126.

⛔ Files ignored due to path filters (1)
  • deno.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • AGENTS.md
  • README.md
  • deno.json
  • scripts/database-snapshot-lib.ts
  • scripts/database-snapshot.ts
  • test/scripts/database-snapshot-options.test.ts
  • test/scripts/database-snapshot.test.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0e1f0a7eaa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread README.md Outdated
Comment thread test/scripts/database-snapshot.test.ts
@stefan-burke

Copy link
Copy Markdown
Member Author

Resolved CodeRabbit’s owner-only file finding in 3b8f226. The verified temporary database is now changed to 0600 before the hard link is created, so the published snapshot inherits owner-only permissions. database-snapshot-safety.test.ts asserts the final mode exactly; targeted coverage is 100%, and deno task precommit passes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/scripts/database-snapshot-safety.test.ts`:
- Around line 63-67: Extract the shared directory-listing helper in
test-utils/files.ts, using Array.fromAsync over Deno.readDir followed by mapping
entry names and sorting them. In test/scripts/database-snapshot-safety.test.ts,
replace the local directoryNames implementation with the shared helper; in
test/scripts/database-snapshot.test.ts, replace the inline directory-entry
listing block with that same helper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9736f825-bf41-4d7e-8ce6-1d30685cacd3

📥 Commits

Reviewing files that changed from the base of the PR and between 0e1f0a7 and 3b8f226.

📒 Files selected for processing (3)
  • scripts/database-snapshot-lib.ts
  • test/scripts/database-snapshot-safety.test.ts
  • test/scripts/database-snapshot.test.ts

Comment thread test/scripts/database-snapshot-safety.test.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0c4036cd0b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/database-snapshot-lib.ts Outdated
Comment thread scripts/database-snapshot-lib.ts
@stefan-burke
stefan-burke added this pull request to the merge queue Jul 22, 2026
Merged via the queue into main with commit a52a0bf Jul 22, 2026
3 checks passed
@stefan-burke
stefan-burke deleted the feature/database-snapshot branch July 22, 2026 14:39
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.

1 participant