# 機能設計書 2-データベース接続管理

## 概要

本ドキュメントは、SQLiteデータベースへの接続のオープンおよびクローズ処理について、その設計と実装の詳細を記述する。sqlite3_open()、sqlite3_open_v2()、sqlite3_open16()、sqlite3_close()、sqlite3_close_v2()関数を中心とした接続管理の仕組みについて解説する。

### 本機能の処理概要

**業務上の目的・背景**：SQLiteを使用するアプリケーションは、データベースファイルへのアクセスを開始するために接続を確立し、使用終了時には接続を適切にクローズする必要がある。接続管理はリソースの適切な確保・解放、トランザクションの整合性、およびマルチスレッド環境での安全なデータベースアクセスを保証する基盤となる。

**機能の利用シーン**：
- アプリケーション起動時にデータベースファイルを開く場面
- 新規データベースの作成が必要な場面
- インメモリデータベースを使用する場面（":memory:"指定）
- 一時データベースを使用する場面（""指定）
- 接続オプション（読み取り専用、共有キャッシュ等）を指定して開く場面
- アプリケーション終了時やリソース解放時にデータベース接続を閉じる場面
- WASMモジュールでのDB接続（new oo.DB()経由）

**主要な処理内容**：
1. sqlite3_initialize()による自動初期化（SQLITE_OMIT_AUTOINIT未定義時）
2. データベースファイル名の解析（URIファイル名対応）
3. VFSの選択と接続の確立
4. データベースハンドル（sqlite3*）の割り当てと初期化
5. 共有キャッシュモードの設定（オプション）
6. プリペアドステートメントとバックアップのクローズ確認
7. リソースの解放とハンドルの無効化

**関連システム・外部連携**：
- VFS（Virtual File System）：ファイルシステムアクセスの抽象化層
- 共有キャッシュ機能：複数接続間でのページキャッシュ共有
- WAL（Write-Ahead Logging）：高性能トランザクション処理

**権限による制御**：
- SQLITE_OPEN_READONLY：読み取り専用接続
- SQLITE_OPEN_READWRITE：読み書き可能接続
- SQLITE_OPEN_CREATE：ファイル未存在時に新規作成

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 基本デモ（UIスレッド版） | 主画面 | new oo.DB()によるインメモリDB作成・接続 |
| 4 | 基本デモ（Worker版） | 主画面 | Worker内でのDB接続管理 |
| 5 | JS Storage デモ | 主画面 | kvvfs VFSでのDB作成・接続 |
| 6 | Worker1 API デモ | 主画面 | Worker経由でのDB接続管理 |
| 7 | Worker1 Promiser デモ | 主画面 | Promise経由でのDB接続管理 |
| 8 | SQLite3 Fiddle | 主画面 | インメモリDBまたは永続DBの接続管理 |
| 12 | Tester1（メインスレッド版） | 主画面 | テスト用DB接続・切断処理 |
| 13 | Tester1（Worker版） | 主画面 | Worker内でのテスト用DB管理 |

## 機能種別

リソース管理機能（データベース接続の確立・解放）

## 入力仕様

### 入力パラメータ

#### sqlite3_open() / sqlite3_open16()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| zFilename | const char* / const void* | Yes | データベースファイル名（UTF-8/UTF-16） | NULL可（空文字列として扱う） |
| ppDb | sqlite3** | Yes | 接続ハンドルの格納先 | NULL不可（SQLITE_MISUSE） |

#### sqlite3_open_v2()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filename | const char* | Yes | データベースファイル名（UTF-8） | NULL可 |
| ppDb | sqlite3** | Yes | 接続ハンドルの格納先 | NULL不可 |
| flags | int | Yes | オープンフラグの組み合わせ | 有効なフラグの組み合わせ |
| zVfs | const char* | No | 使用するVFS名 | NULL時はデフォルトVFS |

#### sqlite3_close() / sqlite3_close_v2()

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| db | sqlite3* | No | クローズする接続ハンドル | NULL時はno-op |

### 入力データソース

- ファイルシステム上のデータベースファイル
- URIファイル名パラメータ（mode=、cache=等）
- VFS設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 戻り値 | int | SQLITE_OK（成功）、またはエラーコード |
| *ppDb | sqlite3* | 有効な接続ハンドル（エラー時もNULL以外の可能性あり） |

### 出力先

- アプリケーションメモリ：接続ハンドル
- ファイルシステム：新規データベースファイル（CREATE時）

## 処理フロー

### 処理シーケンス（オープン処理）

```
1. API装甲チェック
   └─ ppDbがNULLの場合はSQLITE_MISUSEを返却

2. 自動初期化
   └─ sqlite3_initialize()を呼び出し

3. スレッドセーフモード判定
   └─ グローバル設定に基づきミューテックス動作を決定

4. データベースハンドル割り当て
   └─ sqlite3構造体のメモリ確保と初期化

5. ファイル名解析
   └─ URIファイル名のパラメータ抽出

6. VFS選択
   └─ 指定VFSまたはデフォルトVFSを選択

7. データベースファイルオープン
   └─ VFS経由でファイルをオープン

8. スキーマ読み込み
   └─ sqlite_schemaテーブルからスキーマ情報を取得

9. 結果返却
   └─ SQLITE_OKまたはエラーコードを返却
```

