# 機能設計書 19-Drizzle ORM統合

## 概要

本ドキュメントは、Payload CMSにおけるDrizzle ORM統合パッケージ（`@payloadcms/drizzle`）の設計を定義する。PostgreSQLおよびSQLiteデータベースアダプターの共通基盤として、スキーマ生成、クエリ構築、CRUD操作、マイグレーション機能を提供する。

### 本機能の処理概要

`@payloadcms/drizzle`パッケージは、Payload CMSのSQLデータベースアダプター（PostgreSQL、SQLite、Vercel Postgres、D1 SQLite）の共通実装を提供する中核パッケージである。PayloadのフィールドスキーマからDrizzle ORMのスキーマを生成し、共通のCRUD操作を実装する。

**業務上の目的・背景**：複数のSQLデータベースアダプターで共通するロジックを一元管理することで、コードの重複を排除し、保守性を向上させる。Drizzle ORMを抽象化レイヤーとして使用することで、異なるSQL方言間の互換性を確保する。

**機能の利用シーン**：
- PostgreSQL、SQLiteアダプターの内部処理
- Payloadフィールドからデータベーススキーマの自動生成
- クエリ構築とパラメータ解析
- マイグレーションファイルの生成・実行

**主要な処理内容**：
1. スキーマ生成：PayloadフィールドからRawTable/RawRelationを生成
2. クエリ構築：whereパラメータのSQL変換
3. CRUD操作：find、create、update、delete等の共通実装
4. マイグレーション：スキーマ変更の検出とマイグレーション生成

**関連システム・外部連携**：
- Drizzle ORM
- Drizzle Kit（マイグレーション）
- PostgreSQL / SQLiteアダプター

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | （該当なし） | - | データベース層のため画面連携なし |

## 機能種別

ORM統合 / データベース抽象化レイヤー

## 入力仕様

### DrizzleAdapter型

| プロパティ | 型 | 必須 | 説明 |
|-----------|-----|-----|------|
| drizzle | LibSQLDatabase / PostgresDB | Yes | Drizzleインスタンス |
| operators | Operators | Yes | クエリ演算子マップ |
| tables | Record<string, any> | Yes | テーブル定義 |
| relations | Record<string, GenericRelation> | Yes | リレーション定義 |
| rawTables | Record<string, RawTable> | Yes | 抽象テーブル定義 |
| rawRelations | Record<string, Record<string, RawRelation>> | Yes | 抽象リレーション定義 |
| schema | Record<string, unknown> | Yes | 統合スキーマ |
| tableNameMap | Map<string, string> | Yes | テーブル名マッピング |
| localesSuffix | string | No | ロケールテーブル接尾辞 |
| relationshipsSuffix | string | No | リレーションテーブル接尾辞 |
| versionsSuffix | string | No | バージョンテーブル接尾辞 |
| idType | 'serial' / 'uuid' | Yes | IDタイプ |
| blocksAsJSON | boolean | No | ブロックをJSON列で保存 |

## 出力仕様

PayloadのドキュメントフォーマットでJSON形式のデータを返却。

## 処理フロー

### スキーマ生成フロー

```
1. buildTable()呼び出し
   └─ Payloadフィールド定義を受け取る

2. traverseFields()
   └─ 各フィールドタイプに応じてカラム定義を生成
   └─ リレーション、配列、ブロックの特殊処理

3. RawTable/RawRelation生成
   └─ 抽象的なテーブル・リレーション定義を作成

4. buildDrizzleTable()（DB固有）
   └─ RawTableからDrizzleテーブルオブジェクトを生成

5. buildDrizzleRelations()
   └─ RawRelationからDrizzleリレーションを生成
```

### クエリ構築フロー

```
1. buildQuery()呼び出し
   └─ where句、sort、locale等を受け取る

2. parseParams()
   └─ whereオブジェクトをSQL条件に変換
   └─ 演算子マップを使用

3. buildOrderBy()
   └─ ソート条件を生成

4. 結果返却
   └─ joins、orderBy、selectFields、whereを返却
```

## ビジネスルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ロケールテーブル | ローカライズフィールドは専用テーブルに分離 | localization有効時 |
| BR-02 | リレーションテーブル | 多対多リレーションは中間テーブルを使用 | hasMany関係 |
| BR-03 | バージョンテーブル | バージョン管理有効時は別テーブルに保存 | versions有効時 |
| BR-04 | 演算子マッピング | Payload演算子をSQL演算子に変換 | whereクエリ時 |

## 演算子マッピング

| Payload演算子 | SQL演算子 | 説明 |
|--------------|----------|------|
| equals | eq | 等価 |
| not_equals | ne | 非等価 |
| greater_than | gt | より大きい |
| greater_than_equal | gte | 以上 |
| less_than | lt | より小さい |
| less_than_equal | lte | 以下 |
| contains | ilike | 部分一致（大文字小文字無視） |
| like | ilike | パターンマッチ |
| not_like | notIlike | パターン不一致 |
| in | inArray | 配列内に存在 |
| not_in | notInArray | 配列内に存在しない |
| exists | isNotNull | NULL以外 |
| and | and | AND条件 |
| or | or | OR条件 |

## 抽象テーブル構造

### RawColumn型

```typescript
type BaseRawColumn = {
  name: string
  notNull?: boolean
  primaryKey?: boolean
  default?: any
  reference?: {
    name: string
    table: string
    onDelete: UpdateDeleteAction
  }
}

// 各種カラムタイプ
type RawColumn =
  | { type: 'boolean' | 'geometry' | 'jsonb' | 'numeric' | 'serial' | 'text' | 'varchar' }
  | { type: 'timestamp', defaultNow?: boolean, precision: Precision, withTimezone?: boolean }
  | { type: 'uuid', defaultRandom?: boolean }
  | { type: 'enum', enumName: string, options: string[] }
  | { type: 'integer', autoIncrement?: boolean }
  | { type: 'vector', dimensions?: number }
```

### RawTable型

```typescript
type RawTable = {
  name: string
  columns: Record<string, RawColumn>
  foreignKeys?: Record<string, RawForeignKey>
  indexes?: Record<string, RawIndex>
}
```

## エクスポート一覧

### CRUD操作

| 関数名 | 説明 |
|--------|------|
| find | ドキュメント検索 |
| findOne | 単一ドキュメント検索 |
| findDistinct | 重複除外検索 |
| create | ドキュメント作成 |
| updateOne | 単一ドキュメント更新 |
| updateMany | 複数ドキュメント更新 |
| deleteOne | 単一ドキュメント削除 |
| deleteMany | 複数ドキュメント削除 |
| upsert | 作成または更新 |

### マイグレーション

| 関数名 | 説明 |
|--------|------|
| migrate | マイグレーション実行 |
| migrateDown | ロールバック |
| migrateFresh | 全テーブル再作成 |
| migrateRefresh | リセット後マイグレーション |
| migrateReset | マイグレーションリセット |
| migrateStatus | マイグレーション状態確認 |

### トランザクション

| 関数名 | 説明 |
|--------|------|
| beginTransaction | トランザクション開始 |
| commitTransaction | トランザクションコミット |
| rollbackTransaction | トランザクションロールバック |

