# 画面設計書 214-コミュニティソフトウェア保存

## 概要

本ドキュメントは、dbatools PowerShellモジュールにおける「コミュニティソフトウェア保存」機能（Save-DbaCommunitySoftware）の画面設計書です。SQL Serverコミュニティで人気のあるツールをGitHubからダウンロードしてローカルキャッシュに保存する機能を提供します。

### 本画面の処理概要

**業務上の目的・背景**：SQL Server管理者は、Ola Hallengren's Maintenance Solution、First Responder Kit、sp_WhoIsActive、SqlWatchなど、コミュニティが開発した様々なツールを利用します。これらのツールを手動でダウンロード・管理するのは手間がかかります。Save-DbaCommunitySoftwareは、これらのツールを自動的にダウンロードしてローカルキャッシュに保存し、Install-Dba*やUpdate-Dba*コマンドから利用できるようにします。

**画面へのアクセス方法**：PowerShellコンソールから `Save-DbaCommunitySoftware` コマンドを実行します。通常は内部的に他のコマンドから呼び出されますが、手動でキャッシュを更新することも可能です。

**主要な操作・処理内容**：
1. GitHubリポジトリまたはReleases APIから最新バージョンを取得
2. zipファイルをダウンロードして一時ディレクトリに展開
3. ディレクトリ構造を正規化（リリースバージョン名を標準名に変換）
4. ローカルキャッシュディレクトリにコピー
5. 一時ファイルを削除

**画面遷移**：CLIコマンドのため画面遷移はありません。Install-DbaMaintenanceSolution、Install-DbaFirstResponderKit、Install-DbaWhoIsActive、Install-DbaSqlWatch、Install-DbaMultiTool、Invoke-DbaAzSqlDbTipから内部的に呼び出されます。

**権限による表示制御**：ファイルシステムへの書き込み権限が必要です。インターネットアクセスがない環境ではLocalFileパラメータを使用します。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 326 | Save-DbaCommunitySoftware | 主機能 | コミュニティソフトウェアのダウンロード・保存 |
| 313 | Install-DbaMaintenanceSolution | 呼び出し元 | MaintenanceSolutionのインストール時に呼び出し |
| 309 | Install-DbaFirstResponderKit | 呼び出し元 | FirstResponderKitのインストール時に呼び出し |
| 319 | Install-DbaWhoIsActive | 呼び出し元 | WhoIsActiveのインストール時に呼び出し |
| 323 | Install-DbaSqlWatch | 呼び出し元 | SqlWatchのインストール時に呼び出し |
| 321 | Install-DbaMultiTool | 呼び出し元 | DbaMultiToolのインストール時に呼び出し |

## 画面種別

コマンドライン（CLI）実行画面

## URL/ルーティング

```powershell
Save-DbaCommunitySoftware -Software <ソフトウェア名> [-Branch <ブランチ名>] [-LocalFile <ファイルパス>]
```

## 入出力項目

### パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|------|-------------|------|
| Software | string | No | - | ダウンロードするソフトウェア名（MaintenanceSolution/FirstResponderKit/DarlingData/SQLWATCH/WhoIsActive/DbaMultiTool/AzSqlTips） |
| Branch | string | No | ソフトウェアにより異なる | ダウンロードするブランチ（main/master/prerelease等） |
| LocalFile | string | No | - | ローカルzipファイルまたはSQLファイルのパス |
| Url | string | No | - | カスタムダウンロードURL |
| LocalDirectory | string | No | - | カスタム保存先ディレクトリ |
| EnableException | switch | No | $false | 例外を有効化 |

### サポートされるソフトウェア

| Software値 | 説明 | デフォルトBranch | キャッシュディレクトリ |
|------------|------|-----------------|---------------------|
| MaintenanceSolution | Ola Hallengren's SQL Server Maintenance Solution | main | sql-server-maintenance-solution-main |
| FirstResponderKit | Brent Ozar's First Responder Kit | main | SQL-Server-First-Responder-Kit-main |
| DarlingData | Erik Darling's stored procedures | main | DarlingData-main |
| SQLWATCH | Marcin Gminski's SQL Server Monitoring Solution | - | SQLWATCH |
| WhoIsActive | Adam Machanic's sp_WhoIsActive | - | WhoIsActive |
| DbaMultiTool | John McCall's DBA MultiTool | master | dba-multitool-master |
| AzSqlTips | Azure SQL PM team scripts | - | AzSqlTips |

