# 機能設計書 359-Copy-DbaDbAssembly

## 概要

本ドキュメントは、SQL Server CLRアセンブリをデータベース間で移行する `Copy-DbaDbAssembly` コマンドの機能設計書である。

### 本機能の処理概要

本機能は、ソースSQL Serverのデータベースに登録されているカスタムCLRアセンブリを、デスティネーションSQL Serverの対応するデータベースにコピーする。外部アセンブリに必要なTRUSTWORTHY設定も自動的に処理する。

**業務上の目的・背景**：CLRアセンブリ（.NETアセンブリをSQL Serverに登録したもの）は、カスタムストアドプロシージャ、ユーザー定義関数、ユーザー定義型などの基盤となる。データベース移行時にこれらのアセンブリも移行する必要がある。本機能により、複数データベースにまたがるアセンブリを一括でコピーでき、移行作業を効率化する。

**機能の利用シーン**：
- CLR機能を使用するデータベースの移行
- 開発環境から本番環境へのアセンブリ展開
- 複数サーバー間でのアセンブリ標準化
- DR環境構築時のアセンブリ同期

**主要な処理内容**：
1. ソースサーバーの全データベースからユーザーアセンブリを収集
2. デスティネーションサーバーの対応データベース存在確認
3. 外部アセンブリの場合、TRUSTWORTHY設定を有効化
4. 既存アセンブリの存在チェックと削除（-Force時）
5. Script()メソッドでアセンブリスクリプト生成・実行

**関連システム・外部連携**：sys.assemblies、CLR統合機能

**権限による制御**：sysadmin権限が必要。アセンブリ作成にはCONTROL DATABASE権限またはdb_owner権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | PowerShellコンソール | 主画面 | コマンド実行および結果表示 |

## 機能種別

データ移行 / オブジェクトコピー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Source | DbaInstanceParameter | Yes | ソースSQL Serverインスタンス | - |
| SourceSqlCredential | PSCredential | No | ソース認証情報 | - |
| Destination | DbaInstanceParameter[] | Yes | デスティネーションインスタンス（複数可） | - |
| DestinationSqlCredential | PSCredential | No | デスティネーション認証情報 | - |
| Assembly | Object[] | No | コピー対象アセンブリ（DatabaseName.AssemblyName形式） | - |
| ExcludeAssembly | Object[] | No | 除外アセンブリ（DatabaseName.AssemblyName形式） | - |
| Force | Switch | No | 既存アセンブリを上書き | - |
| EnableException | Switch | No | 例外制御 | - |
| WhatIf | Switch | No | 実行シミュレーション | - |
| Confirm | Switch | No | 実行確認 | - |

### 入力データソース

- ソースサーバーの各データベースのAssembliesコレクション（SMO）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DateTime | DbaDateTime | 操作日時 |
| SourceServer | String | ソースサーバー名 |
| SourceDatabase | String | ソースデータベース名 |
| SourceDatabaseID | Int | ソースデータベースID |
| DestinationServer | String | デスティネーションサーバー名 |
| DestinationDatabase | String | デスティネーションデータベース名 |
| DestinationDatabaseID | Int | デスティネーションデータベースID |
| Type | String | オブジェクトタイプ（"Database Assembly"） |
| Name | String | アセンブリ名 |
| Status | String | 結果（Successful / Skipped / Failed） |
| Notes | String | 追加情報 |

### 出力先

- PowerShellパイプライン（MigrationObject）

## 処理フロー

### 処理シーケンス

