# 画面設計書 8-SQLite3Fiddle

## 概要

本ドキュメントは、WebAssembly版SQLite CLIシェルのHTMLフロントエンド（fiddle/index.c-pp.html）の画面設計書です。

### 本画面の処理概要

この画面は、SQLite3のCLIシェルをWebブラウザ上で実行できる対話型アプリケーションを提供します。

**業務上の目的・背景**：SQLite3の機能を手軽に試したい開発者やデータベース学習者向けに、インストール不要でブラウザから直接SQLを実行できる環境を提供します。SQL入力、実行結果表示、データベースのインポート/エクスポート機能を備えた本格的なSQLiteシェルのWeb版です。教育目的やプロトタイピング、SQLの動作確認に最適です。

**画面へのアクセス方法**：HTTPサーバー経由で `fiddle/index.html` にアクセスします。C preprocessorテンプレート（.c-pp.html）からビルド時に生成されます。

**主要な操作・処理内容**：
1. SQL入力 - テキストエリアにSQL文またはシェルコマンドを入力
2. SQL実行 - Runボタンまたはctrl-enter/shift-enterで実行
3. 結果表示 - 出力エリアに実行結果を表示
4. DBインポート - 外部SQLiteファイルを読み込み
5. DBエクスポート - 現在のDBをファイルとしてダウンロード
6. DBリセット - トランジェントDBをリセット
7. 表示モード切り替え - Side-by-side、Swap in/out、Terminal mode等

**画面遷移**：
- 遷移先画面：About画面（モーダル）
- 遷移元画面：index.html

**権限による表示制御**：なし

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | SQLiteライブラリ初期化 | 主機能 | fiddle.jsによるWASM CLIシェル初期化 |
| 2 | データベース接続管理 | 主機能 | インメモリDBまたは永続DBの接続管理 |
| 5 | SQLパーサー/トークナイザー | 主機能 | ユーザー入力SQLの解析処理 |
| 6 | SELECT文処理 | 主機能 | SQLクエリ実行と結果表示 |
| 7 | INSERT文処理 | 主機能 | データ挿入SQLの実行 |
| 8 | UPDATE文処理 | 主機能 | データ更新SQLの実行 |
| 9 | DELETE文処理 | 主機能 | データ削除SQLの実行 |
| 10 | CREATE TABLE処理 | 主機能 | テーブル作成DDLの実行 |
| 11 | DROP TABLE処理 | 主機能 | テーブル削除DDLの実行 |
| 26 | PRAGMA | 補助機能 | DB設定変更（.headers on等のシェルコマンド） |
| 43 | OS抽象化層（VFS） | 補助機能 | DB import/export機能でのファイルアクセス |

## 画面種別

アプリケーション（対話型）

## URL/ルーティング

`ext/wasm/fiddle/index.c-pp.html`（ソース）
`ext/wasm/fiddle/index.html`（ビルド後）

## 入出力項目

| 項目名 | 入出力 | 型 | 説明 |
|--------|--------|-----|------|
| SQL入力エリア | 入力 | テキスト | SQL文またはシェルコマンド |
| 実行結果エリア | 出力 | テキスト | SQL実行結果 |
| Runボタン | 入力 | クリック | SQL実行 |
| Clear Inputボタン | 入力 | クリック | 入力エリアクリア |
| Clear Outputボタン | 入力 | クリック | 出力エリアクリア |
| Load DB | 入力 | ファイル | DBファイルインポート |
| Download DB | 入力 | クリック | DBファイルエクスポート |
| Reset DB | 入力 | クリック | DBリセット |
| Examplesセレクト | 入力 | 選択 | サンプルSQLの選択 |
| Side-by-side | 入力 | チェックボックス | レイアウト切り替え |
| Swap in/out | 入力 | チェックボックス | 入出力位置の入れ替え |
| Auto-scroll output | 入力 | チェックボックス | 自動スクロール |
| Auto-clear output | 入力 | チェックボックス | 実行前の出力クリア |

## 表示項目

| 項目名 | 表示位置 | 説明 |
|--------|----------|------|
| タイトルバー | ヘッダー | "SQLite3 Fiddle" + "Powered by SQLite3"リンク |
| 初期化スピナー | 中央 | WASM初期化中に表示 |
| SQL入力エリア | メインビュー | テキストエリア（モノスペースフォント） |
| 出力エリア | メインビュー | 読み取り専用テキストエリア |
| オプションフィールドセット | 下部 | 各種設定ボタンとチェックボックス |
| About画面 | モーダル | アプリケーション説明 |
| WASMポインタサイズ | オプション | "WASM: 32-bit" または "WASM: 64-bit" |

