# 機能設計書 61-bun:sqlite

## 概要

本ドキュメントは、Bunランタイムが提供するSQLiteデータベースアクセス機能（`bun:sqlite`モジュール）の設計仕様を記載する。

### 本機能の処理概要

`bun:sqlite`は、SQLiteデータベースへの高速かつシンプルなアクセスを提供するBun組み込みモジュールである。ネイティブ実装により、better-sqlite3互換のAPIを高速に提供し、同期的なデータベース操作を可能にする。

**業務上の目的・背景**：アプリケーション開発においてローカルデータベースは、設定管理、キャッシュ、セッションストア、オフラインデータ保存など多くの用途で必要とされる。SQLiteは軽量で設定不要なデータベースとして広く利用されており、Bunに組み込むことで、外部依存なしに高速なデータベース操作を実現する。

**機能の利用シーン**：
- ローカルアプリケーションのデータ永続化
- テスト用データベースの作成と操作
- 設定やキャッシュの保存
- 組み込みアプリケーションでのデータ管理
- CLIツールでのデータ処理

**主要な処理内容**：
1. データベース接続の作成・管理（インメモリ、ファイルベース）
2. SQLクエリの準備（prepare）と実行
3. パラメータ化クエリによる安全なデータ操作
4. トランザクション管理（BEGIN、COMMIT、ROLLBACK、SAVEPOINT）
5. クエリ結果のイテレーションと取得
6. データベースのシリアライズ/デシリアライズ

**関連システム・外部連携**：SQLite3ライブラリ（組み込み）との連携。`Bun.sql`（統一SQLインターフェース）からも利用可能。

**権限による制御**：ファイルシステムのアクセス権限に依存。読み取り専用モードでのデータベースオープンが可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はAPI専用であり、直接関連する画面はない |

## 機能種別

データ連携 / CRUD操作 / データベースアクセス

## 入力仕様

### 入力パラメータ

#### Database コンストラクタ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filename | string \| TypedArray \| undefined | No | データベースファイルパス。空文字列または`:memory:`でインメモリDB | 文字列型またはTypedArray型 |
| options | DatabaseOptions \| number | No | オープンオプションまたはフラグ値 | オブジェクト型または数値型 |

#### DatabaseOptions

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| readonly | boolean | No | 読み取り専用モード | - |
| create | boolean | No | 存在しない場合に作成 | - |
| readwrite | boolean | No | 読み書きモード | - |
| strict | boolean | No | 厳格モード | - |
| safeIntegers | boolean | No | BigIntで整数を返す | - |

#### Statement.run / get / all / values

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ...params | any[] \| object | No | バインドパラメータ | - |

### 入力データソース

- ファイルシステム上のSQLiteデータベースファイル（.db, .sqlite, .sqlite3など）
- インメモリデータベース（`:memory:`）
- シリアライズされたデータベース（Uint8Array等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Database | Database | データベースインスタンス |
| Statement | Statement | プリペアドステートメント |
| run結果 | { changes: number, lastInsertRowid: number \| bigint } | 変更件数と最終挿入行ID |
| get結果 | object \| null | 単一行のオブジェクト |
| all結果 | object[] | 全行の配列 |
| values結果 | any[][] | 全行の値配列 |

### 出力先

- JavaScript オブジェクト（クエリ結果）
- ファイルシステム（serialize時）

## 処理フロー

### 処理シーケンス

```
1. データベースオープン
   └─ SQLiteファイルを開く、またはインメモリDBを作成
2. ステートメント準備
   └─ SQLクエリをプリペアドステートメントとしてコンパイル
3. パラメータバインド
   └─ クエリパラメータを安全にバインド
4. クエリ実行
   └─ run/get/all/values/iterateで結果を取得
5. 結果処理
   └─ JavaScriptオブジェクトに変換して返却
6. ステートメント解放
   └─ finalize()またはSymbol.dispose
7. データベースクローズ
   └─ close()またはSymbol.dispose
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{ファイルパス指定?}
    B -->|Yes| C[ファイルDBをオープン]
    B -->|No/:memory:| D[インメモリDBを作成]
    C --> E[Databaseインスタンス生成]
    D --> E
    E --> F{クエリ実行?}
    F -->|prepare| G[Statementを作成]
    F -->|query| H[キャッシュ付きStatement取得]
    F -->|run| I[直接SQL実行]
    G --> J[パラメータバインド]
    H --> J
    J --> K{実行メソッド}
    K -->|run| L[変更件数を返却]
    K -->|get| M[1行を返却]
    K -->|all| N[全行を返却]
    K -->|values| O[値配列を返却]
    K -->|iterate| P[イテレータを返却]
    L --> Q{継続?}
    M --> Q
    N --> Q
    O --> Q
    P --> Q
    I --> Q
    Q -->|Yes| F
    Q -->|No| R[close/dispose]
    R --> S[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | クエリキャッシュ | query()メソッドは最大20件までステートメントをキャッシュする | query()メソッド使用時 |
| BR-002 | トランザクション自動管理 | transaction()でラップされた関数は自動的にBEGIN/COMMITされる | transaction()使用時 |
| BR-003 | ネストトランザクション | トランザクション内でのトランザクションはSAVEPOINTで処理 | 既存トランザクション内でtransaction()実行時 |
| BR-004 | 読み取り専用制約 | readonlyモードではデータ変更不可 | readonly: true指定時 |

### 計算ロジック

- `changes`: 直前のINSERT/UPDATE/DELETEで影響を受けた行数
- `lastInsertRowid`: 直前のINSERTで生成されたROWID

## データベース操作仕様

### 操作別データベース影響一覧

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| run() | 任意 | INSERT/UPDATE/DELETE/DDL | SQLを直接実行 |
| prepare() | なし | - | ステートメントを準備 |
| query() | なし | - | キャッシュ付きステートメント準備 |
| transaction() | なし | BEGIN/COMMIT/ROLLBACK | トランザクション制御 |

### テーブル別操作詳細

本機能は汎用データベースアクセスのため、特定テーブルに依存しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SQLiteError | データベースエラー | SQL構文エラー、制約違反など | エラーメッセージを確認し、SQL修正 |
| TypeError | 型エラー | 不正なパラメータ型 | 正しい型のパラメータを渡す |
| Error | 一般エラー | インメモリDBを読み取り専用でオープン | 有効なオプション組み合わせを使用 |

### リトライ仕様

SQLiteはファイルロック時にBUSYエラーを返す。アプリケーション側でリトライロジックを実装する必要がある。

## トランザクション仕様

- `transaction(fn)`: 関数をトランザクションでラップ
- デフォルト: `BEGIN`
- `deferred`: `BEGIN DEFERRED`
- `immediate`: `BEGIN IMMEDIATE`
- `exclusive`: `BEGIN EXCLUSIVE`
- エラー発生時は自動ロールバック
- ネストはSAVEPOINTで実現

## パフォーマンス要件

- ネイティブ実装により、better-sqlite3と同等以上の性能
- プリペアドステートメントの再利用でパフォーマンス向上
- query()メソッドによるステートメントキャッシュ（最大20件）

## セキュリティ考慮事項

- パラメータ化クエリによるSQLインジェクション防止
- 読み取り専用モードによるデータ保護
- ファイルシステム権限による アクセス制御

## 備考

- better-sqlite3との互換性を意識したAPI設計
- Symbol.disposeによるリソース管理をサポート
- `Bun.sql`からも利用可能な統一インターフェースを提供

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、モジュールのエクスポート構造とインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sqlite.ts | `src/js/bun/sqlite.ts` | Database、Statement、SQLiteErrorクラスの構造 |

**読解のコツ**: TypeScriptの型定義（`SqliteTypes`）を参照しながら、各クラスのプロパティとメソッドの関係を把握する。`#raw`プライベートフィールドがC++実装への橋渡しであることを意識する。

