# 機能設計書 60-Export-DbaDacPackage

## 概要

本ドキュメントは、SQL ServerデータベースからDACPACまたはBACPACパッケージをエクスポートする機能「Export-DbaDacPackage」の設計仕様を記述する。

### 本機能の処理概要

Export-DbaDacPackageは、DacFxフレームワークを使用してSQL ServerデータベースからDACPAC（スキーマのみ）またはBACPAC（スキーマ＋データ）パッケージを作成する機能である。

**業務上の目的・背景**：データベースのバージョン管理、移行、スキーマ配布には、再現可能なデプロイメントパッケージが必要である。DACPACはスキーマ定義を、BACPACはスキーマとデータを含むポータブルなパッケージ形式で、SQL Server Data Tools (SSDT)やdbatools/Publish-DbaDacPackageで展開可能。

**機能の利用シーン**：
- 開発データベースからのデプロイパッケージ作成
- ソースコントロール用のスキーマスナップショット取得
- 移行アーティファクトの準備
- データベースのバックアップ（BACPAC）

**主要な処理内容**：
1. 対象インスタンス・データベースの特定
2. DacFx DacServicesによる抽出/エクスポート実行
3. または SqlPackage.exeによるコマンドライン実行（ExtendedParameters使用時）
4. 結果ファイルパスと経過時間を出力

**関連システム・外部連携**：
- DacFx (Microsoft.SqlServer.Dac): DacServices API
- SqlPackage.exe: コマンドラインツール（ExtendedParameters使用時）

**権限による制御**：
- 対象データベースへのSELECT権限
- VIEW DEFINITION権限

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIコマンド | 主画面 | PowerShellコマンドラインからの直接実行 |

## 機能種別

エクスポート / パッケージ生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstance[] | Yes | 対象SQL Serverインスタンス | パイプライン入力可能 |
| SqlCredential | PSCredential | No | SQL Server接続用認証情報 | SQL認証のみサポート |
| Database | object[] | No | 対象データベース名 | - |
| ExcludeDatabase | object[] | No | 除外データベース名 | - |
| AllUserDatabases | switch | No | 全ユーザーデータベースを対象 | - |
| Path | string | No | 出力ディレクトリ（デフォルト: DbatoolsExport） | - |
| FilePath | string | No | 完全な出力ファイルパス | - |
| Type | string | No | パッケージタイプ（デフォルト: Dacpac） | Dacpac/Bacpac |
| Table | string[] | No | 対象テーブル（schema.table形式） | - |
| DacOption | object | No | DacExtractOptions/DacExportOptions | TypeによりExpected型が異なる |
| ExtendedParameters | string | No | SqlPackage.exe追加パラメータ | - |
| ExtendedProperties | string | No | SqlPackage.exe追加プロパティ | - |
| EnableException | switch | No | 例外をスローする | - |

### 入力データソース

- SqlInstance: パラメータ指定またはパイプライン入力
- Database: パラメータ指定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverインスタンスのコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Database | string | データベース名 |
| Path | string | 出力ファイルの完全パス |
| Elapsed | prettytimespan | 処理経過時間 |
| Result | string | DacServicesまたはSqlPackage.exeの出力 |

### 出力先

- ファイルシステム: DACPAC/BACPACファイル
- PowerShellパイプライン: 結果オブジェクト

## 処理フロー

### 処理シーケンス

