# 儲存後端

HakoRun 以建置標籤在 ToriiDB 與 Redis 之間切換，兩者使用相同的 key 配置與版本語意。

## 選擇後端

| 後端 | 建置指令 | 位置 | 說明 |
|------|----------|------|------|
| ToriiDB | `make build`（預設） | `~/.config/pardnchiu/hakorun` | 內嵌儲存，不需額外服務 |
| Redis | `make build redis`（`-tags redis`） | `REDIS_HOST:REDIS_PORT` 的 `REDIS_DB` | 啟動時 `PING` 失敗即結束行程 |

兩者實作同一介面（`internal/database/database.go`）：

```go
type backend interface {
    Add(ctx context.Context, script Script) (int64, error)
    Get(ctx context.Context, path string, version int64) (*Script, error)
    Close() error
}
```

## Key 配置

`hash` 為 `md5(path)` 的十六進位字串。

| Key | ToriiDB | Redis |
|-----|---------|-------|
| `meta:<hash>` | JSON：`path`、`language`、`latest`、`versions` | Hash：`path`、`language`、`latest` |
| `code:<hash>:<timestamp>` | 程式碼字串 | 程式碼字串 |
| 版本清單 | 存在 `meta` 的 `versions` 陣列 | Set `meta:<hash>:version` |

## 寫入與讀取

| 操作 | 行為 |
|------|------|
| `Add` | ToriiDB 先寫 `code` 再寫 `meta`，確保 `meta` 不會指向不存在的版本；Redis 以 pipeline 一次送出 |
| `Get`（`version = 0`） | 讀 `meta` 的 `latest` 後取對應 `code` |
| `Get`（指定版本） | 直接取 `code:<hash>:<version>`；不存在回 `assign version not found` |
| 找不到 `meta` | 回 `script not found`，handler 轉為 HTTP 404 |

Handler 對儲存操作使用 5 秒逾時。

## 相關頁面

- [核心概念](/zh/core-concepts)
- [設定](/zh/configuration)