#### Step 2: エントリーポイントを理解する

処理の起点となるDatabaseクラスのコンストラクタを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | sqlite.ts | `src/js/bun/sqlite.ts` | Databaseコンストラクタ（346-425行目） |

**主要処理フロー**:
1. **349-375行目**: TypedArray入力時のデシリアライズ処理
2. **377-412行目**: オプション解析とフラグ設定
3. **419-424行目**: SQLite DBのオープン（`SQL.open`呼び出し）

#### Step 3: ステートメント処理を理解する

Statementクラスの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | sqlite.ts | `src/js/bun/sqlite.ts` | Statementクラス（130-341行目） |

**主要処理フロー**:
- **131-154行目**: コンストラクタでパラメータ数に応じてメソッド最適化
- **187-213行目**: パラメータなしの高速パス
- **230-309行目**: パラメータありのメソッド実装

#### Step 4: トランザクション処理を理解する

トランザクション管理の実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | sqlite.ts | `src/js/bun/sqlite.ts` | transaction()メソッドとヘルパー関数（584-666行目） |

**主要処理フロー**:
- **617-639行目**: getController()でトランザクション制御用ステートメントを準備
- **642-666行目**: wrapTransaction()でトランザクションをラップ

#### Step 5: SQLアダプターを理解する

Bun.sql統一インターフェースとの連携を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | sqlite.ts | `src/js/internal/sql/sqlite.ts` | SQLiteAdapter、SQLiteQueryHandle |

**主要処理フロー**:
- **209-286行目**: SQLiteQueryHandle.run()でクエリ実行
- **288-715行目**: SQLiteAdapterクラスの接続・クエリ管理

### プログラム呼び出し階層図

```
Bun.sql / bun:sqlite
    │
    ├─ Database (sqlite.ts:345)
    │      ├─ SQL.open (C++バインディング)
    │      ├─ prepare() → Statement
    │      ├─ query() → キャッシュ付きStatement
    │      ├─ run() → SQL.run
    │      └─ transaction() → wrapTransaction()
    │
    ├─ Statement (sqlite.ts:130)
    │      ├─ #raw (CppSQLStatement)
    │      │      ├─ run()
    │      │      ├─ get()
    │      │      ├─ all()
    │      │      ├─ values()
    │      │      └─ iterate()
    │      └─ finalize()
    │
    └─ SQLiteAdapter (internal/sql/sqlite.ts:288)
           ├─ createQueryHandle()
           ├─ normalizeQuery()
           └─ connect() / close()
```

### データフロー図

```
[入力]                    [処理]                         [出力]

SQLクエリ文字列 ───────▶ Database.prepare() ───────▶ Statement
                                │
パラメータ配列/オブジェクト ──▶ Statement.run/get/all ──▶ 結果オブジェクト
                                │
                                ▼
                         SQL.run (C++) ───────▶ { changes, lastInsertRowid }
                                │
                                ▼
                         SQLite3 エンジン
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| sqlite.ts | `src/js/bun/sqlite.ts` | ソース | メインモジュール実装 |
| sqlite.ts | `src/js/internal/sql/sqlite.ts` | ソース | Bun.sql用アダプター |
| JSSQLStatement.cpp | `src/bun.js/bindings/JSSQLStatement.cpp` | ソース | C++バインディング |
| query.ts | `src/js/internal/sql/query.ts` | ソース | クエリ基底クラス |
| shared.ts | `src/js/internal/sql/shared.ts` | ソース | 共通ユーティリティ |
| errors.ts | `src/js/internal/sql/errors.ts` | ソース | エラークラス定義 |
