Skip to content

Pleasanter Setup と Rds.json の Provider ​

第5版作成 最終更新 (日本時間)
確認バージョン1.5.3.01.5.8.1

データベースの構築・更新は CodeDefiner が担います。このページでは、CodeDefiner を画面から呼び出す Pleasanter Setup の動き方と、Rds.json の Provider に "Azure" を指定したときに CodeDefiner の処理がどう変わるかをまとめます。

結論:

  • Pleasanter Setup は CodeDefiner を 決められたフローで呼び出すラッパー です。CodeDefiner のスイッチ(/p /t など)が使えないのは、Setup 側が渡す引数が限られているためです。画面が止まって見えても、logs/Implem.CodeDefiner_*.log を見れば処理中かどうか判断できます。
  • Provider: "Azure" を指定すると、CodeDefiner は テーブルの作成・更新だけ を行い、DB 作成・ユーザー作成・スキーマ作成・権限付与・セッション切断をスキップします。タイムゾーンには影響しません。

INFO

Rds.json の Provider の処理は 1.5.3.0 を対象にしています。Pleasanter Setup の節は対象バージョンの明記がない情報です。 確認したソースでも、CodeDefiner の action の分岐とログファイル名(Starter.cs#L30-L31、Starter.cs#L67-L117)、Provider の判定(Initializer.cs#L1026-L1034)、Configurator.Configure() の分岐(Configurator.cs#L25-L47)、SysLogModel.OnAzure(SysLogModel.cs#L3421)が同じであることを確認しています。

CodeDefiner の引数処理 ​

CodeDefiner は Starter.Main(string[] args) で起動引数を受け取り、ArgsType() で /p や /t のようなスイッチを辞書化して処理を分岐します。

csharp
var argHash = ArgsType(args);
var action = args[0];
var path = argHash.Get("p")?.Replace('\\', Path.DirectorySeparatorChar);
var target = argHash.Get("t");

さらに switch (action) で _rds・def・mvc などの処理を切り替える構造になっているため、CLI から細かく制御できます。

csharp
switch (action)
{
    case "_rds":
    case "def":
    case "mvc":
    // ...
}

CodeDefiner のコマンド体系全体は CodeDefiner を参照してください。

Pleasanter Setup ​

CodeDefiner のラッパーとしての位置づけ ​

Pleasanter Setup は CodeDefiner を直接 CLI として使うのではなく、Setup 画面で決められたフローで呼び出すラッパー です。

そのため、CodeDefiner 側にスイッチの実装があっても、Pleasanter Setup の画面がそのスイッチを入力項目として持っていなければ引数として渡せません。「CodeDefiner が対応していない」のではなく、Pleasanter Setup から渡される引数が限定されている ことが、CodeDefiner 単体で使えたスイッチが Setup では使えない理由です。

内部で実行される CodeDefiner の処理 ​

Pleasanter Setup の画面操作は、内部的には Implem.CodeDefiner/Starter.cs の switch (action) にある次の処理の組み合わせに相当します。

Pleasanter Setup でのフェーズCodeDefiner の actionStarter.cs で実行される処理
初期 DB 構成_rds または rdsConfigureDatabase()(rds の場合は続けてコード生成も実行)
定義・コード生成_def または def または mvcCreateDefinitionAccessorCode() / CreateMvcCode()(def は両方、_def は前者のみ)
DB 移行を伴う更新migrateConfigureDatabase() → MigrateDatabase()
パラメータ引き継ぎ系の更新mergeMergeParameters()

CLI で手動実行する場合はこれらを個別のコマンドとして直接呼び出せます。Pleasanter Setup はこの個別処理を画面フローでまとめて実行します。

図を読み込み中…

手動実行との比較 ​

観点手動インストール / 手動バージョンアップPleasanter Setup
処理の実行単位_rds、def、migrate などを個別に実行画面の操作単位で内部実行
スイッチ指定実行時に /p /t /f などを直接指定可能画面が持つ入力項目に依存
進捗の把握実行したコマンド単位で把握しやすい1 つの画面処理に見えるため内部工程が見えにくい
失敗時の切り分けどのコマンドで失敗したか追いやすいログを見て内部工程に分解して把握する必要がある

バージョンアップの手順は バージョンアップ を参照してください。

画面が止まって見えるとき ​

DB 構成、定義生成、コード生成などの長時間処理の最中は、Pleasanter Setup の画面の進捗表示が細かく更新されないため、止まっているように見えます。

ただし CodeDefiner 側はログを出力しながら処理を続けています。Starter.Main は起動時に logs/Implem.CodeDefiner_yyyyMMdd_HHmmss.log を作成し、Trace に出力しています。

csharp
LogFolderName = "logs";
LogNameText = $"Implem.CodeDefiner_{DateTime.Now:yyyyMMdd_HHmmss}";
Directory.CreateDirectory(LogFolderName);
var logName = Path.Combine(LogFolderName, $"{LogNameText}.log");
Trace.Listeners.Add(new TextWriterTraceListener(logName));
Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));