### 処理シーケンス（クローズ処理）

```
1. NULLチェック
   └─ NULLの場合は即座にSQLITE_OKを返却

2. 安全性チェック
   └─ sqlite3SafetyCheckSickOrOk()で状態確認

3. 未完了リソース確認
   └─ プリペアドステートメント、バックアップの存在確認

4. sqlite3_close()の場合
   └─ 未完了リソースがあればSQLITE_BUSYを返却

5. sqlite3_close_v2()の場合
   └─ 接続をzombie状態に移行し、リソース解放を遅延

6. リソース解放
   └─ スキーマ、キャッシュ、ミューテックス等を解放

7. ハンドル解放
   └─ sqlite3構造体のメモリを解放
```

### フローチャート

```mermaid
flowchart TD
    A[sqlite3_open開始] --> B{ppDb == NULL?}
    B -->|Yes| C[SQLITE_MISUSE返却]
    B -->|No| D[sqlite3_initialize]
    D --> E[sqlite3構造体割り当て]
    E --> F[ファイル名解析]
    F --> G[VFS選択]
    G --> H[ファイルオープン]
    H --> I{成功?}
    I -->|Yes| J[スキーマ読み込み]
    I -->|No| K[エラーハンドル設定]
    J --> L[SQLITE_OK返却]
    K --> M[エラーコード返却]
```

```mermaid
flowchart TD
    A[sqlite3_close開始] --> B{db == NULL?}
    B -->|Yes| C[SQLITE_OK返却]
    B -->|No| D{未完了リソースあり?}
    D -->|Yes sqlite3_close| E[SQLITE_BUSY返却]
    D -->|Yes sqlite3_close_v2| F[zombie状態に移行]
    D -->|No| G[リソース解放]
    F --> H[遅延解放設定]
    G --> I[SQLITE_OK返却]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 自動初期化 | sqlite3_open系関数は内部でsqlite3_initialize()を呼び出す | SQLITE_OMIT_AUTOINIT未定義時 |
| BR-002 | ファイル未存在時動作 | SQLITE_OPEN_CREATE指定時のみ新規作成 | sqlite3_open_v2使用時 |
| BR-003 | インメモリDB | ":memory:"指定でメモリ上にDB作成 | 常時 |
| BR-004 | 一時DB | 空文字列指定で一時ファイルにDB作成 | 常時 |
| BR-005 | 接続クローズの安全性 | 未完了リソースがある場合のcloseの挙動が異なる | close vs close_v2 |
| BR-006 | NULL引数許容 | sqlite3_close/close_v2はNULLを安全に受け入れる | 常時 |

### 計算ロジック

特に計算ロジックは存在しない。

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| オープン時 | sqlite_schema | SELECT | スキーマ情報の読み込み |

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

#### sqlite_schema

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | type, name, tbl_name, rootpage, sql | 全行 | スキーマ初期化時 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SQLITE_CANTOPEN | ファイルオープン失敗 | ファイルが存在しない（CREATE未指定） | パスの確認、権限の確認 |
| SQLITE_NOTADB | 非DBファイル | ファイルがSQLite形式でない | 正しいDBファイルを指定 |
| SQLITE_BUSY | リソース使用中 | 未完了リソースあり（sqlite3_close） | リソースをfinalize後に再試行 |
| SQLITE_NOMEM | メモリ不足 | ハンドル割り当て失敗 | メモリを解放して再試行 |
| SQLITE_MISUSE | 不正使用 | ppDbがNULL、または不正な状態 | 正しい引数で呼び出し |
| SQLITE_CORRUPT | DB破損 | スキーマ読み込み時に破損検出 | DBの修復または再作成 |

### リトライ仕様

- SQLITE_BUSYエラー時は、未完了リソースを解放後に再試行可能
- ファイルロック関連のエラーは時間をおいて再試行可能

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

- オープン時：暗黙のトランザクションは開始されない
- クローズ時：未コミットのトランザクションは自動的にロールバック

## パフォーマンス要件

- データベースオープンは通常100ミリ秒以内に完了（ファイルサイズ依存）
- スキーマ読み込みは複雑なスキーマで時間がかかる可能性あり
- インメモリデータベースはファイルI/Oがないため高速

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

- SQLITE_OPEN_READONLYによる書き込み防止
- URIファイル名のパラメータインジェクション対策
- シンボリックリンク攻撃への対策（VFS実装依存）

## 備考

- sqlite3_close_v2()は「遅延クローズ」として設計されており、未完了リソースが解放された時点で自動的にクローズが完了する
- エラー発生時でもハンドルが返される場合があり、エラー詳細取得後にsqlite3_close()が必要

---

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

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

### 推奨読解順序

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

まず、データベース接続を表す構造体を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | sqliteInt.h | `src/sqliteInt.h` | sqlite3構造体の定義、eOpenState等のフィールド |
| 1-2 | sqlite3.h | `src/sqlite3.h` | 公開APIの定義、フラグ定数 |

**読解のコツ**: sqlite3構造体はデータベース接続の状態を全て保持する。特にeOpenState（SQLITE_STATE_OPEN、SQLITE_STATE_ZOMBIE等）が接続状態を管理する。

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

処理の起点となる公開API関数を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.c | `src/main.c` | sqlite3_open()、sqlite3_open_v2()、sqlite3_close()の実装 |

**主要処理フロー（オープン）**:
1. **3677-3683行目**: sqlite3_open()のエントリーポイント、openDatabase()へ委譲
2. **3684-3691行目**: sqlite3_open_v2()のエントリーポイント、フラグとVFS名を受け取る
3. **3316-3670行目**: openDatabase()の本体実装
4. **3329-3335行目**: API装甲とsqlite3_initialize()呼び出し
5. **3355-3361行目**: フラグのバリデーション

**主要処理フロー（クローズ）**:
1. **1343行目**: sqlite3_close()の定義、sqlite3Close(db,0)へ委譲
2. **1344行目**: sqlite3_close_v2()の定義、sqlite3Close(db,1)へ委譲
3. **1246-1290行目**: sqlite3Close()の本体実装
4. **1248-1250行目**: NULL引数のno-op処理

#### Step 3: 内部実装を理解する

接続確立の詳細な処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | main.c | `src/main.c` | openDatabase()の詳細実装 |
| 3-2 | main.c | `src/main.c` | sqlite3ParseUri()によるURIファイル名解析 |

**主要処理フロー**:
- **3034-3188行目**: sqlite3ParseUri()でURIファイル名を解析
- **3400-3500行目**: sqlite3BtreeOpen()でB-Tree接続を確立

#### Step 4: リソース解放処理を理解する

クローズ時のリソース解放処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | main.c | `src/main.c` | sqlite3Close()とsqlite3LeaveMutexAndCloseZombie() |
| 4-2 | main.c | `src/main.c` | connectionIsBusy()による未完了リソース確認 |

**主要処理フロー**:
- **1356-1420行目**: sqlite3LeaveMutexAndCloseZombie()でのリソース解放
- **1220-1240行目**: connectionIsBusy()での未完了チェック

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

```
sqlite3_open() / sqlite3_open_v2()        [main.c:3677/3684]
    │
    ├─ sqlite3_initialize()               [main.c:190]
    │
    └─ openDatabase()                     [main.c:3316]
           │
           ├─ sqlite3MallocZero()         メモリ確保
           │
           ├─ sqlite3ParseUri()           [main.c:3034]
           │      └─ URIファイル名解析
           │
           ├─ sqlite3_vfs_find()          VFS検索
           │
           ├─ sqlite3BtreeOpen()          [btree.c]
           │      └─ B-Tree接続確立
           │
           └─ sqlite3Init()               スキーマ初期化
                  └─ sqlite_schema読み込み