## 表示項目

このコマンドはオブジェクトを出力しません。ファイル操作のみを実行します。

## イベント仕様

### 1-コマンド実行時

1. Softwareパラメータに基づいてダウンロードURLとローカルディレクトリを決定
2. SQLWATCH、WhoIsActive、AzSqlTipsの場合はGitHub Releases APIで最新リリースを取得
3. LocalFileが指定された場合:
   - WhoIsActive/AzSqlTipsで.sqlファイルの場合は直接コピー
   - .zipファイルの場合は展開
4. URLからダウンロードの場合:
   - Invoke-TlsWebRequestでzipファイルをダウンロード
   - 一時ディレクトリに展開
5. ディレクトリ名を正規化:
   - SQLWATCH: "SQLWATCH 4.3.0.23725 20210721131116" -> "SQLWATCH"
   - WhoIsActive: "amachanic-sp_whoisactive-459d2bc" -> "WhoIsActive"
   - FirstResponderKit: "SQL-Server-First-Responder-Kit-20211106" -> "SQL-Server-First-Responder-Kit-main"
   - DbaMultiTool: "dba-multitool-1.7.5" -> "dba-multitool-master"
   - AzSqlTips: "azure-sql-tips-1.10" -> "AzSqlTips"
6. 既存のキャッシュディレクトリを削除
7. 新しいディレクトリをキャッシュ先にコピー
8. 一時ファイル・ディレクトリを削除

## データベース更新仕様

このコマンドはデータベースを更新しません。ファイルシステムへの書き込みのみを行います。

### 操作別ファイルシステム影響一覧

| 操作（イベント） | 対象パス | 操作種別 | 概要 |
|----------------|---------|---------|------|
| ダウンロード | $env:TEMP\dbatools_software_download_*.zip | CREATE | 一時zipファイル作成 |
| 展開 | $env:TEMP\dbatools_software_download_* | CREATE | 一時展開ディレクトリ作成 |
| コピー | Path.DbatoolsData\{ソフトウェア名} | REPLACE | キャッシュディレクトリ更新 |
| クリーンアップ | 一時ファイル・ディレクトリ | DELETE | 一時ファイル削除 |

## メッセージ仕様

| 種別 | メッセージ | 発生条件 |
|------|----------|---------|
| エラー | Unable to get release information from {releasesUrl} | GitHub API呼び出し失敗時 |
| エラー | No release found | リリースが存在しない場合 |
| エラー | {LocalFile} doesn't exist | LocalFileが存在しない場合 |
| エラー | {LocalFile} has to be a zip file | LocalFileがzipファイルでない場合 |
| エラー | Unable to extract {LocalFile} to {zipFolder} | 展開失敗時 |
| エラー | Url not found. Did you specify any -Software? | URLが決定できない場合 |
| エラー | Unable to download {Url} to {zipFile} | ダウンロード失敗時 |
| エラー | The archive does not contain the desired directory | アーカイブ内容が不正な場合 |
| エラー | Unable to remove the old target directory | 既存ディレクトリ削除失敗時 |
| エラー | Unable to copy the directory | コピー失敗時 |

## 例外処理

| 例外条件 | 動作 |
|---------|------|
| GitHub API呼び出し失敗 | 既定のプロキシ設定でリトライ、それでも失敗時はStop-Function |
| リリース未存在 | Stop-Functionで処理を中断 |
| LocalFile未存在 | Stop-Functionで処理を中断 |
| LocalFileがzipファイルでない | Stop-Functionで処理を中断（WhoIsActive/AzSqlTipsの.sqlは例外） |
| 展開失敗 | Stop-Functionでエラーを報告 |
| ダウンロード失敗 | 既定のプロキシ設定でリトライ、それでも失敗時はStop-Function |
| ディレクトリ削除失敗 | Stop-Functionでエラーを報告、一時ファイルを削除 |
| コピー失敗 | Stop-Functionでエラーを報告、一時ファイルを削除 |

## 備考

- インターネットアクセスがない環境では、以下のURLから手動でzipファイルをダウンロードしてLocalFileパラメータで指定可能:
  - 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
