# 機能設計書 116-Get-DbaDependency

## 概要

本ドキュメントは、SQL Serverオブジェクトの依存関係をマッピングし、適切なデプロイ順序で作成スクリプトを生成するための機能設計書である。

### 本機能の処理概要

**業務上の目的・背景**：データベースオブジェクトの変更やマイグレーションを行う際、依存関係の把握は極めて重要である。オブジェクトを変更する前に影響範囲を理解し、デプロイ時には依存するオブジェクトが先に作成されている必要がある。本機能は、SMOのScripterオブジェクトを使用して依存関係を発見し、階層的なティア情報と共に作成スクリプトを生成する。

**機能の利用シーン**：
- オブジェクト変更前の影響分析
- 環境間のオブジェクトマイグレーション
- デプロイスクリプトの自動生成（正しい順序）
- データベーススキーマのドキュメント化
- 依存関係のトラブルシューティング

**主要な処理内容**：
1. 入力されたSMOオブジェクトからサーバーオブジェクトを特定
2. SMO Scripterを使用してDiscoverDependenciesを実行
3. 依存関係ツリーを再帰的に走査してティア情報を付与
4. 各依存オブジェクトの詳細情報と作成スクリプトを取得
5. ティア順にソートして結果を返却

**関連システム・外部連携**：SQL Server Management Objects（SMO）のScripterクラスを使用。

**権限による制御**：対象オブジェクトとその依存オブジェクトへの読み取り権限が必要。スクリプト生成にはDEFINITION権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | PowerShellコマンドラインインターフェースのみ |

## 機能種別

データ参照 / 依存関係分析 / スクリプト生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| InputObject | object | No | 分析対象のSMOオブジェクト（パイプライン可） | URNプロパティを持つSMOオブジェクト |
| AllowSystemObjects | switch | No | システムオブジェクトを結果に含める | - |
| Parents | switch | No | 依存方向を逆転（このオブジェクトが依存するものを取得） | - |
| IncludeSelf | switch | No | 入力オブジェクト自身を結果に含める | - |
| EnableException | switch | No | 例外を発生させるかどうか | - |

### 入力データソース

- InputObject: Get-DbaDatabase、Get-DbaDbTable等からのパイプライン入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverのコンピュータ名 |
| ServiceName | string | SQL Serverサービス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Dependent | string | 依存オブジェクトの名前 |
| Type | string | SMOオブジェクトタイプ（Table、View、StoredProcedure等） |
| Owner | string | スキーマ/所有者 |
| IsSchemaBound | bool | スキーマバインドかどうか |
| Parent | string | 親オブジェクトの名前 |
| ParentType | string | 親オブジェクトのSMOタイプ |
| Tier | int | デプロイ階層（1=最下層、高い数値=上位依存） |
| Object | SMO object | 依存オブジェクトのSMOインスタンス |
| Urn | string | オブジェクトのURN |
| OriginalResource | object | 分析対象の元オブジェクト |
| Script | string | T-SQL作成スクリプト |

### 出力先

- PowerShellパイプライン（標準出力）
- Dataplat.Dbatools.Database.Dependency カスタムオブジェクトとして返却

## 処理フロー

### 処理シーケンス

