# 機能設計書 209-Rename-DbaDatabase

## 概要

本ドキュメントは、dbatools PowerShellモジュールのRename-DbaDatabase関数の機能設計を定義する。この関数は、プレースホルダーをサポートするカスタマイズ可能なテンプレートを使用して、データベース名、ファイルグループ名、論理ファイル名、物理ファイル名を体系的に変更するための機能を提供する。

### 本機能の処理概要

Rename-DbaDatabaseは、テンプレートベースの命名規則を使用してデータベースコンポーネントを体系的に名前変更する。SQL Server環境全体で一貫した命名標準を強制するための機能を提供する。

**業務上の目的・背景**：一貫性のないシステムを継承した場合や新しい命名ポリシーを実装する場合に、データベース命名の標準化が必要になる。この関数は、データベース名、ファイルグループ名、論理ファイル名、物理ファイル名のすべてを一貫したテンプレートに基づいて名前変更する機能を提供する。

**機能の利用シーン**：
- 命名規則の標準化
- データベース移行時の名前変更
- 開発/テスト環境のデータベースクローン作成
- 物理ファイル構造の整理

**主要な処理内容**：
1. データベース名の変更（オプションでユーザーを強制切断）
2. ファイルグループ名の変更（PRIMARYファイルグループは変更不可）
3. 論理ファイル名の変更
4. 物理ファイル名の変更
5. -Move指定時はデータベースをオフラインにしてファイル操作を実行
6. 名前の重複時は自動的にカウンターを追加

**関連システム・外部連携**：
- SQL Server Database Engine：データベース名前変更操作
- SMO：Rename()メソッド
- ファイルシステム：物理ファイルの名前変更/移動

**権限による制御**：sysadmin権限およびファイルシステムへのアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | データベース管理 | 補助機能 | データベースの名前変更 |

## 機能種別

データ更新（DDL操作）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes（Serverセット時） | 対象のSQL Serverインスタンス | - |
| SqlCredential | PSCredential | No | SQL Server認証用の資格情報 | - |
| Database | object[] | No | 対象データベース名 | - |
| ExcludeDatabase | object[] | No | 除外するデータベース名 | - |
| AllDatabases | switch | No | 全ユーザーデータベースを対象 | - |
| DatabaseName | string | No | 新しいデータベース名のテンプレート | <DBN>, <DATE>プレースホルダー |
| FileGroupName | string | No | 新しいファイルグループ名のテンプレート | <FGN>, <DBN>, <DATE>プレースホルダー |
| LogicalName | string | No | 新しい論理ファイル名のテンプレート | <FT>, <LGN>, <FGN>, <DBN>, <DATE>プレースホルダー |
| FileName | string | No | 新しい物理ファイル名のテンプレート | <FNN>, <FT>, <LGN>, <FGN>, <DBN>, <DATE>プレースホルダー |
| ReplaceBefore | switch | No | 古い名前をプレースホルダー置換前に削除 | - |
| Force | switch | No | アクティブな接続を強制切断 | - |
| SetOffline | switch | No | 名前変更後にデータベースをオフライン | - |
| Move | switch | No | 物理ファイルを自動的に移動 | - |
| Preview | switch | No | 変更をプレビュー（実行しない） | - |
| InputObject | Microsoft.SqlServer.Management.Smo.Database[] | Yes（Pipeセット時） | パイプラインからのデータベースオブジェクト | ValueFromPipeline |
| EnableException | switch | No | 例外を直接スローするかどうか | - |

### 入力データソース

- パラメータ入力：SqlInstance、Database
- パイプライン入力：Get-DbaDatabaseからのデータベースオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverが稼働しているコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Database | object | データベースオブジェクト |
| DBN | hashtable | データベース名変更（元の名前→新しい名前） |
| FGN | hashtable | ファイルグループ名変更 |
| LGN | hashtable | 論理ファイル名変更 |
| FNN | hashtable | 物理ファイル名変更 |
| PendingRenames | ArrayList | 移動待ちのファイル操作 |
| Status | string | "FULL"（完全成功）または"PARTIAL"（部分成功） |

### 出力先

- パイプライン：PSCustomObject
- SQL Server：データベース/ファイル名の変更

## 処理フロー

### 処理シーケンス