sqlite3_close() / sqlite3_close_v2()      [main.c:1343/1344]
    │
    └─ sqlite3Close()                     [main.c:1246]
           │
           ├─ connectionIsBusy()          [main.c:1220]
           │      └─ 未完了リソース確認
           │
           ├─ sqlite3VtabRollback()       仮想テーブルロールバック
           │
           └─ sqlite3LeaveMutexAndCloseZombie()  [main.c:1356]
                  │
                  ├─ sqlite3BtreeClose()  B-Tree接続クローズ
                  │
                  └─ sqlite3DbFree()      メモリ解放
```

### データフロー図

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

ファイル名          ───▶ sqlite3_open()           ───▶ sqlite3*ハンドル
フラグ                        │
VFS名                         ├─▶ URIパラメータ解析
                              ├─▶ VFS選択
                              ├─▶ ファイルオープン
                              └─▶ スキーマ読み込み

sqlite3*ハンドル    ───▶ sqlite3_close()          ───▶ SQLITE_OK/BUSY
                              │
                              ├─▶ 未完了チェック
                              ├─▶ トランザクションロールバック
                              └─▶ リソース解放
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.c | `src/main.c` | ソース | sqlite3_open/close系APIの実装 |
| sqliteInt.h | `src/sqliteInt.h` | ヘッダー | sqlite3構造体定義 |
| sqlite3.h | `src/sqlite3.h` | ヘッダー | 公開API・定数定義 |
| btree.c | `src/btree.c` | ソース | B-Tree接続管理 |
| pager.c | `src/pager.c` | ソース | ページャー（ファイルI/O） |
| os_unix.c | `src/os_unix.c` | ソース | UNIX系VFS実装 |
| vdbeapi.c | `src/vdbeapi.c` | ソース | プリペアドステートメント管理 |
| prepare.c | `src/prepare.c` | ソース | スキーマ初期化処理 |
