# 機能設計書 213-Save-DbaCommunitySoftware

## 概要

本ドキュメントは、GitHubからSQL Serverコミュニティツールをダウンロードしてローカルキャッシュを管理するSave-DbaCommunitySoftware関数の機能設計書です。

### 本機能の処理概要

Save-DbaCommunitySoftwareは、GitHubリポジトリから人気のあるSQL Serverコミュニティツールをダウンロードし、dbatoolsインストールコマンドで使用するローカルキャッシュにアーカイブを展開します。この関数は、必須のDBAスクリプトコレクションの取得とバージョン管理を自動的に処理し、複数のツールリポジトリを手動でダウンロードおよび整理する必要を排除します。

**業務上の目的・背景**：SQL Server DBAは、Ola Hallengren's Maintenance Solution、First Responder Kit、sp_WhoIsActiveなど、様々なコミュニティツールを活用します。これらのツールを個別にダウンロードして管理することは手間がかかります。本機能は、これらのツールの取得・バージョン管理・ディレクトリ構造の正規化を一元的に行い、DBAの作業効率を向上させます。

**機能の利用シーン**：
- Install-DbaMaintenanceSolutionやInstall-DbaFirstResponderKitを実行する前のツール準備
- インターネット接続のない環境でローカルファイルからツールをインストールする場合
- 最新版のコミュニティツールにアップデートする場合
- 特定のブランチやバージョンのツールを取得する場合

**主要な処理内容**：
1. 対象ソフトウェアの決定とURL/ディレクトリ設定
2. GitHubからのZIPファイルダウンロード（またはローカルファイルの使用）
3. 一時ディレクトリへのアーカイブ展開
4. ディレクトリ構造の正規化（ソフトウェアごとの命名規則適用）
5. ターゲットディレクトリへのコピーとクリーンアップ

**関連システム・外部連携**：
- GitHub API（リリース情報の取得）
- 各コミュニティプロジェクトのリポジトリ（MaintenanceSolution, FirstResponderKit, DarlingData, SQLWATCH, WhoIsActive, DbaMultiTool, AzSqlTips）

**権限による制御**：ファイルシステムへの書き込み権限が必要です。

## 関連画面

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

## 機能種別

ファイルダウンロード / ソフトウェア管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Software | string | No | ダウンロードするソフトウェア名 | MaintenanceSolution, FirstResponderKit, DarlingData, SQLWATCH, WhoIsActive, DbaMultiTool, AzSqlTips |
| Branch | string | No | ダウンロードするブランチ/バージョン | 文字列型 |
| LocalFile | string | No | ローカルZIPファイルまたはSQLファイルのパス | ファイルパス |
| Url | string | No | カスタムダウンロードURL | URI形式 |
| LocalDirectory | string | No | 展開先のカスタムディレクトリ | ディレクトリパス |
| EnableException | switch | No | 例外を有効化 | スイッチ型 |
| WhatIf | switch | No | 実行シミュレーション | スイッチ型 |
| Confirm | switch | No | 確認プロンプト表示 | スイッチ型 |

### 入力データソース

- GitHubリポジトリ（オンラインダウンロード）
- ローカルZIPファイル/SQLファイル（オフラインインストール）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| なし | - | このコマンドはパイプラインにオブジェクトを返しません |

### 出力先

- dbatoolsデータディレクトリ（Path.DbatoolsData設定値）
- カスタム指定されたLocalDirectory

## 処理フロー

### 処理シーケンス

