Skip to content
Open
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
19 changes: 19 additions & 0 deletions docs/runtime/sqlite.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,25 @@ db.close(true);
has no effect after the first.
</Note>

<Important title="WAL sidecar files">
When using WAL (Write-Ahead Logging) mode with a file-based database, SQLite creates additional sidecar files:
`-wal` (write-ahead log) and `-shm` (shared memory). The cleanup behavior of these files after calling `.close()`
varies by platform and SQLite configuration:

- **Linux**: Sidecar files are typically cleaned up after close
- **macOS**: Sidecar files may persist after close due to platform-specific SQLite behavior
- **Windows**: Behavior varies by Windows version and SQLite configuration

If you need to ensure sidecar files are cleaned up, consider manually removing them after closing the database:
```ts
import { rmSync } from "node:fs";

db.close();
rmSync("mydb.sqlite-wal");
rmSync("mydb.sqlite-shm");
```
Comment on lines +146 to +152
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add { force: true } to prevent errors when files don't exist.

The rmSync calls will throw ENOENT if the sidecar files don't exist (e.g., on Linux where they may already be cleaned up, or if WAL mode wasn't actually used). Adding { force: true } makes the cleanup idempotent and safe across platforms.

🛠️ Proposed fix
   ```ts
   import { rmSync } from "node:fs";

   db.close();
-  rmSync("mydb.sqlite-wal");
-  rmSync("mydb.sqlite-shm");
+  rmSync("mydb.sqlite-wal", { force: true });
+  rmSync("mydb.sqlite-shm", { force: true });
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/runtime/sqlite.mdx` around lines 146 - 152, The rmSync calls can throw
ENOENT if the WAL/SHM sidecar files are absent; update the cleanup to call
rmSync("mydb.sqlite-wal", { force: true }) and rmSync("mydb.sqlite-shm", {
force: true }) after db.close() so removal is idempotent and safe across
platforms — locate the calls to rmSync in the snippet and add the { force: true
} option.

</Important>
Comment on lines +136 to +153
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Cross-reference the fileControl API for deterministic cleanup.

The linked issue (#27481) specifically requests documenting db.fileControl(constants.SQLITE_FCNTL_PERSIST_WAL, 0) as the deterministic cleanup option. This API is already documented at lines 647-658, but this Important note doesn't mention it. The fileControl approach is preferable to manual file deletion as it instructs SQLite itself to clean up the files on close.

Consider restructuring to recommend the fileControl approach first, with manual deletion as a fallback:

📝 Suggested documentation improvement
   If you need to ensure sidecar files are cleaned up, consider manually removing them after closing the database:
+  If you need deterministic cleanup of sidecar files, use the `fileControl` API before closing:
+  ```ts
+  import { Database, constants } from "bun:sqlite";
+
+  const db = new Database("mydb.sqlite");
+  db.run("PRAGMA journal_mode = WAL;");
+  // Disable WAL persistence - files will be cleaned up on close
+  db.fileControl(constants.SQLITE_FCNTL_PERSIST_WAL, 0);
+  // ... use database ...
+  db.close();
+  ```
+
+  Alternatively, you can manually remove the files after closing:
   ```ts
-  import { rmSync } from "node:fs";
+  import { rmSync } from "node:fs"; 
 
   db.close();
-  rmSync("mydb.sqlite-wal");
-  rmSync("mydb.sqlite-shm");
+  rmSync("mydb.sqlite-wal", { force: true });
+  rmSync("mydb.sqlite-shm", { force: true });
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
<Important title="WAL sidecar files">
  When using WAL (Write-Ahead Logging) mode with a file-based database, SQLite creates additional sidecar files:
  `-wal` (write-ahead log) and `-shm` (shared memory). The cleanup behavior of these files after calling `.close()` 
  varies by platform and SQLite configuration:

  - **Linux**: Sidecar files are typically cleaned up after close
  - **macOS**: Sidecar files may persist after close due to platform-specific SQLite behavior
  - **Windows**: Behavior varies by Windows version and SQLite configuration

  If you need deterministic cleanup of sidecar files, use the `fileControl` API before closing:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/runtime/sqlite.mdx` around lines 136 - 153, Update the "WAL sidecar
files" Important note to recommend using the deterministic SQLite API before
suggesting manual deletion: explain and show using Database and
db.fileControl(constants.SQLITE_FCNTL_PERSIST_WAL, 0) after enabling WAL (e.g.,
after db.run("PRAGMA journal_mode = WAL;")) so SQLite will clean up sidecar
files on db.close(), then present manual rmSync deletion as a fallback and use
rmSync("mydb.sqlite-wal", { force: true }) and rmSync("mydb.sqlite-shm", {
force: true }) to avoid errors when removing files.


### `using` statement

You can use the `using` statement to ensure that a database connection is closed when the `using` block is exited.
Expand Down