## イベント仕様

### 1-ページロード（初期化）

**トリガー**: ページロード完了時

**処理内容**:
1. **fiddle.js行329**: `new Worker('fiddle-worker.js')` でWorker作成
2. **行330**: `SF.worker.onmessage` でメッセージハンドラ設定
3. **行413-416**: 'fiddle-ready'イベント受信で `onSFLoaded()` 実行
4. **行561-893**: UI初期化、イベントハンドラ登録

### 2-SQL実行（Runボタン）

**トリガー**: Runボタンクリック、またはctrl-enter/shift-enter

**処理内容**:
```javascript
btnShellExec.addEventListener('click',function(ev){
  let sql;
  if(taInput.selectionStart<taInput.selectionEnd){
    sql = taInput.value.substring(taInput.selectionStart,taInput.selectionEnd).trim();
  }else{
    sql = taInput.value.trim();
  }
  if(sql) SF.dbExec(sql);
},false);
```

**行番号**: 598-607

**処理フロー**:
1. 選択範囲があればその部分のみ、なければ全文を取得
2. `SF.dbExec(sql)` でWorkerにSQL送信
3. 'working'/'start'イベント → 実行中表示
4. 'stdout'/'stderr'イベント → 結果表示
5. 'working'/'end'イベント → 完了処理

### 3-DBインポート

**トリガー**: Load DBボタンクリック後にファイル選択

**処理内容**:
```javascript
eLoadDb.addEventListener('change',function(){
  const f = this.files[0];
  const r = new FileReader();
  r.addEventListener('load', function(){
    SF.wMsg('open',{
      filename: f.name,
      buffer: this.result
    }, [this.result]);
  });
  r.readAsArrayBuffer(f);
});
```

**行番号**: 753-782

### 4-DBエクスポート

**トリガー**: Download DBボタンクリック

**処理内容**:
```javascript
btnExport.addEventListener('click',function(){
  enableMutatingElements(false);
  SF.wMsg('db-export');
});

SF.addMsgHandler('db-export', function(ev){
  const blob = new Blob([ev.buffer], {type:"application/x-sqlite3"});
  const a = document.createElement('a');
  a.href = window.URL.createObjectURL(blob);
  a.download = ev.filename;
  a.click();
});
```

**行番号**: 724-749

### 5-DBリセット

**トリガー**: Reset DBボタンクリック

**処理内容**:
```javascript
SF.resetDb = function(){
  if(window.confirm("Really destroy all content and tables "
                    +"in the (transient) db?")){
    this.wMsg('db-reset');
  }
  return this;
};
```

**行番号**: 301-307

### 6-サンプルSQL選択

**トリガー**: Examplesセレクトで選択

**処理内容**:
```javascript
xElem.addEventListener('change', function(){
  taInput.value = '-- ' +
    this.selectedOptions[0].innerText +
    '\n' + this.value;
  SF.dbExec(this.value);
});
```

**行番号**: 854-859

**サンプル一覧**:
- Help: .help
- Box Mode: .mode box
- Setup table T: CREATE TABLE + INSERT + SELECT
- sqlite_schema: select * from sqlite_schema
- Mandelbrot: 再帰CTEによるフラクタル生成
- JSON pretty-print: json_pretty()使用例

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| SQL実行 | 任意 | 任意 | ユーザー入力に依存 |
| DBインポート | 全体 | REPLACE | 外部DBファイルで置換 |
| DBエクスポート | 全体 | READ | 現在のDBを取得 |
| DBリセット | 全体 | DELETE | トランジェントDBを初期化 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|----------|
| LOG-001 | 情報 | "SQLite version X.X.X" | 初期化完了時 |
| LOG-002 | 情報 | SQL実行結果 | SQL実行後 |
| LOG-003 | 情報 | "Exported (possibly auto-downloaded): {filename}" | エクスポート完了時 |
| LOG-004 | 情報 | "Loaded {filename}. Opening db..." | インポート中 |
| ERR-001 | エラー | "Export failed: {error}" | エクスポート失敗時 |
| ERR-002 | エラー | "Loading {filename} failed for unknown reasons." | インポート失敗時 |

