# 機能設計書 666-ConvertTo-DbaDataTable

## 概要

本ドキュメントは、PowerShellオブジェクトをSQL Server一括操作用の.NET DataTableオブジェクトに変換するConvertTo-DbaDataTable機能の設計仕様を記述したものである。

### 本機能の処理概要

ConvertTo-DbaDataTableは、PowerShellオブジェクトを適切なカラム型とデータベース互換フォーマットを持つ.NET DataTableオブジェクトに変換する機能である。Write-DbaDataTableや他のバルクインサートメソッドを使用してSQL Serverテーブルにデータをインポートするための一括操作に不可欠な機能である。

**業務上の目的・背景**：データ型を自動検出してSQL Server互換のフォーマットに変換し、dbatools特有のタイプ（DbaSize、DbaTimeSpan）を適切に処理する。TimeSpanオブジェクトをミリ秒、秒、または文字列表現に変換するなど、特殊タイプの変換方法を制御できる。一般的なシナリオとしては、Get-DbaDatabase、Get-DbaBackupHistoryなどのdbatools コマンドの結果を取得し、カスタムレポーティングテーブルに格納するための準備がある。

**機能の利用シーン**：
- dbatoolsコマンドの出力をSQL Serverテーブルにインポート
- PowerShellオブジェクトのバルクインサート準備
- レポーティングデータの蓄積
- 複雑なオブジェクト配列のデータベース格納

**主要な処理内容**：
1. 入力オブジェクトの受け取りとnullハンドリング
2. DataTableの初期化
3. 各オブジェクトのプロパティから列の作成
4. 型変換処理（特殊タイプ対応）
5. 値のDataRowへの挿入
6. 完成したDataTableの出力

**関連システム・外部連携**：System.Data.DataTableを使用してデータ構造を作成し、Write-DbaDataTable等のバルクインサート機能と連携する。

**権限による制御**：メモリ内処理のため特別な権限は不要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | PowerShellコンソール | 主画面 | コマンド実行とDataTable出力 |

## 機能種別

データ変換 / オブジェクト変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| InputObject | PSObject[] | Yes | 変換するPowerShellオブジェクト | パイプライン入力可能、null許容 |
| TimeSpanType | string | No | TimeSpanの変換方法 | Ticks/TotalDays/TotalHours/TotalMinutes/TotalSeconds/TotalMilliseconds/String |
| SizeType | string | No | DbaSizeの変換方法 | Int64/Int32/String |
| IgnoreNull | switch | No | nullオブジェクトを除外 | - |
| Raw | switch | No | すべての列を文字列に | - |
| EnableException | switch | No | 例外を有効化 | - |

### 入力データソース

- InputObject: パイプラインまたはパラメータから取得（必須）
- デフォルト: TimeSpanType=TotalMilliseconds, SizeType=Int64

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DataTable | System.Data.DataTable | 入力オブジェクトから変換されたDataTable |

### 出力先

パイプライン出力（System.Data.DataTable）

## 処理フロー

### 処理シーケンス