```
1. ソースサーバー接続
   └─ Connect-DbaInstance (MinimumVersion 9)

2. ソースアセンブリ収集
   ├─ 各アクセス可能データベースをループ
   └─ IsSystemObject = false のアセンブリを収集

3. デスティネーションループ開始

4. デスティネーションサーバー接続
   └─ Connect-DbaInstance (MinimumVersion 9)

5. デスティネーションアセンブリ収集
   └─ 既存アセンブリ一覧取得

6. アセンブリループ開始

7. デスティネーションDB存在確認
   └─ 存在しない場合はスキップ

8. フィルタチェック
   └─ Assembly/ExcludeAssembly パラメータ適用

9. TRUSTWORTHY設定
   └─ External アセンブリで DB が Trustworthy でない場合

10. 既存チェック
    ├─ 存在しない場合: コピー実行
    ├─ 存在 + Force なし: スキップ
    └─ 存在 + Force: 依存チェック後に削除

11. アセンブリコピー実行
    └─ Script() でSQL生成、Query() で実行

12. 結果出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[ソースサーバー接続]
    B --> C[全DBからアセンブリ収集]
    C --> D[デスティネーションループ]
    D --> E[デスティネーション接続]
    E --> F[アセンブリループ]
    F --> G{デスティネーションDB存在?}
    G -->|No| H[Skipped: DB未存在]
    G -->|Yes| I{フィルタ通過?}
    I -->|No| J[スキップ]
    I -->|Yes| K{External + 非Trustworthy?}
    K -->|Yes| L[TRUSTWORTHY ON設定]
    K -->|No| M{既存あり?}
    L --> M
    M -->|No| N[コピー実行]
    M -->|Yes| O{-Force?}
    O -->|No| P[Skipped出力]
    O -->|Yes| Q{依存あり?}
    Q -->|Yes| R[Failed: 依存あり]
    Q -->|No| S[DROP ASSEMBLY]
    S --> N
    N --> T{成功?}
    T -->|Yes| U[Successful出力]
    T -->|No| V[Failed出力]
    H --> W{次のアセンブリ?}
    P --> W
    R --> W
    U --> W
    V --> W
    J --> W
    W -->|Yes| F
    W -->|No| X{次のデスティネーション?}
    X -->|Yes| D
    X -->|No| Y[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | システムアセンブリ除外 | IsSystemObject = true は対象外 | 常時 |
| BR-002 | DB存在必須 | デスティネーションに同名DBが必要 | 常時 |
| BR-003 | TRUSTWORTHY自動設定 | External アセンブリで非Trustworthy時 | External Security Level |
| BR-004 | 依存アセンブリ削除不可 | 他アセンブリが参照している場合は削除不可 | -Force時 |
| BR-005 | フィルタ形式 | DatabaseName.AssemblyName 形式 | Assembly/ExcludeAssembly |

### 計算ロジック

特になし

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 取得 | sys.assemblies | SELECT (SMO経由) | アセンブリ一覧取得 |
| 依存チェック | sys.assembly_references | SELECT | 依存関係確認 |
| 設定変更 | 対象DB | ALTER DATABASE | TRUSTWORTHY ON |
| 削除 | sys.assemblies | DROP ASSEMBLY | 既存アセンブリ削除 |
| 追加 | sys.assemblies | CREATE ASSEMBLY | アセンブリ追加 |

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

#### sys.assemblies (SMO Assemblies)

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | name, assembly_id, is_user_defined | is_user_defined = 1 | ユーザーアセンブリのみ |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ConnectionError | 接続エラー | インスタンス接続失敗 | Stop-Function、continue |
| DbNotFound | DB不存在 | デスティネーションDB未存在 | Skipped出力、continue |
| TrustworthyFailed | 設定エラー | TRUSTWORTHY設定失敗 | Failed出力、continue |
| HasDependencies | 依存エラー | 依存アセンブリあり | Failed出力、continue |
| DropFailed | 削除エラー | アセンブリ削除失敗 | Failed出力、continue |
| CreateFailed | 作成エラー | アセンブリ作成失敗 | Failed出力、continue |

### リトライ仕様

リトライ処理なし。

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

各アセンブリは個別に処理。TRUSTWORTHY設定とアセンブリ作成は別トランザクション。

## パフォーマンス要件

- アセンブリ数とサイズに比例した処理時間

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

- sysadmin権限が必要
- TRUSTWORTHY設定はセキュリティリスクを伴う
- CLR統合が有効である必要がある

## 備考

- 依存オブジェクト（CLRストアドプロシージャ、関数、型）はコピーされない
- アセンブリのみのコピーで、参照するオブジェクトは別途移行が必要

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Copy-DbaDbAssembly.ps1 | `public/Copy-DbaDbAssembly.ps1` | Assembliesコレクション（124-137行目） |

**読解のコツ**: SMO Assembly オブジェクトのAssemblySecurityLevelプロパティに注目。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Copy-DbaDbAssembly.ps1 | `public/Copy-DbaDbAssembly.ps1` | 関数全体の処理フロー |

**主要処理フロー**:
1. **103-115行目**: パラメータ定義
2. **116-140行目**: ソースアセンブリ収集
3. **150-163行目**: デスティネーションアセンブリ収集
4. **198-213行目**: TRUSTWORTHY設定
5. **215-244行目**: 既存チェックと削除
6. **246-263行目**: アセンブリコピー実行

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

```
Copy-DbaDbAssembly
    │
    ├─ Connect-DbaInstance (Source, MinimumVersion 9)
    │
    ├─ foreach $database in $sourceServer.Databases
    │      └─ $database.Assemblies (IsSystemObject = false)
    │
    ├─ Connect-DbaInstance (Destination, MinimumVersion 9)
    │
    ├─ foreach $database in $destServer.Databases
    │      └─ $database.Assemblies 取得
    │
    ├─ ALTER DATABASE SET TRUSTWORTHY ON
    │      └─ External アセンブリ用
    │
    ├─ sys.assembly_references 参照チェック
    │
    ├─ DROP ASSEMBLY (Force時)
    │
    └─ $currentAssembly.Script() → Query()
           └─ アセンブリ作成
```

### データフロー図

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

Source ───▶ Connect-DbaInstance
                 │
                 ▼
          全DBのAssemblies収集
          (IsSystemObject = false)
                 │
Destination ───▶ Connect-DbaInstance
                 │
                 ▼
          デスティネーションDB存在確認
                 │
                 ▼
          TRUSTWORTHY設定 (External時)
                 │
                 ▼
          既存チェック
                 │
          ┌──────┴──────┐
          ▼             ▼
       存在しない     存在する
          │             │
          │        ┌────┴────┐
          │        ▼         ▼
          │     -Force    Force無し
          │        │         │
          │    依存チェック  Skipped
          │        │         │
          │      DROP        │
          │        │         │
          └────┬───┘         │
               ▼             │
          Script()→Query()   │
               │             │
               ▼             ▼
          Successful    MigrationObject出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Copy-DbaDbAssembly.ps1 | `public/Copy-DbaDbAssembly.ps1` | ソース | メイン関数 |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