```
1. beginブロック: ユーティリティ関数の定義
   ├─ Read-Parent: 循環参照検出用の親URN取得
   ├─ Get-DependencyTree: SMO Scripterで依存関係を発見
   ├─ Read-DependencyTree: ツリーを再帰的に走査してティア付け
   ├─ Get-DependencyTreeNodeDetail: 各ノードの詳細情報取得
   └─ Select-DependencyPrecedence: 重複排除とソート
2. processブロック開始
   └─ 各InputObjectについてループ処理
      ├─ 2.1 URNプロパティの検証
      ├─ 2.2 親を辿ってサーバーオブジェクトを取得
      ├─ 2.3 Get-DependencyTree で依存関係ツリー取得
      ├─ 2.4 Read-DependencyTree でティア情報を付与
      └─ 2.5 Get-DependencyTreeNodeDetail で詳細取得
3. エラー処理
   └─ 無効なSMOオブジェクト時は Stop-Function で次へ
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{InputObjectをループ}
    B --> C{URNプロパティあり?}
    C -->|No| D[Stop-Function: 無効なSMOオブジェクト]
    D --> B
    C -->|Yes| E[親を辿ってServerオブジェクト取得]
    E --> F{Server取得成功?}
    F -->|No| G[Stop-Function: サーバーオブジェクト不明]
    G --> B
    F -->|Yes| H[Get-DependencyTree]
    H --> I{依存関係あり?}
    I -->|No| J[警告: 依存関係なし]
    J --> B
    I -->|Yes| K{IncludeSelf?}
    K -->|Yes| L[Read-DependencyTree Tier=0]
    K -->|No| M[Read-DependencyTree Tier=1]
    L --> N[Get-DependencyTreeNodeDetail]
    M --> N
    N --> O[Select-DependencyPrecedence]
    O --> P[結果出力]
    P --> B
    B --> Q[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ティア順序 | ティア1が最下層、高い数値ほど上位依存 | 常時 |
| BR-002 | Parents逆転 | -Parents指定時はティアが負の値になる | Parents指定時 |
| BR-003 | 循環参照検出 | 親URNに自身が含まれる場合は処理を停止 | 常時 |
| BR-004 | システムオブジェクト | AllowSystemObjects=falseの場合はシステムオブジェクトを除外 | デフォルト |
| BR-005 | 重複排除 | 同じオブジェクトが複数ティアに現れる場合、最高ティアのみ保持 | 常時 |

### 計算ロジック

- **Tier計算**: 再帰的にツリーを走査し、深さに応じてティア値を増加
- **Parents時のTier**: Tier値に-1を乗じて負の値に変換

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 依存関係発見 | sys.sql_expression_dependencies等 | SELECT (SMO Scripter経由) | 依存関係情報を取得 |
| スクリプト生成 | sys.sql_modules等 | SELECT (SMO Scripter経由) | オブジェクト定義を取得 |

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

SMO Scripterが内部的にシステムテーブルにアクセスする。直接的なテーブル操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidData | URNプロパティがない | Stop-Function でエラー出力、次のオブジェクトへ |
| - | InvalidData | サーバーオブジェクトが見つからない | Stop-Function でエラー出力、次のオブジェクトへ |
| - | 警告 | 依存関係が見つからない | Write-Message で情報出力、次のオブジェクトへ |
| - | 警告 | 循環参照検出 | Write-Message で警告出力、当該ブランチの処理を停止 |

### リトライ仕様

リトライ処理は実装されていない。エラー時は当該オブジェクトをスキップして次を処理。

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

読み取り専用操作のため、トランザクション管理は不要。

## パフォーマンス要件

- 依存関係が深いオブジェクトは処理時間が長くなる可能性
- SMO Scripterのプログレスイベントで進捗状況を報告
- 大量の依存オブジェクトがある場合はメモリ使用量に注意

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

- オブジェクト定義（Scriptプロパティ）が出力される
- 機密性の高いビジネスロジックが含まれる可能性
- VIEW DEFINITION権限が必要

## 備考

- Scripterオプションで DriAll = true を設定（外部キー等の依存関係も含む）
- SET ANSI_NULLS ON、SET QUOTED_IDENTIFIER ON はスクリプトから削除
- 各スクリプトの末尾に "go" を追加
- 技術詳細: https://technet.microsoft.com/en-us/library/ms345449(v=sql.105).aspx

---

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

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

### 推奨読解順序

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

本機能ではカスタム型 Dataplat.Dbatools.Database.Dependency を使用する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Get-DbaDependency.ps1 | `public/Get-DbaDependency.ps1` | 出力型（53行目: .OUTPUTS）とプロパティ構造（209-222行目） |

**読解のコツ**: New-Object Dataplat.Dbatools.Database.Dependency でカスタムオブジェクトを作成。

#### Step 2: ユーティリティ関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Get-DbaDependency.ps1 | `public/Get-DbaDependency.ps1` | beginブロックの4つの関数（97-255行目） |

**主要処理フロー**:
1. **97-106行目**: Read-Parent - 循環参照検出用の親URN取得
2. **108-146行目**: Get-DependencyTree - SMO Scripterで依存関係を発見
3. **148-176行目**: Read-DependencyTree - 再帰的ティア付与
4. **178-234行目**: Get-DependencyTreeNodeDetail - 詳細情報と作成スクリプト取得
5. **236-255行目**: Select-DependencyPrecedence - 重複排除とソート

#### Step 3: メイン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Get-DbaDependency.ps1 | `public/Get-DbaDependency.ps1` | processブロック（258-289行目） |

**主要処理フロー**:
- **261-263行目**: URN検証
- **266-273行目**: 親を辿ってServerオブジェクト取得
- **277行目**: Get-DependencyTree呼び出し
- **285-286行目**: Read-DependencyTree呼び出し（IncludeSelfによる分岐）
- **287行目**: Get-DependencyTreeNodeDetail と Select-DependencyPrecedence

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

```
Get-DbaDependency
    │
    ├─ beginブロック
    │      ├─ Read-Parent (関数定義)
    │      ├─ Get-DependencyTree (関数定義)
    │      ├─ Read-DependencyTree (関数定義)
    │      ├─ Get-DependencyTreeNodeDetail (関数定義)
    │      └─ Select-DependencyPrecedence (関数定義)
    │
    └─ processブロック
           │
           ├─ URN検証
           │
           ├─ 親を辿ってServerオブジェクト取得
           │
           ├─ Get-DependencyTree
           │      └─ SMO Scripter.DiscoverDependencies()
           │
           ├─ Read-DependencyTree (再帰)
           │      ├─ ティア付与
           │      ├─ 循環参照チェック
           │      ├─ FirstChild処理
           │      └─ NextSibling処理
           │
           ├─ Get-DependencyTreeNodeDetail
           │      ├─ $Server.GetSmoObject()
           │      ├─ Dependency オブジェクト作成
           │      └─ Scripter.EnumScriptWithList()
           │
           └─ Select-DependencyPrecedence
                  ├─ Group-Object
                  └─ Sort-Object Tier
```

### データフロー図

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

InputObject ───────▶ URN検証 ───────▶ 親を辿る
(SMOオブジェクト)            │
                            ▼
                     Get-DependencyTree
                            │
                            ▼
                     DependencyTree
                            │
                            ▼
                     Read-DependencyTree
                            │
                            ▼
                     ティア付きノード一覧
                            │
                            ▼
                     Get-DependencyTreeNodeDetail
                            │
                            ▼
                     Dependency オブジェクト
                     + 作成スクリプト
                            │
                            ▼
                     Select-DependencyPrecedence
                            │
                            ▼
                     ティア順ソート済み ───▶ パイプライン出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Get-DbaDependency.ps1 | `public/Get-DbaDependency.ps1` | ソース | メイン関数の実装 |
| Dependency.ps1 | `private/classes/Dependency.ps1` | ソース | Dataplat.Dbatools.Database.Dependency クラス定義 |
| Export-DbaScript.ps1 | `public/Export-DbaScript.ps1` | ソース | 関連機能：スクリプトエクスポート |