```
1. beginブロック：DataTable初期化
   └─ 空のDataTableと列追跡変数の作成
2. processブロック：各InputObjectの処理
   └─ nullハンドリング（IgnoreNull対応）
3. 列の動的作成
   └─ 最初の非nullオブジェクトでスキーマ決定
4. 型変換処理
   └─ Convert-Type関数による型判定と変換
5. 特殊タイプのハンドリング
   └─ TimeSpan/DbaSize/DbaDateTime[]
6. DataRow作成と値挿入
   └─ 各プロパティをDataRowに設定
7. endブロック：DataTable出力
   └─ 完成したDataTableをパイプラインに出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[DataTable初期化]
    B --> C{InputObject null?}
    C -->|Yes| D{IgnoreNull?}
    D -->|Yes| E[スキップ]
    D -->|No| F[空行追加]
    C -->|No| G{DataRow型?}
    G -->|Yes| H[Merge処理]
    G -->|No| I[NewRow作成]
    I --> J[各プロパティループ]
    J --> K{列存在?}
    K -->|No| L[Add-Column]
    K -->|Yes| M[型変換]
    L --> M
    M --> N{特殊タイプ?}
    N -->|Yes| O[Convert-SpecialType]
    N -->|No| P[通常値設定]
    O --> Q[DataRowに値設定]
    P --> Q
    Q --> R{次のプロパティ?}
    R -->|Yes| J
    R -->|No| S[DataRow追加]
    S --> T{次のObject?}
    E --> T
    F --> T
    H --> T
    T -->|Yes| C
    T -->|No| U[DataTable出力]
    U --> V[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-666-1 | 型自動検出 | 入力オブジェクトのプロパティ型から列の型を決定 | Raw=false時 |
| BR-666-2 | 文字列モード | Raw=true時はすべての列をSystem.Stringに | Raw=true時 |
| BR-666-3 | TimeSpan変換 | TimeSpanType指定に従って変換 | TimeSpan/DbaTimeSpan型検出時 |
| BR-666-4 | Size変換 | SizeType指定に従って変換 | DbaSize型検出時 |
| BR-666-5 | Null行処理 | IgnoreNull=false時はnullでも空行を追加 | null入力時 |
| BR-666-6 | 配列結合 | System.Object[]やString[]はカンマ区切りで結合 | 配列プロパティ検出時 |

### 計算ロジック

**TimeSpan変換ロジック**:
- Ticks: $value.Ticks (Int64)
- TotalDays/TotalHours/TotalMinutes/TotalSeconds/TotalMilliseconds: 対応するプロパティ値 (Int64)
- String: $value.ToString() (String)

**DbaSize変換ロジック**:
- Int64: $value.Byte (Int64)
- Int32: $value.Byte (Int32)
- String: $value.ToString() (String)

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

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

本機能はメモリ内処理のため、直接的なデータベース操作はない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Stop-Function | プロパティ追加失敗 | エラー出力後継続 |
| - | 例外 | 型変換失敗 | System.Stringにフォールバック |

### リトライ仕様

リトライ処理は実装されていない。

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

メモリ内処理のためトランザクション管理は不要。

## パフォーマンス要件

- ストリーミング処理により大量データでもメモリ効率的
- 列スキーマは最初の非nullオブジェクトで決定（後続オブジェクトでの追加列対応あり）
- Rawモードでは型検出処理をスキップして高速化可能

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

- 入力データは検証なしでDataTableに格納されるため、後続のWrite-DbaDataTableで適切なサニタイズが必要
- センシティブなデータを含むオブジェクトの変換に注意

## 備考

- Chad Millerのスクリプトをベースに開発（https://gallery.technet.microsoft.com/scriptcenter/4208a159-a52e-4b99-83d4-8048468d29dd）
- 型変換に失敗した場合は-Rawパラメータを試すことを推奨
- 出力されるDataTableはWrite-DbaDataTableで直接使用可能

---

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

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

### 推奨読解順序

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

System.Data.DataTableの構造と、dbatools特有の型（DbaSize, DbaTimeSpan）を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ConvertTo-DbaDataTable.ps1 | `public/ConvertTo-DbaDataTable.ps1` | 内部関数Convert-Typeのサポート型リスト |

**読解のコツ**: 139-156行目で定義された$types配列が標準サポート型のリスト。これ以外の型は文字列に変換される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ConvertTo-DbaDataTable.ps1 | `public/ConvertTo-DbaDataTable.ps1` | begin/process/endブロック構造 |

**主要処理フロー**:
1. **122-323行目**: beginブロック - DataTable初期化と内部関数定義
2. **126-213行目**: Convert-Type関数 - 型変換ロジック
3. **215-263行目**: Convert-SpecialType関数 - 特殊タイプ変換
4. **265-313行目**: Add-Column関数 - 列追加処理
5. **325-432行目**: processブロック - 各オブジェクトの処理
6. **434-437行目**: endブロック - DataTable出力

#### Step 3: 内部関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Convert-Type | 同ファイル内 | 型判定と変換値決定 |
| 3-2 | Convert-SpecialType | 同ファイル内 | TimeSpan/DbaSize変換 |
| 3-3 | Add-Column | 同ファイル内 | DataColumn動的追加 |

**主要処理フロー**:
- **Convert-Type**: 型名を受け取り、サポート型リストと照合、特殊タイプの変換処理
- **Convert-SpecialType**: TimeSpanType/SizeTypeパラメータに基づく値変換
- **Add-Column**: プロパティからDataColumnを作成してDataTableに追加

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

```
ConvertTo-DbaDataTable
    │
    ├─ begin
    │      ├─ Convert-Type (定義)
    │      ├─ Convert-SpecialType (定義)
    │      ├─ Add-Column (定義)
    │      └─ DataTable初期化
    │
    ├─ process (各InputObject)
    │      ├─ null check → IgnoreNull処理
    │      │
    │      ├─ DataRow型 → Merge
    │      │
    │      └─ 通常オブジェクト
    │             ├─ NewRow作成
    │             └─ 各プロパティ処理
    │                    ├─ Add-Column (列未存在時)
    │                    ├─ Convert-Type (型判定)
    │                    └─ Convert-SpecialType (特殊タイプ)
    │
    └─ end
           └─ , $datatable (出力)
```

### データフロー図

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

PSObject[] ────────────▶ processブロック
                              │
                              ▼
                        ┌──────────────┐
                        │ null check   │
                        └──────────────┘
                              │
            ┌─────────────────┼─────────────────┐
            ▼                 ▼                 ▼
       IgnoreNull        空行追加         通常処理
       スキップ                              │
                                             ▼
                                    ┌───────────────┐
                                    │ NewRow作成    │
                                    └───────────────┘
                                             │
TimeSpanType ─────────────────────┐         │
SizeType ─────────────────────────┼────────▶│
Raw ──────────────────────────────┘         │
                                             ▼
                                    ┌───────────────┐
                                    │ 各プロパティ  │
                                    │ 型変換・挿入  │
                                    └───────────────┘
                                             │
                                             ▼
                                    ┌───────────────┐
                                    │ Rows.Add      │
                                    └───────────────┘
                                             │
                                             ▼
                                       DataTable ──────────▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ConvertTo-DbaDataTable.ps1 | `public/ConvertTo-DbaDataTable.ps1` | ソース | メイン機能実装 |
| Write-DbaDataTable.ps1 | `public/Write-DbaDataTable.ps1` | ソース | DataTableのSQL Server書込み（関連機能） |
| Dataplat.Dbatools.Utility.Size | `internal/types/` | タイプ | DbaSize型定義 |
| Dataplat.Dbatools.Utility.DbaTimeSpan | `internal/types/` | タイプ | DbaTimeSpan型定義 |