## 例外処理

| 例外状況 | 対応処理 |
|---------|----------|
| WASMロード失敗 | モジュールステータスにエラー表示 |
| SQL実行エラー | stderrハンドラで出力エリアに赤色表示 |
| DBインポート失敗 | FileReader errorイベントでエラー表示 |
| DBエクスポート失敗 | エラーメッセージを出力エリアに表示 |

## 備考

- デフォルトでインメモリDB（トランジェント）
- 永続ストレージオプションが利用可能な場合はヘルプに表示
- jquery.terminalによるターミナルモードはオプション
- localStorage/sessionStorageで設定を永続化
- URLパラメータ `?sql=...` で初期SQL指定可能
- URLパラメータ `?about` でAbout画面を初期表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | fiddle.js | `ext/wasm/fiddle/fiddle.js` | SqliteFiddle (SF) オブジェクトの構造 |

**読解のコツ**:
- `SF` (SqliteFiddle) がアプリケーションのメインオブジェクト
- `SF.config` に設定を格納
- `SF._msgMap` にWorkerメッセージハンドラを登録
- `SF.worker` がWorkerインスタンス

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.c-pp.html | `ext/wasm/fiddle/index.c-pp.html` | HTML構造とfiddle.js読み込み |
| 2-2 | fiddle.js | `ext/wasm/fiddle/fiddle.js` | SF初期化とWorker作成 |

**主要処理フロー**:
1. **行402**: fiddle.js読み込み
2. **行329**: `new Worker('fiddle-worker.js')` でWorker作成
3. **行330**: `SF.worker.onmessage` 設定
4. **行413-416**: 'fiddle-ready'で `onSFLoaded()` 実行

#### Step 3: Workerとの通信を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fiddle.js | `ext/wasm/fiddle/fiddle.js` | SF.wMsg()とaddMsgHandler() |

**主要処理フロー**:
- **行293-296**: `SF.wMsg(type, data)` でWorkerにメッセージ送信
- **行265-274**: `SF.addMsgHandler(type, callback)` でハンドラ登録
- **行276-286**: `SF.runMsgHandlers(msg)` でメッセージルーティング

#### Step 4: UI操作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | fiddle.js | `ext/wasm/fiddle/fiddle.js` | onSFLoaded()内のイベントハンドラ設定 |

**主要処理フロー**:
- **行572-573**: Reset DBボタン
- **行579-582**: Clear Inputボタン
- **行598-607**: Runボタン
- **行660-687**: チェックボックスのdata-config/data-csstgt処理

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

```
index.html (ページロード)
    │
    └─ fiddle.js
           │
           ├─ storage モジュール初期化
           │      └─ localStorage/sessionStorage/transient選択
           │
           ├─ SqliteFiddle (SF) オブジェクト定義
           │      ├─ config
           │      ├─ echo()
           │      ├─ addMsgHandler()
           │      ├─ wMsg()
           │      └─ resetDb()
           │
           ├─ new Worker('fiddle-worker.js')
           │      └─ onmessage → SF.runMsgHandlers()
           │
           └─ 'fiddle-ready' 受信
                  └─ onSFLoaded()
                         ├─ UI初期化
                         ├─ イベントハンドラ登録
                         ├─ サンプルSQL設定
                         └─ URLパラメータ処理
```

### データフロー図

```
[ユーザー入力]          [メインスレッド]           [Worker]

SQL入力
    │
    └── Runボタン ─────▶ SF.dbExec()
                              │
                              └── SF.wMsg('shellExec', sql)
                                        │
                                        └─────────────────▶ SQL実行
                                                                │
SF.echo() ◀───────────────── 'stdout'/'stderr' ◀───────────────┘
    │
    ▼
出力エリア表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.c-pp.html | `ext/wasm/fiddle/index.c-pp.html` | テンプレート | C preprocessorテンプレート |
| index.html | `ext/wasm/fiddle/index.html` | テンプレート | ビルド後HTML |
| fiddle.js | `ext/wasm/fiddle/fiddle.js` | ソース | メインアプリケーションロジック |
| fiddle-worker.js | `ext/wasm/fiddle/fiddle-worker.js` | ソース | Worker側SQLite実行エンジン |
| jquery.terminal.bundle.min.js | `ext/wasm/fiddle/jqterm/` | ライブラリ | ターミナルモード（オプション） |