```
1. 出力ディレクトリ確認
   └─ Test-ExportDirectory -Path $Path

2. パラメータセット確認
   └─ CMDパラメータセット時はSqlPackage.exe確認

3. Database/AllUserDatabases確認
   └─ どちらも未指定の場合はエラー

4. DacOptionの型チェック
   └─ Type=Dacpac時はDacExtractOptions
   └─ Type=Bacpac時はDacExportOptions

5. テーブルフィルタ構築
   └─ Tableパラメータからスキーマ.テーブルのタプル生成

6. 各インスタンスに対してループ
   └─ Connect-DbaInstance

7. SQL Serverバージョン確認
   └─ 最小バージョン: SQL Server 2008 R2 (10.50)

8. データベース列挙
   └─ Invoke-DbaQueryでスレッドセーフな列挙

9. 各データベースに対してループ
   └─ ファイルパス決定、DacServices作成

10. 抽出/エクスポート実行
    └─ SMOモード: DacServices.Extract/ExportBacpac
    └─ CMDモード: SqlPackage.exe実行

11. 結果出力
    └─ PSCustomObjectとして即座に出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[Test-ExportDirectory]
    B --> C{CMDパラメータセット?}
    C -->|Yes| D[Get-DbaSqlPackagePath確認]
    D --> E{SqlPackage存在?}
    E -->|No| F[Stop-Function]
    E -->|Yes| G[Database確認]
    C -->|No| G
    G --> H{Database OR AllUserDBs?}
    H -->|No| I[Stop-Function]
    H -->|Yes| J{DacOption型チェック}
    J --> K[インスタンスループ]
    K --> L[Connect-DbaInstance]
    L --> M{バージョン >= 10.50?}
    M -->|No| N[Stop-Function]
    M -->|Yes| O[Invoke-DbaQuery: DB列挙]
    O --> P[Databaseフィルタ]
    P --> Q[DBループ]
    Q --> R[Get-ExportFilePath]
    R --> S{SMOモード?}
    S -->|Yes| T[DacServices作成]
    T --> U{Type = Dacpac?}
    U -->|Yes| V[DacServices.Extract]
    U -->|No| W[DacServices.ExportBacpac]
    S -->|No| X[SqlPackage.exe実行]
    V --> Y[PSCustomObject出力]
    W --> Y
    X --> Y
    Y --> Z{次のDB?}
    Z -->|Yes| Q
    Z -->|No| AA{次のインスタンス?}
    AA -->|Yes| K
    AA -->|No| AB[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 最小バージョン | SQL Server 2008 R2 (10.50)以上が必要 | 常時 |
| BR-02 | DB指定必須 | DatabaseまたはAllUserDatabasesのいずれかが必要 | 常時 |
| BR-03 | DacOption型一致 | Type=DacpacはDacExtractOptions、Type=BacpacはDacExportOptions | DacOption指定時 |
| BR-04 | SqlPackage必須 | ExtendedParameters/ExtendedProperties使用時はSqlPackage.exeが必要 | CMDモード時 |

### 計算ロジック

- Elapsed: Stopwatch.Elapsed をprettytimespan形式に変換

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| DB列挙 | sys.databases | SELECT | アクセス可能DBの一覧取得 |
| スキーマ抽出 | 全テーブル/ビュー/SP等 | SELECT | DacFx経由でメタデータ取得 |
| データエクスポート | 対象テーブル | SELECT | BACPAC時のデータ取得 |

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

#### sys.databases

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | name | database_id > 4 AND state = 0 | ユーザーDBのみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | SQL Serverに接続できない | Stop-Functionで処理継続 |
| VersionError | バージョンエラー | SQL Server 2008 R2未満 | Stop-Functionで処理継続 |
| DacOptionTypeError | 型エラー | DacOptionの型がTypeと不一致 | Stop-Functionで処理終了 |
| SqlPackageNotFound | ツール未検出 | SqlPackage.exeが見つからない | Stop-Functionで処理終了 |
| ExtractionError | 抽出エラー | DacServices抽出失敗 | Stop-Functionで処理継続 |

### リトライ仕様

特になし。各データベースは独立して処理される。

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

DacFxの抽出処理は読み取り専用。スナップショット分離レベルで実行。

## パフォーマンス要件

- 大規模データベースでは抽出に時間がかかる
- DacOption.CommandTimeoutで制御可能
- BACPAC時はデータ量に比例して時間増加

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

- SqlCredentialによる認証情報の安全な受け渡し
- SQL認証のみサポート（SqlCredential指定時）
- 出力ファイルにはスキーマ情報（およびBACPAC時はデータ）が含まれるため適切なアクセス制御が必要

## 備考

- 3パーツ参照（外部データベース参照）がある場合、抽出が失敗する可能性あり
- DacFx APIはdbatools.libraryから提供
- 出力ファイル名にはサーバー名、DB名、タイムスタンプが含まれる

---

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

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

### 推奨読解順序

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

出力されるPSCustomObjectの構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Export-DbaDacPackage.ps1 | `public/Export-DbaDacPackage.ps1` | 361-369行目（PSCustomObject出力） |

**読解のコツ**: Select-DefaultViewでComputerName, InstanceNameを非表示にし、主要プロパティのみ表示。

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

パラメータ定義と初期化処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Export-DbaDacPackage.ps1 | `public/Export-DbaDacPackage.ps1` | 121-144行目（パラメータ定義） |
| 2-2 | Export-DbaDacPackage.ps1 | `public/Export-DbaDacPackage.ps1` | 145-157行目（begin block） |

**主要処理フロー**:
1. **146行目**: Test-ExportDirectory
2. **150-156行目**: CMDパラメータセット時のSqlPackage確認

#### Step 3: データベース列挙を理解する

スレッドセーフなDB列挙を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Export-DbaDacPackage.ps1 | `public/Export-DbaDacPackage.ps1` | 213-268行目 |

**主要処理フロー**:
- **221-227行目**: SQLクエリでDB一覧取得（Get-DbaDatabase代替）
- **253行目**: Invoke-DbaQuery実行
- **256-258行目**: Databaseフィルタ適用

#### Step 4: SMOモード（DacFx API）を理解する

DacServicesによる抽出処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Export-DbaDacPackage.ps1 | `public/Export-DbaDacPackage.ps1` | 288-323行目 |

**主要処理フロー**:
- **289-292行目**: DacServices作成
- **293-298行目**: DacOption初期化（未指定時）
- **300行目**: イベントハンドラ登録
- **302-312行目**: Type=Dacpac時のExtract
- **313-322行目**: Type=Bacpac時のExportBacpac

#### Step 5: CMDモード（SqlPackage.exe）を理解する

コマンドライン実行を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Export-DbaDacPackage.ps1 | `public/Export-DbaDacPackage.ps1` | 324-360行目 |

**主要処理フロー**:
- **325-326行目**: action決定（Extract/Export）
- **329行目**: SqlPackage引数構築
- **331-350行目**: Process実行

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

```
Export-DbaDacPackage
    │
    ├─ [begin]
    │      ├─ Test-ExportDirectory
    │      └─ [CMDモード] Get-DbaSqlPackagePath
    │
    └─ [process]
           │
           └─ [foreach: SqlInstance]
                  │
                  ├─ Connect-DbaInstance
                  │
                  ├─ バージョンチェック (>= 10.50)
                  │
                  ├─ Invoke-DbaQuery (DB列挙)
                  │
                  └─ [foreach: Database]
                         │
                         ├─ Get-ExportFilePath
                         │
                         ├─ [SMOモード]
                         │      │
                         │      ├─ DacServices作成
                         │      │
                         │      └─ Extract/ExportBacpac
                         │
                         └─ [CMDモード]
                                │
                                └─ SqlPackage.exe実行