```
1. ソフトウェア別設定の決定
   └─ Branch, Url, LocalDirectory の自動設定

2. ダウンロード/ファイル処理
   ├─ LocalFile（.sql）: 専用ディレクトリ作成、コピー
   ├─ LocalFile（.zip）: 解凍処理
   └─ Url: ダウンロード後、解凍処理

3. ディレクトリ名正規化
   └─ ソフトウェアごとの命名規則に従いリネーム

4. ターゲットディレクトリへのコピー
   └─ 既存ディレクトリの削除後、コピー

5. 一時ファイル・フォルダのクリーンアップ
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Software指定?}
    B -->|Yes| C[Branch/Url/LocalDirectory設定]
    B -->|No| D{Url指定?}

    C --> E{LocalFile?}
    D -->|No| F[エラー: URL not found]
    D -->|Yes| E

    E -->|.sql & WhoIsActive/AzSqlTips| G[専用フォルダ作成、コピー]
    E -->|.zip| H[Expand-Archive実行]
    E -->|No| I[Invoke-TlsWebRequestダウンロード]

    I --> J[Expand-Archive実行]
    G --> K[ディレクトリ名正規化]
    H --> K
    J --> K

    K --> L{ディレクトリ名一致?}
    L -->|No| M[エラー: 不正なアーカイブ]
    L -->|Yes| N[既存ディレクトリ削除]

    N --> O[Copy-Item実行]
    O --> P[一時ファイル削除]
    M --> P
    P --> Q[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | デフォルトブランチ設定 | MaintenanceSolution/FirstResponderKit/DarlingData: main、DbaMultiTool: master | Branch未指定時 |
| BR-002 | リリースベースダウンロード | SQLWATCH/WhoIsActive/AzSqlTipsはGitHub API経由で最新リリースを取得 | 該当Software指定時 |
| BR-003 | プレリリースサポート | SQLWATCHはBranch='prerelease'でプレリリース版を取得 | Branch指定時 |
| BR-004 | SQLファイル直接インストール | WhoIsActive/AzSqlTipsは.sqlファイルを直接LocalFileとして指定可能 | LocalFileが.sql |
| BR-005 | ディレクトリ名正規化 | リリースZIPのディレクトリ名を標準名にリネーム | 展開後 |

### 計算ロジック

該当なし

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

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

該当なし（データベース操作なし）

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | リリース情報取得失敗 | GitHub APIへのアクセス失敗 | プロキシ設定を試行後、エラー終了 |
| - | リリース未発見 | リリースが存在しない | エラーメッセージ出力 |
| - | ファイル未存在 | LocalFile指定ファイルが存在しない | エラーメッセージ出力 |
| - | 拡張子不正 | LocalFileが.zipでない（.sql以外） | エラーメッセージ出力 |
| - | 展開失敗 | ZIPファイルの展開に失敗 | エラーメッセージ出力、一時ファイル削除 |
| - | ディレクトリ不一致 | アーカイブ内容が期待と異なる | エラーメッセージ出力 |

### リトライ仕様

- ダウンロード失敗時、デフォルトプロキシ設定で1回リトライ

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

該当なし（ファイルシステム操作）

## パフォーマンス要件

- ダウンロードサイズはソフトウェアにより異なる（数MB〜数十MB）
- ネットワーク帯域に依存

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

- GitHub APIアクセス（HTTPS）
- ダウンロードファイルのUnblock-File実行（Windows環境）
- プロキシ認証のサポート

## 備考

- オフライン環境では事前にZIPファイルをダウンロードし、LocalFileパラメータで指定可能
- 各ソフトウェアのダウンロードURL:
  - MaintenanceSolution: https://github.com/olahallengren/sql-server-maintenance-solution
  - FirstResponderKit: https://github.com/BrentOzarULTD/SQL-Server-First-Responder-Kit/releases
  - DarlingData: https://github.com/erikdarlingdata/DarlingData
  - SQLWATCH: https://github.com/marcingminski/sqlwatch/releases
  - WhoIsActive: https://github.com/amachanic/sp_whoisactive/releases
  - DbaMultiTool: https://github.com/LowlyDBA/dba-multitool/releases
  - AzSqlTips: https://github.com/microsoft/azure-sql-tips/releases

---

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

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

### 推奨読解順序

#### Step 1: ソフトウェア別設定を理解する

各ソフトウェアの設定ロジックを把握します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Save-DbaCommunitySoftware.ps1 | `public/Save-DbaCommunitySoftware.ps1` 107-233行目 | ソフトウェア別のBranch/Url/LocalDirectory設定ロジック |

**読解のコツ**: 各ソフトウェアはif-elseifチェーンで処理され、それぞれ固有のURL生成ロジックとディレクトリ命名規則を持ちます。

#### Step 2: ダウンロード・展開処理を理解する

ファイル取得と展開のロジックを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Save-DbaCommunitySoftware.ps1 | `public/Save-DbaCommunitySoftware.ps1` 243-314行目 | LocalFile/.sql処理、ZIPダウンロード、展開処理 |

**主要処理フロー**:
1. **243-258行目**: WhoIsActive/AzSqlTips用.sqlファイル処理
2. **260-280行目**: LocalFile（ZIP）展開処理
3. **281-314行目**: URLからのダウンロードと展開

#### Step 3: ディレクトリ名正規化を理解する

各ソフトウェアのリネーム処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Save-DbaCommunitySoftware.ps1 | `public/Save-DbaCommunitySoftware.ps1` 319-386行目 | ディレクトリ名の正規化処理 |

**主要処理フロー**:
- **324-333行目**: SQLWATCH正規化（バージョン情報保存、リネーム）
- **334-341行目**: WhoIsActive正規化
- **342-349行目**: FirstResponderKit正規化
- **350-357行目**: DbaMultiTool正規化
- **358-366行目**: AzSqlTips正規化

#### Step 4: ターゲットディレクトリコピーとクリーンアップを理解する

最終的なファイル配置とクリーンアップを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Save-DbaCommunitySoftware.ps1 | `public/Save-DbaCommunitySoftware.ps1` 388-416行目 | コピー処理、一時ファイル削除 |

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

```
Save-DbaCommunitySoftware
    │
    ├─ Get-DbatoolsConfigValue (DbatoolsDataパス取得)
    │
    ├─ Invoke-TlsWebRequest (GitHub API/ダウンロード)
    │      └─ プロキシ設定フォールバック
    │
    ├─ Expand-Archive (ZIP展開)
    │
    ├─ Unblock-File (Windows: ファイルブロック解除)
    │
    ├─ Rename-Item (ディレクトリ正規化)
    │
    ├─ Copy-Item (ターゲットへコピー)
    │
    └─ Remove-Item (一時ファイル削除)
```

### データフロー図

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

Software指定      ───▶ URL/Branch決定      ───▶
     or                      │
Url指定                      ▼
     or          ───▶ ダウンロード/展開   ───▶ 一時ディレクトリ
LocalFile                    │
                             ▼
                 ───▶ ディレクトリ正規化  ───▶ LocalDirectory
                             │
                             ▼
                 ───▶ 一時ファイル削除
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Save-DbaCommunitySoftware.ps1 | `public/Save-DbaCommunitySoftware.ps1` | ソース | メイン関数 |
| Invoke-TlsWebRequest.ps1 | `private/functions/Invoke-TlsWebRequest.ps1` | ソース | TLS対応Webリクエスト |
| Get-DbatoolsConfigValue.ps1 | `public/Get-DbatoolsConfigValue.ps1` | ソース | 設定値取得 |
| Join-DbaPath.ps1 | `public/Join-DbaPath.ps1` | ソース | パス結合 |
| Stop-Function.ps1 | `private/functions/Stop-Function.ps1` | ソース | エラー処理 |
