# 機能設計書 324-Install-DbaWhoIsActive

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける `Install-DbaWhoIsActive` 機能の設計書である。Adam Machanic氏が開発したsp_WhoIsActiveストアドプロシージャをダウンロード・インストールし、SQL Serverのリアルタイムセッション監視を可能にする機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：SQL Serverのパフォーマンストラブルシューティングにおいて、現在実行中のクエリ、ブロッキングチェーン、待機統計、リソース消費状況をリアルタイムで把握することは極めて重要である。sp_WhoIsActiveは、SQL Server Profilerのオーバーヘッドなしにこれらの情報を提供する最も広く使用されているツールである。本機能は、sp_WhoIsActiveのダウンロードと複数インスタンスへのインストールを自動化する。

**機能の利用シーン**：本番環境でのパフォーマンス問題調査、ブロッキングセッションの特定、クエリ実行状況の監視、新規SQL Server環境の標準ツールセットアップ、オフライン環境でのインストールなどで利用される。

**主要な処理内容**：
1. GitHubから最新版のsp_WhoIsActiveをダウンロード（またはローカルファイルを使用）
2. ローカルキャッシュに保存
3. SQLスクリプトを読み込みバージョン情報を抽出
4. 指定されたSQL Serverインスタンスに接続
5. ターゲットデータベースにストアドプロシージャをインストール
6. インストール結果とバージョン情報を返却

**関連システム・外部連携**：
- GitHub（sp_WhoIsActiveリポジトリ: https://github.com/amachanic/sp_whoisactive）
- Save-DbaCommunitySoftware（ダウンロード処理）
- Invoke-DbaWhoIsActive（利用先）

**権限による制御**：ターゲットデータベースへのCREATE PROCEDURE権限が必要。masterデータベースへのインストール推奨（サーバー全体でのアクセス可能）。

## 関連画面

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

## 機能種別

インストール処理 / スクリプト実行

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| SqlInstance | DbaInstanceParameter[] | Yes | ターゲットSQL Serverインスタンス | パイプラインから受け取り可能 |
| SqlCredential | PSCredential | No | 認証用資格情報 | Windows/SQL認証対応 |
| Database | object | No | インストール先データベース | 未指定時はGUIで選択 |
| LocalFile | string | No | ローカルファイルパス（SQLまたはZIP） | Test-Pathで検証 |
| Force | switch | No | キャッシュを無視して再ダウンロード | - |
| EnableException | switch | No | 例外を有効化 | - |
| Confirm | switch | No | 確認プロンプト表示 | SupportsShouldProcess |
| WhatIf | switch | No | 実行内容の表示のみ | SupportsShouldProcess |

### 入力データソース

- GitHub: sp_WhoIsActiveリリースから最新版を取得
- ローカルファイル: LocalFileパラメータで指定されたSQLまたはZIPファイル
- ローカルキャッシュ: dbatoolsデータディレクトリ内のキャッシュ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ComputerName | string | SQL Serverをホストするコンピュータ名 |
| InstanceName | string | SQL Serverインスタンス名 |
| SqlInstance | string | 完全なSQL Serverインスタンス名 |
| Database | string | インストール先データベース名 |
| Name | string | ストアドプロシージャ名（sp_WhoisActive） |
| Version | string | sp_WhoIsActiveのバージョン |
| Status | string | インストール状態（Installed/Updated） |

### 出力先

PowerShellパイプライン（PSCustomObject）

## 処理フロー

### 処理シーケンス