```
1. 前処理
   └─ 1.1 パラメータ検証
   └─ 1.2 日付フォーマット取得
2. データベースループ
   └─ 2.1 システムDB/アクセス不可DB/ミラーリング/AG対象DBをスキップ
   └─ 2.2 データベース名の変更（DatabaseName指定時）
       └─ 2.2.1 プレースホルダー置換
       └─ 2.2.2 重複チェック
       └─ 2.2.3 Force指定時は接続強制切断
       └─ 2.2.4 $db.Rename()実行
   └─ 2.3 ファイルグループ名の変更（FileGroupName指定時）
       └─ 2.3.1 PRIMARYは除外
       └─ 2.3.2 プレースホルダー置換
       └─ 2.3.3 重複時はカウンター追加
       └─ 2.3.4 $fg.Rename()実行
   └─ 2.4 論理ファイル名の変更（LogicalName指定時）
       └─ 2.4.1 プレースホルダー置換
       └─ 2.4.2 重複時はカウンター追加
       └─ 2.4.3 $logical.Rename()実行
   └─ 2.5 物理ファイル名の変更（FileName指定時）
       └─ 2.5.1 プレースホルダー置換
       └─ 2.5.2 重複時はカウンター追加
       └─ 2.5.3 $logical.FileName設定 + $db.Alter()
       └─ 2.5.4 Pending_Renamesに追加
   └─ 2.6 ファイル移動（Move指定時）
       └─ 2.6.1 データベースをオフライン
       └─ 2.6.2 ファイルRename-Item
       └─ 2.6.3 データベースをオンライン
3. 結果出力
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[パラメータ検証]
    B --> C{データベースループ}
    C -->|次のDB| D{対象外?}
    D -->|Yes| C
    D -->|No| E{DatabaseName指定?}
    E -->|Yes| F[DB名変更]
    E -->|No| G{FileGroupName指定?}
    F --> G
    G -->|Yes| H[FG名変更ループ]
    G -->|No| I{LogicalName指定?}
    H --> I
    I -->|Yes| J[論理名変更ループ]
    I -->|No| K{FileName指定?}
    J --> K
    K -->|Yes| L[物理名変更ループ]
    K -->|No| M{Move指定?}
    L --> M
    M -->|Yes| N[オフライン→移動→オンライン]
    M -->|No| O[結果出力]
    N --> O
    O --> C
    C -->|完了| P[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-209-01 | PRIMARYファイルグループ保護 | PRIMARYファイルグループは名前変更不可 | FileGroupName指定時 |
| BR-209-02 | 重複回避カウンター | 名前重複時は自動的にカウンター（001, 002...）を追加 | 重複検出時 |
| BR-209-03 | システムDB除外 | master, model, msdb, tempdb, distributionは対象外 | 常時 |
| BR-209-04 | ミラーリング/AG除外 | ミラーリング中またはAG参加中のDBは対象外 | 常時 |
| BR-209-05 | 処理順序 | データベース名→ファイルグループ名→論理ファイル名→物理ファイル名の順序で処理 | 常時 |
| BR-209-06 | 部分失敗時停止 | 名前変更中にエラーが発生した場合は残りの処理を停止 | エラー発生時 |

### 計算ロジック

プレースホルダー置換:
- `<DBN>`: 現在のデータベース名
- `<DATE>`: 現在日付（yyyyMMdd形式）
- `<FGN>`: 現在のファイルグループ名
- `<LGN>`: 現在の論理ファイル名
- `<FT>`: ファイルタイプ（ROWS, LOG, MMO, FS）
- `<FNN>`: 現在の物理ファイル名（拡張子なし）

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

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

| 操作 | 対象 | 操作種別 | 概要 |
|-----|-----|---------|------|
| DB名変更 | データベース | DDL (ALTER DATABASE) | $db.Rename() |
| FG名変更 | ファイルグループ | DDL (ALTER DATABASE) | $fg.Rename() |
| 論理名変更 | データベースファイル | DDL (ALTER DATABASE) | $logical.Rename() |
| 物理名変更 | データベースファイル | DDL (ALTER DATABASE) | $db.Alter() |
| オフライン設定 | データベース | DDL (ALTER DATABASE) | Set-DbaDbState -Offline |
| オンライン設定 | データベース | DDL (ALTER DATABASE) | Set-DbaDbState -Online |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| DuplicateName | 重複エラー | 新しい名前が既に存在 | 別の名前を指定 |
| RenameError | 実行エラー | Rename()メソッド失敗 | エラー詳細を確認 |
| FileAccessError | ファイルエラー | 物理ファイルにアクセス不可 | 権限を確認 |
| OfflineError | 状態エラー | オフライン/オンライン切替失敗 | 接続状況を確認 |

### リトライ仕様

リトライ処理は実装されていない。エラー発生時は残りの処理を停止。

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

各名前変更操作は独立して実行。部分成功の場合はStatus="PARTIAL"を返す。

## パフォーマンス要件

- 名前変更操作は即時完了
- 物理ファイル移動はファイルサイズに依存

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

- sysadmin権限が必要
- ファイルシステムへのアクセス権限が必要（Move使用時）
- ConfirmImpact=Mediumで確認プロンプト

## 備考

- Simone Bizzotto (@niphold) により作成
- -Previewパラメータで変更をプレビュー可能
- masterデータベースのバックアップを推奨

---

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

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

### 推奨読解順序

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

SMOのDatabaseオブジェクトとファイル構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Microsoft.SqlServer.Management.Smo.Database | SMO | Rename()、FileGroups、LogFiles |
| 1-2 | Microsoft.SqlServer.Management.Smo.FileGroup | SMO | Files、Rename() |
| 1-3 | Microsoft.SqlServer.Management.Smo.DataFile | SMO | FileName、Rename() |

**読解のコツ**: データベースはFileGroups→Files、LogFilesの階層構造を持つ。各レベルでRename()メソッドが使用可能。

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

Rename-DbaDatabase.ps1の構造を理解する。

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

**主要処理フロー**:
1. **226-260行目**: begin ブロック（ヘルパー関数、検証）
2. **337-369行目**: データベース名変更処理
3. **371-425行目**: ファイルグループ名変更処理
4. **428-556行目**: 論理ファイル名変更処理
5. **558-725行目**: 物理ファイル名変更処理
6. **726-855行目**: ファイル移動処理

#### Step 3: 関連機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Set-DbaDbState.ps1 | `public/Set-DbaDbState.ps1` | オフライン/オンライン切替 |
| 3-2 | Get-DbaFile.ps1 | `public/Get-DbaFile.ps1` | ファイル存在確認 |

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

```
Rename-DbaDatabase
    │
    ├─ Connect-DbaInstance
    │      └─ SQL Server接続確立
    │
    ├─ $db.Rename()
    │      └─ データベース名変更
    │
    ├─ $fg.Rename()
    │      └─ ファイルグループ名変更
    │
    ├─ $logical.Rename()
    │      └─ 論理ファイル名変更
    │
    ├─ $db.Alter()
    │      └─ 物理ファイル名変更（メタデータ）
    │
    ├─ Set-DbaDbState
    │      └─ オフライン/オンライン切替
    │
    ├─ Get-DbaFile
    │      └─ ファイル存在確認
    │
    └─ Invoke-Command2 + Rename-Item
           └─ 物理ファイル移動
```

### データフロー図

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

SqlInstance ─────────────▶ Connect-DbaInstance
    │                              │
Database ────────────────▶ システムDB除外
    │                              │
    │                              ▼
DatabaseName ────────────▶ DB名変更
    │                              │
    │                              ▼
FileGroupName ───────────▶ FG名変更ループ
    │                              │
    │                              ▼
LogicalName ─────────────▶ 論理名変更ループ
    │                              │
    │                              ▼
FileName ────────────────▶ 物理名変更ループ
    │                              │
    │                              ▼
Move ────────────────────▶ ファイル移動
                                   │
                                   ▼
                          PSCustomObject ─────────▶ パイプライン出力
                          (DBN, FGN, LGN, FNN,
                           PendingRenames, Status)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Rename-DbaDatabase.ps1 | `public/Rename-DbaDatabase.ps1` | ソース | メイン関数実装 |
| Set-DbaDbState.ps1 | `public/Set-DbaDbState.ps1` | ソース | オフライン/オンライン切替 |
| Get-DbaFile.ps1 | `public/Get-DbaFile.ps1` | ソース | ファイル存在確認 |
| Get-DbaDatabase.ps1 | `public/Get-DbaDatabase.ps1` | ソース | データベース取得（パイプライン入力元） |