```

### データフロー図

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

SqlInstance ─────────────▶ Connect-DbaInstance
                                   │
                                   ▼
Database/AllUserDBs ─────▶ Invoke-DbaQuery (DB列挙)
                                   │
                                   ▼
                          [foreach: Database]
                                   │
Path/FilePath ──────────▶ Get-ExportFilePath ──────▶ .dacpac/.bacpac
                                   │
Type (Dacpac/Bacpac) ────▶        │
                                   ▼
                          ┌───────────────────┐
                          │ SMOモード?        │
                          └─────────┬─────────┘
                               Yes  │  No
                          ┌─────────┴─────────┐
                          ▼                   ▼
                    DacServices          SqlPackage.exe
                    Extract/Export       コマンド実行
                          │                   │
                          └─────────┬─────────┘
                                    │
                                    ▼
                          PSCustomObject ────────────────▶ パイプライン
                          (Database, Path,
                           Elapsed, Result)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Export-DbaDacPackage.ps1 | `public/Export-DbaDacPackage.ps1` | ソース | メイン機能実装 |
| Publish-DbaDacPackage.ps1 | `public/Publish-DbaDacPackage.ps1` | ソース | 関連機能（デプロイ） |
| New-DbaDacOption.ps1 | `public/New-DbaDacOption.ps1` | ソース | DacOptionオブジェクト作成 |
| New-DbaDacPackage.ps1 | `public/New-DbaDacPackage.ps1` | ソース | ソースからDACPAC作成 |
| New-DbaDacProfile.ps1 | `public/New-DbaDacProfile.ps1` | ソース | デプロイプロファイル作成 |
| Get-DbaSqlPackagePath.ps1 | `private/functions/Get-DbaSqlPackagePath.ps1` | ソース | SqlPackage.exeパス取得 |
| Install-DbaSqlPackage.ps1 | `public/Install-DbaSqlPackage.ps1` | ソース | SqlPackage.exeインストール |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