---

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

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/drizzle/src/index.ts` | ソース | パッケージエントリーポイント |
| types.ts | `packages/drizzle/src/types.ts` | ソース | 共通型定義 |
| find.ts | `packages/drizzle/src/find.ts` | ソース | findオペレーション |
| create.ts | `packages/drizzle/src/create.ts` | ソース | createオペレーション |
| buildQuery.ts | `packages/drizzle/src/queries/buildQuery.ts` | ソース | クエリ構築 |
| operatorMap.ts | `packages/drizzle/src/queries/operatorMap.ts` | ソース | 演算子マッピング |
| build.ts | `packages/drizzle/src/schema/build.ts` | ソース | スキーマ生成 |

### 推奨リーディング順序

1. **types.ts** - DrizzleAdapter型、RawTable/RawColumn型の定義を確認
2. **index.ts** - エクスポート一覧でパッケージ構成を把握
3. **schema/build.ts** - buildTable()でスキーマ生成の流れを理解
4. **queries/buildQuery.ts** - クエリ構築ロジックを確認
5. **queries/operatorMap.ts** - 演算子マッピングを確認
6. **find.ts / create.ts** - CRUD操作の実装パターンを理解

### 主要処理フロー

#### types.ts

- **42-46行目**: PostgresDB、SQLiteDB型定義
- **77-89行目**: TransactionSQLite、TransactionPg型定義
- **91-122行目**: CountDistinct、DeleteWhere、Execute、Insert関数型
- **191-216行目**: RawTable、RawForeignKey、RawIndex型
- **221-313行目**: RawColumn各種型（timestamp、uuid、enum等）
- **384-438行目**: DrizzleAdapter型定義

#### queries/operatorMap.ts

- **39-57行目**: operatorMapオブジェクト
- **41行目**: contains: ilike（大文字小文字無視）
- **42行目**: equals: eq
- **50行目**: like: ilike
- **52行目**: not_like: notIlike

#### schema/build.ts

- **70-92行目**: buildTable関数のパラメータ定義
- **115-147行目**: traverseFields()でフィールド走査
- **158-178行目**: timestampsカラム（createdAt、updatedAt）の追加
- **189-241行目**: ロケールテーブルの生成
- **340-444行目**: textsテーブル（hasMany textフィールド用）
- **546-724行目**: relationshipsテーブル（多対多リレーション用）

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

```
@payloadcms/drizzle
├── スキーマ生成
│   ├── buildTable() - テーブル定義生成
│   │   ├── traverseFields() - フィールド走査
│   │   └── buildDrizzleRelations() - リレーション生成
│   └── buildRawSchema() - 抽象スキーマ構築
├── クエリ構築
│   ├── buildQuery() - クエリ全体構築
│   │   ├── parseParams() - where条件解析
│   │   └── buildOrderBy() - ソート構築
│   └── operatorMap - 演算子変換
├── CRUD操作
│   ├── find() → findMany()
│   ├── findOne()
│   ├── create() → upsertRow()
│   ├── updateOne() → upsertRow()
│   ├── updateMany()
│   ├── deleteOne()
│   └── deleteMany()
├── トランザクション
│   ├── beginTransaction()
│   ├── commitTransaction()
│   └── rollbackTransaction()
└── マイグレーション
    ├── migrate()
    ├── migrateDown()
    ├── migrateFresh()
    └── migrateStatus()
```

### データフロー図

```
[Payload Config]
     │
     ▼
[buildRawSchema] ─────────────────────┐
     │                                │
     ▼                                │
[RawTable/RawRelation]                │
     │                                │
     ├──[PostgreSQL]──┐               │
     │                │               │
     ▼                ▼               │
[buildDrizzleTable] [buildDrizzleTable]
     │                │               │
     └────────┬───────┘               │
              ▼                       │
       [Drizzle Schema]               │
              │                       │
              ▼                       │
  [find/create/update/delete] ◄───────┘
              │
              ▼
     [SQL Query / Result]
```

### PostgreSQL/SQLite固有処理

| 処理 | PostgreSQL | SQLite |
|------|------------|--------|
| スキーマ生成 | `packages/drizzle/src/postgres/` | `packages/drizzle/src/sqlite/` |
| IDタイプ | serial / uuid | integer / text |
| enum | ネイティブenum | text + check |
| timestamp | timestamptz | text |
| vector | pgvector | 非対応 |
| like | ilike | like（大文字小文字無視） |