```
1. beginブロック：ダウンロードとスクリプト準備
   └─ Force/LocalFile/キャッシュ状態に応じてダウンロード
   └─ SQLファイルを読み込みバージョン抽出
2. processブロック：各インスタンスへのインストール
   └─ Connect-DbaInstanceで接続
3. データベース選択
   └─ 未指定時はShow-DbaDbListでGUI選択
4. 既存プロシージャ確認
   └─ sys.proceduresからsp_WhoisActiveの存在確認
5. スクリプト実行
   └─ Invoke-DbaQueryでスクリプト実行
6. 結果オブジェクト出力
   └─ 既存の場合はUpdated、新規の場合はInstalled
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Force指定または<br>キャッシュ不在?}
    B -->|Yes| C[Save-DbaCommunitySoftwareで<br>ダウンロード]
    B -->|No| D[キャッシュを使用]
    C --> D
    D --> E[SQLファイル読み込み]
    E --> F[バージョン情報抽出]
    F --> G[各SqlInstanceをループ]
    G --> H[Connect-DbaInstance]
    H --> I{接続成功?}
    I -->|No| J[エラー出力して次へ]
    I -->|Yes| K{Database指定<br>あり?}
    K -->|No| L[Show-DbaDbListで<br>GUI選択]
    K -->|Yes| M[指定データベース使用]
    L --> N{選択あり?}
    N -->|No| O[エラー終了]
    N -->|Yes| M
    M --> P[既存プロシージャ確認]
    P --> Q[Invoke-DbaQueryで<br>スクリプト実行]
    Q --> R{実行成功?}
    R -->|No| S[エラー出力]
    R -->|Yes| T{既存プロシージャ?}
    T -->|Yes| U[Status=Updated]
    T -->|No| V[Status=Installed]
    U --> W[結果オブジェクト出力]
    V --> W
    S --> X{次のインスタンス?}
    W --> X
    J --> X
    X -->|Yes| G
    X -->|No| Y[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-324-01 | master推奨 | masterデータベースへのインストールを推奨 | Database指定時に警告表示 |
| BR-324-02 | GUI選択 | Database未指定時はGUIでデータベース選択 | 対話モード時 |
| BR-324-03 | ファイル形式 | SQLファイルまたはZIPファイルを受け付け | LocalFile指定時 |
| BR-324-04 | USE master除去 | スクリプトからUSE master文を削除 | スクリプト読み込み時 |

### 計算ロジック

バージョン抽出ロジック：
- スクリプト内から"Who Is Active? v"を検索
- その後の閉じ括弧までの文字列をバージョンとして抽出

ステータス判定ロジック：
- 既存プロシージャ数 > 0: Status = 'Updated'
- それ以外: Status = 'Installed'

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 既存プロシージャ確認 | sys.procedures | SELECT | sp_WhoisActive存在確認 |
| プロシージャ作成/更新 | ターゲットデータベース | DDL | ストアドプロシージャの作成または置換 |

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

#### sys.procedures

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | COUNT(*) | is_ms_shipped=0 AND name LIKE '%sp_WhoisActive%' | 存在確認 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ConnectionError | インスタンス接続失敗 | Stop-Functionで処理継続 |
| - | DownloadError | GitHubダウンロード失敗 | Stop-Functionで処理中断 |
| - | ValidationError | データベース未選択 | Stop-Functionで処理中断 |
| - | DatabaseError | データベースが見つからないまたは書き込み不可 | Stop-Functionで処理継続 |
| - | ExecutionError | スクリプト実行失敗 | Stop-Functionで処理継続 |

### リトライ仕様

明示的なリトライ機能は実装されていない。Forceパラメータで再ダウンロードを試行可能。

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

スクリプト実行はInvoke-DbaQueryによって管理される。明示的なトランザクション制御は行われていない。

## パフォーマンス要件

特に定義されていない。AppVeyorでの長いバッチ実行問題回避のためInvoke-DbaQueryを使用。

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

- Windows認証およびSQL認証に対応
- MFAサポートはConnect-DbaInstanceを事前に使用
- Azure Active Directory認証対応
- 資格情報はPSCredentialオブジェクトとして安全に管理

## 備考

- sp_WhoIsActive公式サイト: http://whoisactive.com
- 作者への寄付: http://tinyurl.com/WhoIsActiveDonate
- 作者: Chrissy LeMaire (@cl)
- SQL Server 2005以上が必要

---

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

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

### 推奨読解順序

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

出力オブジェクトの構造を把握することから始める。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Install-DbaWhoIsActive.ps1 | `public/Install-DbaWhoIsActive.ps1` | 203-211行目のPSCustomObject定義 |

**読解のコツ**: Versionプロパティはスクリプト内から動的に抽出される点に注目。

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

パラメータ定義とbeginブロックを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Install-DbaWhoIsActive.ps1 | `public/Install-DbaWhoIsActive.ps1` | 108-118行目のparam定義 |
| 2-2 | Install-DbaWhoIsActive.ps1 | `public/Install-DbaWhoIsActive.ps1` | 120-157行目のbeginブロック |

**主要処理フロー**:
1. **108-118行目**: パラメータ定義（LocalFileはTest-Pathで検証）
2. **126-134行目**: Save-DbaCommunitySoftwareでダウンロード
3. **136-142行目**: SQLファイル検索（新旧ファイル名対応）
4. **144-155行目**: スクリプト読み込みとバージョン抽出

#### Step 3: インストール処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Install-DbaWhoIsActive.ps1 | `public/Install-DbaWhoIsActive.ps1` | 169-182行目のGUI選択ロジック |
| 3-2 | Install-DbaWhoIsActive.ps1 | `public/Install-DbaWhoIsActive.ps1` | 183-218行目のインストール処理 |

**主要処理フロー**:
- **169-182行目**: Database未指定時のShow-DbaDbList呼び出し
- **185-188行目**: 既存プロシージャ確認クエリ
- **191行目**: Invoke-DbaQueryでスクリプト実行
- **196-200行目**: ステータス判定（Updated/Installed）

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

```
Install-DbaWhoIsActive
    │
    ├─ Get-DbatoolsConfigValue
    │      └─ dbatools設定からデータディレクトリパス取得
    │
    ├─ Join-DbaPath
    │      └─ キャッシュパスの構築
    │
    ├─ Save-DbaCommunitySoftware
    │      └─ GitHubからのダウンロードとキャッシュ保存
    │
    ├─ Get-ChildItem
    │      └─ SQLファイルの検索
    │
    ├─ [IO.File]::ReadAllText
    │      └─ SQLスクリプトの読み込み
    │
    ├─ Connect-DbaInstance
    │      └─ SQL Serverへの接続
    │
    ├─ Show-DbaDbList
    │      └─ データベース選択GUI表示
    │
    └─ Invoke-DbaQuery
           └─ SQLスクリプト実行