- WhoIsActiveとAzSqlTipsは.sqlファイルを直接指定可能
- SQLWATCHのprereleaseブランチでプレリリース版を取得可能
- キャッシュはPath.DbatoolsData設定値のディレクトリに保存

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Save-DbaCommunitySoftware.ps1 | `public/Save-DbaCommunitySoftware.ps1` | 出力なし（行77-79） |

**読解のコツ**: このコマンドは出力オブジェクトを返しません。ファイル操作のみを実行します。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Save-DbaCommunitySoftware.ps1 | `public/Save-DbaCommunitySoftware.ps1` | パラメータ定義（行93-101）とソフトウェア別URL/ディレクトリ設定（行107-233） |

**主要処理フロー**:
1. **行103-233**: ソフトウェア別のURL、ブランチ、ローカルディレクトリの決定
2. **行235-314**: ダウンロードと展開処理
3. **行316-386**: ディレクトリ名の正規化とアーカイブ内容の検証
4. **行388-415**: キャッシュディレクトリへのコピーとクリーンアップ

#### Step 3: ソフトウェア別処理を理解する

| ソフトウェア | URL生成方式 | 行番号 |
|-------------|------------|--------|
| MaintenanceSolution | ブランチベース | 107-116 |
| FirstResponderKit | ブランチベース | 117-126 |
| DarlingData | ブランチベース | 127-136 |
| SQLWATCH | Releases API | 137-170 |
| WhoIsActive | Releases API | 171-196 |
| DbaMultiTool | ブランチベース | 197-206 |
| AzSqlTips | Releases API | 207-233 |

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

```
Save-DbaCommunitySoftware
    |
    +-- Get-DbatoolsConfigValue
    |      +-- Path.DbatoolsDataの取得
    |
    +-- Invoke-TlsWebRequest
    |      +-- GitHub Releases API呼び出し（SQLWATCH/WhoIsActive/AzSqlTips）
    |      +-- zipファイルダウンロード
    |
    +-- Expand-Archive
    |      +-- zipファイル展開
    |
    +-- Get-ChildItem / Rename-Item
    |      +-- ディレクトリ名正規化
    |
    +-- Copy-Item
    |      +-- キャッシュディレクトリへコピー
    |
    +-- Remove-Item
           +-- 一時ファイル削除
```

### データフロー図

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

Software ─────────▶ URL/Branch/LocalDirectory決定 ────▶ 設定値
      |
      v
(SQLWATCH/WhoIsActive/AzSqlTips)
GitHub Releases API ──▶ Invoke-TlsWebRequest ─────────▶ 最新リリースURL
      |
      v
URL ──────────────▶ Invoke-TlsWebRequest ─────────────▶ 一時zipファイル
      |
      v
zipファイル ───────▶ Expand-Archive ───────────────────▶ 一時展開ディレクトリ
      |
      v
展開ディレクトリ ──▶ Rename-Item（正規化）────────────▶ 標準名ディレクトリ
      |
      v
                    Copy-Item ────────────────────────▶ キャッシュディレクトリ
      |
      v
                    Remove-Item ──────────────────────▶ 一時ファイル削除
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Save-DbaCommunitySoftware.ps1 | `public/Save-DbaCommunitySoftware.ps1` | ソース | メインコマンド実装 |
| Install-DbaMaintenanceSolution.ps1 | `public/Install-DbaMaintenanceSolution.ps1` | 呼び出し元 | MaintenanceSolution呼び出し |
| Install-DbaFirstResponderKit.ps1 | `public/Install-DbaFirstResponderKit.ps1` | 呼び出し元 | FirstResponderKit呼び出し |
| Install-DbaWhoIsActive.ps1 | `public/Install-DbaWhoIsActive.ps1` | 呼び出し元 | WhoIsActive呼び出し |
| Install-DbaSqlWatch.ps1 | `public/Install-DbaSqlWatch.ps1` | 呼び出し元 | SqlWatch呼び出し |
| Install-DbaMultiTool.ps1 | `public/Install-DbaMultiTool.ps1` | 呼び出し元 | MultiTool呼び出し |
| Invoke-DbaAzSqlDbTip.ps1 | `public/Invoke-DbaAzSqlDbTip.ps1` | 呼び出し元 | AzSqlTips呼び出し |