ログで実行中かを確認する ​

Pleasanter Setup の実行中に最新のログを表示すると、処理が進んでいるか判断できます。次のコマンドは Pleasanter のインストールディレクトリ(例: C:\web\pleasanter。Implem.CodeDefiner.exe と logs フォルダがある場所)で実行します。

powershell
$latestLog = Get-ChildItem .\logs\Implem.CodeDefiner_*.log |
  Sort-Object LastWriteTime -Descending |
  Select-Object -First 1

Get-Content $latestLog.FullName -Wait

次の 3 点が確認できれば、画面の更新が少なくても処理自体は動いていると判断できます。

  • ログファイルの LastWriteTime が更新され続けている
  • <INFO> や <SUCCESS> の行が追加されている
  • ログ末尾に <SUCCESS> で始まる完了メッセージ行(...Completed を含む行)が出る

1.5.8.1 では、テーブルの処理中はテーブルごとに <INFO> TablesConfigurator.ConfigureTableSet: テーブル名 の行が出て、作り直すテーブルでは Tables.MigrateTable / Tables.CreateTable の行が続きます。ログにもコンソールにも同じ行が出ます(TablesConfigurator.cs#L151-L161、Consoles.cs#L18-L45)。同じ行のまま長く止まっているときは、そのテーブルの移行(全件のコピー)が続いています。データの多いテーブルほど時間がかかります。

CodeDefiner を直接実行したときの y の確認は、DB・ユーザー・スキーマの作成 / 更新とライセンス情報の表示、Issues / Results の列の減少チェックが終わったあとに出ます。y を入力したあとに動くのはテーブルの作成・移行と権限付与です。処理の順序と移行のしかたは CodeDefiner の「データベースの作成・更新」を参照してください。

Azure App Service(Windows)の Kudu で実行するとき ​

Azure App Service(Windows)の Kudu の Debug Console で CodeDefiner を実行すると、日本語の出力が文字化けすることがあります。Kudu の CMD のコードページは chcp で確認でき(例: Active code page: 437)、chcp 65001 で UTF-8(CP65001)に切り替えられます。エラーが出ずに Active code page: 65001 と表示されれば使えます。

cmd
chcp 65001 && echo テスト

「テスト」が文字化けせずに表示されれば切り替わっています。Kudu のセッションを閉じるとコードページは元に戻るため、CodeDefiner を実行するバッチの先頭に書いておきます。

cmd
@echo off
chcp 65001 > nul
dotnet Implem.CodeDefiner.dll _rds

PowerShell の Debug Console では、chcp 65001 のあと [Console]::OutputEncoding を確認し、BodyName が utf-8 になっているかを見ます。chcp を実行しても [Console]::OutputEncoding は別途変更が必要な場合があります。Linux の App Service は既定で UTF-8 のため、この手順は要りません。

INFO

この節は Azure App Service(Windows)の Kudu で確認した内容で、プリザンターのソースとは関係しません。

Rds.json の Provider ​

設定値 ​

データベースの設定ファイル App_Data/Parameters/Rds.json には Provider という項目があります。既定値は "Local" で、Azure SQL Database などの Azure 環境で動かす場合は "Azure" を指定します。

json
{
    "Dbms": "PostgreSQL",
    "Provider": "Local",
    "SaConnectionString": "Server=localhost;Database=postgres;UID=postgres;PWD=SetSaPWD",
    "OwnerConnectionString": "Server=localhost;Database=#ServiceName#;UID=#ServiceName#_Owner;PWD=SetAdminsPWD",
    "UserConnectionString": "Server=localhost;Database=#ServiceName#;UID=#ServiceName#_User;PWD=SetUsersPWD",
    "SqlCommandTimeOut": 0,
    "MinimumTime": 3,
    "DeadlockRetryCount": 4,
    "DeadlockRetryInterval": 1000,
    "DisableIndexChangeDetection": true,
    "SysLogsSchemaVersion": 1,
    "MySqlConnectingHost": "%"
}

指定できる値は "Local" と "Azure" の 2 種類です。

初期化時の処理 ​

起動時に Initializer.SetRdsParameters() が呼ばれ、Provider の値が判定されて Environments.RdsProvider に設定されます。"Azure" 以外の値はすべて "Local" として扱われます。

csharp
public static void SetRdsParameters()
{
    Parameters.Rds.SaConnectionString =
        Parameters.Rds.SaConnectionString.Replace(
            "#ServiceName#", Environments.ServiceName);
    Parameters.Rds.OwnerConnectionString =
        Parameters.Rds.OwnerConnectionString.Replace(
            "#ServiceName#", Environments.ServiceName);
    Parameters.Rds.UserConnectionString =
        Parameters.Rds.UserConnectionString.Replace(
            "#ServiceName#", Environments.ServiceName);
    switch (Parameters.Rds.Provider)
    {
        case "Azure":
            Environments.RdsProvider = "Azure";
            break;
        default:
            Environments.RdsProvider = "Local";
            break;
    }
    Environments.DeadlockRetryCount = Parameters.Rds.DeadlockRetryCount;
    Environments.DeadlockRetryInterval = Parameters.Rds.DeadlockRetryInterval;
}

この Environments.RdsProvider が、以降の処理分岐のキーになります。

図を読み込み中…

CodeDefiner 実行時の違い ​

Provider の値が最も大きく影響するのは CodeDefiner の実行時です。Configurator.Configure() は Environments.RdsProvider == "Local" の条件で処理を分岐しています。

csharp
internal static bool Configure(
    ISqlObjectFactory factory,
    bool force,
    bool noInput,
    bool showLicenseInfo = true,
    bool checkMigration = false)
{
    if (checkMigration == false)
    {
        if (Environments.RdsProvider == "Local")
        {
            UsersConfigurator.KillTask(factory: factory);
            RdsConfigurator.Configure(factory: factory);
            UsersConfigurator.Configure(factory: factory);
            SchemaConfigurator.Configure(factory: factory);
        }
        if (CheckColumnsShrinkage(
            factory: factory,
            force: force,
            noInput: noInput,
            showLicenseInfo: showLicenseInfo))
        {
            TablesConfigurator.Configure(factory: factory);
            if (Environments.RdsProvider == "Local")
            {
                PrivilegeConfigurator.Configure(factory: factory);
            }
            return true;
        }
        return false;
    }
    else
    {
        var isCreatingDb = false;
        if (Environments.RdsProvider == "Local")
        {
            isCreatingDb = !RdsConfigurator.Exists(factory: factory, databaseName: Environments.ServiceName);
            // ... ログ出力
        }
        // ...
    }
}
処理LocalAzure
既存 DB セッションの強制切断(KillTask)実行スキップ
データベースの作成・更新(RdsConfigurator)実行スキップ
DB ユーザーの作成・更新(UsersConfigurator)実行スキップ
スキーマの作成・更新(SchemaConfigurator)実行スキップ
テーブルの作成・更新(TablesConfigurator)実行実行
ユーザー権限の付与(PrivilegeConfigurator)実行スキップ

Provider: "Azure" を設定した場合は テーブルの作成・更新だけ が実行され、それ以外の DB レベルの操作はすべてスキップされます。

スキップされる処理の内容 ​

KillTask(セッションの強制切断) ​

Owner ユーザーと User ユーザーの既存 DB セッションを KILL コマンドで強制終了します。CodeDefiner による DB 変更をロックなしで安全に実行するための前処理です。

csharp
internal static void KillTask(ISqlObjectFactory factory)
{
    KillTask(
        factory: factory,
        connectionString: Parameters.Rds.OwnerConnectionString);
    KillTask(
        factory: factory,
        connectionString: Parameters.Rds.UserConnectionString);
}

RdsConfigurator(データベースの作成・更新) ​

SA(システム管理者)権限でデータベース自体の作成や更新を行います。PostgreSQL では CREATE DATABASE、SQL Server では同等の DDL が実行されます。

csharp
internal static void Configure(ISqlObjectFactory factory)
{
    if (!Exists(factory: factory, databaseName: Environments.ServiceName))
    {
        CreateDatabase(factory: factory, databaseName: Environments.ServiceName);
    }
    else
    {
        UpdateDatabase(factory: factory, databaseName: Environments.ServiceName);
    }
}

UsersConfigurator(DB ユーザーの作成・更新) ​

_Owner ユーザー(管理者)と _User ユーザー(一般)の DB ログインを作成・更新します。CREATE LOGIN や ALTER LOGIN に相当する SQL が SA 権限で実行されます。

csharp
private static string CreateUserCommandText(string uid, string pwd, string host)
{
    return uid.EndsWith("_Owner")
        ? Def.Sql.CreateLoginAdmin
            .Replace("#Pwd#", pwd)
            .Replace("#MySqlConnectingHost#", host)
        : Def.Sql.CreateLoginUser
            .Replace("#Pwd#", pwd)
            .Replace("#MySqlConnectingHost#", host);
}

SchemaConfigurator(スキーマの作成・更新) ​

CREATE SCHEMA でスキーマを作成し、Owner・User に対してアクセス権を設定します。PostgreSQL での運用を想定した処理です。

csharp
internal static void Configure(ISqlObjectFactory factory)
{
    if (factory.SqlDefinitionSetting.IsCreatingDb)
    {
        Def.SqlIoByAdmin(factory).ExecuteNonQuery(
            factory: factory,
            dbTransaction: null,
            dbConnection: null,
            commandText: Def.Sql.CreateSchema
                .Replace("#Uid_Owner#", ocn["uid"])
                .Replace("#Uid_User#", ucn["uid"])
                .Replace("#SchemaName#", factory.SqlDefinitionSetting.SchemaName));
    }
    // ...
}

PrivilegeConfigurator(権限付与) ​

GRANT 文で、Owner ユーザーには管理者権限を、User ユーザーには一般権限を付与します。

csharp
private static void Execute(ISqlObjectFactory factory, string connectionString, string host)
{
    var cn = new TextData(connectionString, ';', '=');
    if (cn["uid"].EndsWith("_Owner"))
    {
        // GRANT PRIVILEGE ADMIN を実行
    }
    else
    {
        // GRANT PRIVILEGE USER を実行
    }
}

Azure でスキップされる理由 ​

Azure SQL Database は Microsoft が提供するマネージドな PaaS サービスで、ローカル環境とは次の点が異なります。

項目ローカル SQL ServerAzure SQL Database
DB 作成SA 権限で実行可能Azure ポータルや ARM テンプレートで事前作成
SA 権限利用可能利用不可(マネージドサービスの制約)
セッション強制終了sp_who + KILL で可能SA レベル操作は制限される
ユーザー管理CREATE LOGIN で作成Azure AD 認証や SQL 認証はポータルで管理
スキーマ・権限管理SA で自由に設定事前に設定済みの想定

Azure SQL Database では、DB 作成、ユーザー管理、権限設定などのインフラレベルの管理は Azure が担います。CodeDefiner は「テーブルの作成・更新」だけを担当し、ほかの処理は Azure 側で事前に済んでいることが前提になっています。

アプリ実行時(SysLogs)への影響 ​

アプリケーションの実行時にも RdsProvider が使われます。ログを記録するとき、OnAzure プロパティに Environments.RdsProvider == "Azure" の結果が設定されます。

csharp
private void SetProperties(
    Context context,
    SysLogTypes sysLogType = SysLogTypes.Info)
{
    SysLogType = sysLogType;
    OnAzure = Environments.RdsProvider == "Azure";
    MachineName = Environments.MachineName;
    // ...
}

この値は SysLogs テーブルの OnAzure 列に保存されるため、ログのフィルタリングや分析に使えます。

タイムゾーンへの影響はない ​

Azure 環境では OS のタイムゾーンが UTC になることが多いため、Provider: "Azure" がタイムゾーンを UTC にしているように見えることがあります。しかし、Provider の設定とタイムゾーンの処理は 完全に独立 しています。

タイムゾーンは App_Data/Parameters/Service.json の TimeZoneDefault で設定します。

json
{
    "Name": "Implem.Pleasanter",
    "TimeZoneDefault": "UTC",
    ...
}

起動時に Initializer.SetTimeZone() が呼ばれ、この値から Environments.TimeZoneInfoDefault が設定されます。

csharp
private static void SetTimeZone()
{
    Environments.TimeZoneInfoDefault = TimeZoneInfo.GetSystemTimeZones()
        .FirstOrDefault(o => o.Id == Parameters.Service.TimeZoneDefault)
            ?? TimeZoneInfo.Utc;
    Def.ColumnDefinitionCollection
        .FirstOrDefault(o => o.Id == "Users_TimeZone").Default = Environments.TimeZoneInfoDefault.Id;
}

TimeZoneDefault に一致するタイムゾーンが見つからない場合は TimeZoneInfo.Utc にフォールバックします。既定値が "UTC" なので、変更しなければ UTC で動作します。RdsProvider の値はこの処理に一切関与しません。Azure 環境で UTC になるのは、Service.json の設定とサーバー OS のタイムゾーンが UTC であることが原因です。

タイムゾーンの考え方は タイムゾーンの考え方 を参照してください。

関連ページ ​

変更履歴

第5版記事の確認版を繰り返す表現を整理する
第4版CodeDefiner のデータベース作成・更新とパラメータの引き継ぎ、画面でのパラメータ管理、MCP エンドポイントのブラウザアクセスの解説と、関連する改修・設計メモを追加
第3版「内部実装を読む」を 1.5.8.1 のソースで検証して修正
第2版記事のファイル名に並び順の番号を付け、元記事リンクを frontmatter の sources に移行
第1版「内部実装を読む」に SiteSettings・Upsert・Pleasanter Setup を追加