```

### データフロー図

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

GitHubリポジトリ ───▶ Save-DbaCommunitySoftware ───▶ ローカルキャッシュ
       or                     │
ローカルファイル              │
                              ▼
                    Get-ChildItem（SQLファイル取得）
                              │
                              ▼
                    [IO.File]::ReadAllText
                       （スクリプト読み込み）
                              │
                              ▼
                    バージョン情報抽出
                              │
SqlInstance ───────▶ Connect-DbaInstance
                              │
                              ▼
                    Invoke-DbaQuery（スクリプト実行）
                              │
                              ▼
                        PSCustomObject
                    （インストール結果）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Install-DbaWhoIsActive.ps1 | `public/Install-DbaWhoIsActive.ps1` | ソース | メイン関数の実装 |
| Save-DbaCommunitySoftware.ps1 | `private/functions/Save-DbaCommunitySoftware.ps1` | ソース | コミュニティソフトウェアのダウンロード |
| Connect-DbaInstance.ps1 | `public/Connect-DbaInstance.ps1` | ソース | SQL Server接続 |
| Show-DbaDbList.ps1 | `private/functions/Show-DbaDbList.ps1` | ソース | データベース選択GUI |
| Invoke-DbaQuery.ps1 | `public/Invoke-DbaQuery.ps1` | ソース | SQLクエリ実行 |
