#コンテスト

0 フォロワー · 151 投稿

コンテストタグは、InterSystems開発者コミュニティで行われているコーディングコンペティションに関連する投稿をまとめたものです。

記事 Kosaku Ikeda · 10月 26, 2025 14m read

コミュニティの皆さんこんにちは。
 

ベクトル検索関連の処理が完全にノーマークだった私が、一先ず「やってみよう!」との事で、2つの動画のサンプルを実行してみました。
Pythonは初心者なので、アレな箇所があっても目をつぶっていただけると幸いです。

また、間違っている箇所があったら、ご指摘いただけると幸いです。


■参考にした動画

■参考にしたコミュニティ記事

【目的】

本記事では、動画で紹介された内容を実際にIRIS環境上で実行できるよう、具体的な環境構築とコーディングを記載致します。
コミュニティの皆さんが簡単に試せるようになれば幸いです。

またGithubにサンプルソースを配置しているので、必要な方は参考にして下さい。

【準備】

■作業環境

※環境作成方法に問題のない方は、読み飛ばしていただいて構いません。

項目 バージョン情報・他
OS WIndowsServer2019
IRIS IRIS Community 2025.2.0.227.0
Python 3.12.10
開発環境 VS Code 1.105.1
0
0 41
記事 Toshihiko Minamoto · 10月 16, 2025 2m read

私が先週リリースしたInterSystems Testing Managerの新しいバージョンでは、@Timothy Leavittの優れた
テストカバレッジツールが追加され、私は2025年度Developer Toolsコンテストに出品しました。

こちらは、IPMプロジェクトのユニットテストが、IPMリポジトリでソート順を上書きできると思われる機能をまだカバーしていないことを示すティザー的なスクリーンショットです。

88行目が開発者への警告として赤くハイライトされていることに注目してください。

VS Codeのエクスプローラービューには「バッテリーインジケーター」風のアイコンが表示されており、このクラスのメソッド内の実行可能な行のうち、テストでカバーされているのが76%のみであるため、黄色になっています。 インジケーターにカーソルを合わせると、さらに詳しい情報が表示され、メソッドのカバレッジ(9個中8個)が、エディター内のオプションのテストカバレッジツールバーに第2のインジケーターとして表示されます。

VS Codeでは、しきい値を設定できるほか、赤・黄・緑が区別しにくい場合には、色自体も構成できます。

いかがでしょうか? すでにInterSystemsの%UnitTestフレームワークをご利用中であれば、ぜひご自身でもお試しください。 ご意見・ご感想は大歓迎です。コンテストの投票への投票もぜひお願いします。投票は米国東部時間で8月3日(日)深夜まで受け付けています。

0
0 20
お知らせ Toshihiko Minamoto · 10月 14, 2025

%UnitTestフレームワークのユーザーは、InterSystems Testing Manager拡張機能の最新リリース(v2.0.0)を@Timothy Leavittの素晴らしいテストカバレッジツールと組み合わせることで、VS Code内でテストカバレッジ情報を取得できるようになりました。

上部にテストカバレッジのペインが表示されています。左側のテストエクスプローラーと併せて確認しやすいように、右側のセカンダリサイドバーに移動させました。

直近のテスト実行(テストカバレッジツール自体のユニットテストすべて)の結果、TestCoverage.Procedures内のBitValueメソッドはカバーされていましたが、BitCountメソッド(および他の6つのメソッド)はカバーされていないことに注目してください。 TestCoverageパッケージの全体で43.08%の実行可能行のみが、ユニットテストによってカバーされていました。

InterSystems Testing Managerに対するこの大幅なアップグレードを、現在開催中のDeveloper Toolsコンテスト に出品します。 もし良いと思っていただけたら、来週の投票でぜひ応援してください!

0
0 29
お知らせ Mihoko Iijima · 9月 30, 2025

開発者の皆さん、こんにちは!本日(10月1日)よりコンテストへご応募いただけます💨

✅コンテスト詳細👉「第3回 InterSystems Japan 技術文書ライティングコンテスト 開催!

✅応募方法👉「記事の投稿方法:第 1 回技術文書ライティングコンテスト

✅応募記事一覧👉「技術文書ライティングコンテスト一覧

0
0 27
お知らせ Mihoko Iijima · 9月 25, 2025

開発者の皆さんこんにちは!

技術文書ライティングコンテストの開始(10月1日)まであと少しとなりました!💨

このお知らせでは、今年の賞品を発表いたします!

👀

🎁賞品情報🎁

審査員投票とコミュニティメンバーからの「いいね」の数の合計で順位を決定します。

1位~3位を受賞された方は、各順位に記載された賞品の中からお好きな1点をお選びいただけます。(1位の方は1~3位の賞品を、2位の方は2~3位の賞品をお選びいただけます)

🥇 1位

  • リカバリーウェア TENTIAL BAKUNEシリーズ
  • スマートリング Re・De Ring
  • アウトドアの体験ギフト EXCITING Gift Premium -エキサイティング プレミアム

🥈 2位

  • MYTREX DR. HEAT NECK
  • ソーダーストリーム TERRA スターターキット
  • アウトドアの体験ギフト EXCITING Gift -エキサイティング

🥉 3位

  • Bluetoothスピーカー
  • モレスキン クラシックダイアリー Large
  • スタバギフトカード(5000円)

🎁参加賞:投稿いただいた方全員に「モバイルバッテリー」をプレゼント!

1回目、2回目とは異なる賞品を!ということで賞品決めチームでいろいろ探してみました👀

高得点を狙う場合は、早めの投稿がおすすめです!(コミュニティメンバーからの「いいね」ポイントをより多くゲットできます!)

0
0 52
お知らせ Mihoko Iijima · 9月 9, 2025

開発者の皆さん、こんにちは!

今年で 3 回目となりますが、✍技術文書ライティングコンテスト✍ 開催します!

📣9/26更新:賞品、参加賞決定しました!

📣 9/29更新:コンテスト投稿一覧ページ準備完了です!

📣 11/6更新:応募期間を1週間延長し、応募締切は11月24日(月)に変更しました!

テーマはいつもと同じで InterSystems IRIS/InterSystems IRIS for Health に関連した内容であればどのような内容でもご応募いただけます。

🎁 参加賞:投稿いただいた方全員に「モバイルバッテリー」をプレゼント!

🏆 特別賞:選ばれた3作品に、今年も特別賞あります!詳細はこちら

コンテストへの応募はとても簡単です。2025年10月1日(水)~11月1724日(月)までの期間に開発者コミュニティに「IRISに関連した記事」を投稿してください。

もちろん!今年も🍆ボーナスポイント🍆あります!こちらをご参照ください!

1
0 100
お知らせ Mihoko Iijima · 8月 5, 2025

開発者の皆さん、こんにちは!

InterSystems Developer Tool コンテスト の勝者が発表されましたのでお知らせします!

今回のコンテストには、17 の素晴らしいアプリケーション 🔥🔥が投稿されました。

ご応募いただきました参加者の皆さん、素敵な作品をありがとうございました!

それでは受賞者を発表します!

0
0 26
お知らせ Mihoko Iijima · 7月 9, 2025

開発者の皆さん、こんにちは!

開発者の方々の業務を効率化する有用なツールの開発を目的とした、InterSystems のオンラインプログラミングコンテストの開催が決定しました!📣

🏆 InterSystems Developer Tools コンテスト 🏆

期間:2025年7月14日~8月3日

賞金総額: $12,000


0
0 43
記事 Andre Larsen Barbosa · 6月 9, 2025 3m read

image

相手に隙を与えないノックアウトパンチのように、オープンソースプラットフォームであるKubernetesは、その可用性(つまり、サポート、サービス、ツールの容易な入手性)により、無限の可能性を秘めています。Kubernetesはコンテナ内のジョブとサービスを管理できるプラットフォームであり、これらのプロセスの構成と自動化を大幅に簡素化します。

しかし、タイトルイメージにふさわしい、このツールに「正しい」名前、InterSystems Kubernetes Operatorを与えましょう。

原理は至ってシンプルです。サービスを選択し、ゲームのルールを定義するだけで(ここでもKnockoutを参照)、すべてが可能な限り透明性と効率性を高めて提供されます。これは、インストール、修復、そして事前定義された要件を満たさない場合の最終的な復旧にも適用されます。

では、IKOと他のオペレーターの違いは何でしょうか?Kubernetes API(ここではK8sと略します)の拡張機能であるIrisClusterカスタムコンポーネントは、ロックされたIRISクラスター、分散Cachéクラスター、さらには匿名インスタンスとしてデプロイするオプションを備えています。これらすべてを、最も多様なKubernetesプラットフォーム上で実行できます。最後に、InterSystemsのクラスタ管理機能も搭載されており、以前は手動でしか実行できなかったノードの追加によるタスクの自動化が可能になります。

これは非常に魅力的で、スポーツやゲームに例えられていますが、なぜ必要なのでしょうか?答えは比較的簡単です。InterSystems IRISをK8sに統合するためにIrisClusterは必要ありません。しかし、K8sはスタンドアロンアプリケーションであるため、これらのIRISインスタンスを構成するための定義とスクリプトを作成する必要があります。このように、IKOはこのプロセスを自動化し、メンテナンスを容易にします。コンテナを使用することは、必要な一連のアクティビティをパッケージ化する優れた方法です。

ところで、この機会を活用してみてはいかがでしょうか?コンテナとは何かご存知ですか?ヒント:単なるボードゲームではありません。

image

答えは、あるパッケージの「輸送」に大きく関係しています。アプリケーションとサービスをパッケージ化して分離し、他の部分とは独立して実行できるようにするためです。これにより、必要に応じて、ある環境から別の環境への「輸送」が容易になります。

InterSystemsの膨大なドキュメントを活用し、IKOのインストールとその後の設定および調整手順へのリンクを以下に示します。

https://docs.intersystems.com/components/csp/docbook/DocBook.UI.Page.cls...

K8sというニックネームに誰も興味を持たないように。Kubernetesという名前はギリシャ語に由来し、水先案内人、つまり指揮官を意味します。そして、先頭の「K」と末尾の「S」の間の文字数は8です。つまり、「K8s」です。

0
0 35
お知らせ Mihoko Iijima · 6月 2, 2025

開発者の皆さん、こんにちは!

InterSystems FHIR とデジタルヘルスの相互運用性コンテスト 2025 の勝者が発表されました!

今回のコンテストには、11 の素晴らしいアプリケーション 🔥 が投稿されました。

ご応募いただきました参加者の皆さん、素敵な作品をありがとうございました!

それでは受賞者を発表します!

0
0 34
お知らせ Mihoko Iijima · 5月 7, 2025

開発者の皆さん、こんにちは!

次のコンテストの詳細が発表されましたのでご案内します。

🏆 InterSystems FHIR とデジタルヘルスの相互運用性コンテスト 2025 🏆

期間:2025年5月12日~6月1日

賞金総額:$12,000


0
0 37
お知らせ Mihoko Iijima · 4月 8, 2025

開発者の皆さん、こんにちは!

InterSystems AI プログラミングコンテスト:ベクトル検索、生成AI、AIエージェント(USコミュニティ)の勝者が発表されましたのでお知らせします!

今回のコンテストには 15 の素晴らしいアプリケーション 🔥が投稿されました。

ご応募いただきました参加者の皆さん、素敵な作品をありがとうございました。  

それでは受賞者を発表します!

0
0 42
お知らせ Mihoko Iijima · 3月 10, 2025

開発者の皆さん、こんにちは!

25人のコミュニティメンバーが参加した InterSystems 技術文書ライティングコンテスト(USコミュニティ) ですが、なんと!

🌟 38 の素晴らしい記事 🌟の投稿がありました!

コンテストは、革新性と専門知識をもった参加者による非常に質の高い記事が数多く投稿されたため、審査員によるベスト 3 の選出は簡単ではありませんでした。

それでは、受賞作品を発表します!

0
0 53
お知らせ Mihoko Iijima · 2月 28, 2025

開発者の皆さん、こんにちは!

今年最初のプログラミング・コンテスト(USコミュニティ)の開催が決定しました!

🏆 InterSystems AI プログラミングコンテスト:ベクトル検索、生成AI、AIエージェント 🏆

期間:2025年3月17日~4月6日

賞品総額:$12,000 + GlobalSummit2025 へご招待!


0
0 91
お知らせ Mihoko Iijima · 1月 26, 2025

開発者の皆さん、こんにちは!

2025 年最初のコンテスト開催が決定しました!

✍️ InterSystems 技術文書ライティングコンテスト 2025(USコミュニティ) ✍️

InterSystems 製品やサービスに関連した記事であればどのような内容でもご応募いただけます。

🎁 投稿者全員に参加賞あります: コンテストに投稿いただいた参加者全員にスペシャルな参加賞をご用意いたします!

0
0 57
お知らせ Mihoko Iijima · 11月 24, 2024

開発者の皆さん、こんにちは!

🎄 クリスマスの雰囲気が漂いはじめた今日のこの頃、今年最後のプログラミングコンテストで何か新しいことに挑戦するのはどうでしょうか? 

🏆 アイデア実現コンテスト 🏆

Community Opportunity のステータスを持ち、実際のプログラミングを必要とするInterSystems Ideas Portal のアイデアを実装した作品をご応募ください。

期間:2024年12月2日~22日

賞金総額: $14,000

0
0 59
お知らせ Toshihiko Minamoto · 11月 6, 2024

VS Code には強力なスニペット機能が備わっており、Marketplace は開発者がスニペットを公開して使用できる方法を提供しています。 ただし、Marketplace での公開は面倒である上、InterSystems コーダーを対象としたスニペットは、現実的には Marketplace の訪問者のごく少数にしか興味を持たれません。

このことから、oex-vscode-snippets-template を作成する発想を得ました。InterSystems 開発者向けのコードスニペットを公開するための専用リポジトリを作成する GitHub テンプレートです。

また、oex-vscode-snippets-example というスニペットサンプルのリポジトリも Open Exchange で公開され、IPM / ZPM を使ってインストールされます。 以下のようにして、ネームスペースにパッケージをインストールします。

zpm "install vscode-snippets-John.Murray-example"

次に Server Manager と InterSystems ObjectScript 拡張機能を使用してそのネームスペースのサーバーサイドを編集する際は、コード補完(Ctrl+Space)リストに TODO コメントを挿入するための複数のスニペットが含まれるようになります。

oex-vscode-snippets-template は 2023 Grand Prix に出品中です。 気に入っていただけたら投票してください。 フィードバックもお待ちしています。

0
0 44
お知らせ Mihoko Iijima · 10月 28, 2024

開発者の皆さん、こんにちは!

第2回 技術文書ライティングコンテスト に応募された作品のボーナスポイント獲得状況をお知らせします📣(順位発表は11月1日を予定しています)

記事 EmbeddedPythonに関連する記事(4点) 生成AIに関連する記事(4点) FHIRに関連する記事(3点) コードの記述が含まれる記事(2点) 動作するコードサンプルをGitリポジトリへ公開する(5点) 記事の内容に関連した画面キャプチャや図を貼る(1点) 合計点
FHIR Object Modelを使ったInteroperability開発     11
UnitTest(ユニットテスト)の自動化について考察        

6

IRIS環境設定の自動化について~インストールマニフェストの利用~     12
Embedded Python を利用する時の注意点

      7
IRIS開発における生成AIの活用について       7
SourceControlを用いた自動ソースチェックツールについて       8
0
0 71
お知らせ Mihoko Iijima · 10月 20, 2024

開発者の皆さん、こんにちは!

🖋 InterSystems Japan 技術文書ライティングコンテスト2024:IRISに関連した記事 🖋の応募受付期間が終了し、残るは投票のみとなりました!

第2回目のコンテストは✨6作品✨の応募がありました!

コミュニティメンバーは「イイネ」 をクリックすることで投票できます。2024年10月31日(木)23時59分59秒 まで投票受付中です。

素晴らしい6作品のなかから、🔥これだ!🔥と思う記事の「イイネ」をクリックしてください。

以下、投票方法についてご案内します。

(1) 開発者コミュニティにログインする。

ログインアカウントをお持ちでない方は、コミュニティページ上部の  (下図赤枠)をクリックし、アカウント登録を行って下さい。

クリックした後の流れは「アカウント作成方法」の記事をご参照ください。

(2) 投稿記事一覧ページに移動します。

投稿記事を👀じっくり読みます👀

(3) 「いいね」をクリックします。

投稿記事一覧ページ上でクリックする場合はそれぞれの投稿画面左下にあるのマークをクリックします。クリック前はグレーの表示ですがクリック後に変わります。

各記事を参照している状態で「いいね」をクリックする場合は、画面左側にアイコン一覧が縦に並んでいますのでのマークをクリックします。

良い記事が見つかったらをクリックして作者を応援しましょう!📣

0
0 89
お知らせ Mihoko Iijima · 8月 2, 2024

開発者の皆さん、こんにちは!

昨年初めて開催した日本の InterSystems 開発者コミュニティのコンテストですが、📣今年も開催します!📣

テーマは昨年と同じで InterSystems IRIS/InterSystems IRIS for Health に関連した内容であればどのような内容でもご応募いただけます。

🖋 InterSystems Japan 技術文書ライティングコンテスト2024:IRISに関連した記事 🖋

🎁 参加賞:投稿いただいた方全員に👚開発者コミュニティ特製Tシャツ👕をプレゼントいたします!

🏆 特別賞:選ばれた3作品に特別賞があります。

8/30更新:賞品情報追加しました!ぜひご確認ください!👇

4
0 324
記事 Kawasaki Kazuhito · 10月 14, 2024 15m read

開発者の皆様はじめまして。 私からはIRISのソースコントロール機能を用いたソースの自動チェック機能のご紹介をしたいと思います。 チーム開発では、ソースの可読性や実装方法等がある程度統一されるようにコーディング規約を作成すると思います。 しかし、メンバーの入れ替わりでコーディング規約の説明をしていても徹底されないことが起こることも少なくありません。 なので、ソースコントロールを使用してコンパイル時に自動的にチェックするようにしました。 IRIS内で完結させるメリットとして、エラーチェックだけでなくチェック後にエラーがなければコンパイルまで自動で行えること、 %Dictionary.ClassDefinition(クラス定義)を使用できるので、チェッククラスを作成しやすいこと等があげられます。

目次

  1. ソースコントロールについて
  2. 今回用意したチェック用クラスの紹介
  3. ソースコントロールへの設定
  4. 実際の動作
  5. 感想

1.ソースコントロールについて まず、ソースコントロールについて簡単に記載します。 ソースコントロールとは、一般的にコードに対する変更を追跡し管理することを表します。 IRISのソースコントロール機能には様々なメソッドが用意されています。 今回はそれを使用することでソースの自動チェック機能を実現していきます。 参考リンク:InterSystems IRIS とソース・コントロール・システムの統合、 ソース・コントロール設定の構成

2.今回用意したチェック用クラスの紹介 今回作成したチェック用クラスには基底クラスとして、「%Studio.SourceControl.Base」と「%Studio.Extension.Base」(%Studio.SourceControl.Baseの基底クラス)を使用しています。 上記のクラスにはログイン時のイベントやロード前イベントなどが定義されており、今回は「OnBeforeCompile」(コンパイル前イベント)を使用しました。 image

では、実際のチェック用クラスの内容をご紹介します。 今回は以下をコーディング規則として実装をしています。 ①クラスの命名チェック - 「XXXX」始まりのクラス名であること ②インデントチェック - インデントは4の倍数の半角空白で埋めること ③変数の利用チェック - 定義した変数は利用すること ④引数の利用チェック - パラメータとして受け取った引数は利用すること

Class User.CompileChk Extends %Studio.SourceControl.Base
{

///  処理概要 :コンパイル前チェック
///  <br>IN :InternalName : コンパイル対象クラス
///  <br>OUT :%Status
///  <br>処理詳細:規約に則さない実装がされている場合、コンパイルエラーにする。
Method OnBeforeCompile(InternalName As %String, ByRef qstruct As %String) As %Status
{
    Set InternalName = $REPLACE(InternalName, ".CLS", "")
    Set clsDef = ##Class(%Dictionary.ClassDefinition).%OpenId(InternalName)

    Set SKIPuFLG = $$$NO
    Write !,"****************コンパイルチェック開始****************",!
    Write "TARGET : "_InternalName,!
    Set hasErr = 0
    
    #; クラス名チェック
    Set hasErr = hasErr + '##class(User.Chk.ClassNamingChecker).%New().IsCorrectDefine(clsDef)
    #; インデントチェック
    Set hasErr = hasErr + '##class(User.Chk.IndentChecker).%New().UseWrongIndent(clsDef)
    #; 変数の利用チェック
    Set hasErr = hasErr + '##class(User.Chk.UseValChecker).%New().UseVal(clsDef)
    #; 引数の利用チェック
    Set hasErr = hasErr + '##class(User.Chk.UseArgsChecker).%New().UseArgs(clsDef)
    

    Write "****************コンパイルチェック完了****************",!
    If (hasErr > 0) {
        Return $$$ERROR($$$GeneralError, "コンパイルエラーがあります。")
    } Else {
        Return $$$OK
    }
}

}

①クラスの命名チェッククラス - User.Chk.ClassNamingChecker Class User.Chk.ClassNamingChecker Extends %RegisteredObject {

///  処理概要 :クラス定義の命名規約違反チェック
///  <br>IN :clsDef : クラス定義
///  <br>OUT :%Boolean
///  <br>処理詳細:クラスの命名がコーディング規約に従っているかどうかをチェックする。
Method IsCorrectDefine(clsDef As %Dictionary.ClassDefinition) As %Boolean
{
    Write "*クラス名チェック",!

    Set ret = $$$YES
    If (clsDef '= "") {
        Set clsName = clsDef.Name
        Set ret = ..WriteStartWithStrErr(clsName)
    }

    Return ret
}

///  処理概要 :命名先頭不正のエラー表示
///  <br>IN :clsName クラス名/ keyword キーワード
///  <br>OUT :%Boolean
///  <br>処理詳細:クラス名の先頭がキーワードで開始していなければエラーを表示する。
Method WriteStartWithStrErr(clsName As %String) As %Boolean [ Private ]
{
    If ($FIND(clsName, ".XXXX") > 0) {
        #; OK
        Return $$$YES
    } Else {
        Write "E: クラス名はXXXXという単語で始まる必要があります。",!
        Return $$$NO
    }
}

}

クラス内で行っていること 引数として%Dictionary.ClassDefinition(クラス定義)を受け取り、クラス定義内のプロパティであるNameを使用することで クラス名を取得。取得したクラス名に対して、「.XXXX」を$FINDで検索することでクラスの先頭が「XXXX」であるかチェックを行います。

②インデントチェック - User.Chk.IndentChecker

Class User.Chk.IndentChecker Extends %RegisteredObject
{

///  処理概要 :インデント不正チェック
///  <br>IN :clsDef : クラス定義
///  <br>OUT :%Boolean
///  <br>処理詳細:インデントが4の倍数になっているかをチェックをする。
Method UseWrongIndent(clsDef As %Dictionary.ClassDefinition) As %Boolean
{
    Write "*インデント不正チェック",!
    Set isCorrect = $$$YES
    Set count = clsDef.Methods.Count()
    For i = 1: 1: count {
        Set cnt = 0
        Set method = clsDef.Methods.GetAt(i)
        Do method.Implementation.Rewind()

        While ('method.Implementation.AtEnd) {
            Set cnt = cnt + 1
            Set line = method.Implementation.ReadLine()
            If (line = "") {
                Continue
            }

            If ('$MATCH(line, "^( {4}){1,}[^ ].*")) {
                Set isCorrect = $$$NO
                Write "E: インデントが4の倍数になっていません。: "_method.Name_"+"_cnt_line,!
            }
        }
    }

    Return isCorrect
}

}

クラス内で行っていること 引数として%Dictionary.ClassDefinition(クラス定義)を受け取り、クラス定義内のプロパティであるMethods.Count()でメソッドの数を取得。 メソッドごとに1行ずつチェックを行います。チェックは正規表現を使用(^( {4}){1,}[^ ].*の部分)し、半角スペースが4の倍数になっているかチェックを行います。

③変数の利用チェック - User.Chk.UseValChecker

Class User.Chk.UseValChecker Extends %RegisteredObject
{

///  処理概要 :変数の利用チェック
///  <br>IN :clsDef : クラス定義
///  <br>OUT :%Boolean
///  <br>処理詳細:定義された変数が利用されているかをチェックをする。
Method UseVal(clsDef As %Dictionary.ClassDefinition) As %Boolean
{

    Set isCorrect = $$$YES
    Set count = clsDef.Methods.Count()
    For i = 1: 1: count {
        Set cnt = 0
        Set method = clsDef.Methods.GetAt(i)
        Do method.Implementation.Rewind()

        Set args = method.FormalSpec
        Set argList = {}
        For j = 1: 1: $LENGTH(args, ",") {
            Set arg = $REPLACE($REPLACE($REPLACE($PIECE($PIECE(args, ",", j), ":", 1), "&", ""), "*", ""), "...", "")
            If (arg = "") {
                Continue
            }
            Do argList.%Set(arg, "")
        }

        Set valList = {}
        While ('method.Implementation.AtEnd) {
            Set cnt = cnt + 1
            Set line = method.Implementation.ReadLine()
            If (line = "") {
                Continue
            }
            If (..HasComment(line)) {
                Continue
            }

            If ($FIND(line, "Set ") > 0) {
                Set valNm = $PIECE($REPLACE($PIECE($PIECE(line, "Set ", 2), "="), " ", ""), "(")
                #; オブジェクトへの参照は対象外。
                If (($FIND(valNm, ".") = 0) && ($FIND(valNm, "$") = 0)) {
                    #; 変数の定義があればObjectに登録。
                    If (('valList.%IsDefined(valNm)) && 'argList.%IsDefined(valNm)) {
                        Do valList.%Set(valNm, $$$NO)
                    }
                }
            }

            Set iter = valList.%GetIterator()
            While iter.%GetNext(.key, .value) {
                If ($FIND($REPLACE(line, "Set "_key_" ", ""), key) > 0) {
                    Do valList.%Set(key, $$$YES)
                }
            }
        }
        Set iter = valList.%GetIterator()
        While iter.%GetNext(.key, .value) {
            If ('value) {
                Write "E: "_method.Name_"() にて変数"_key_"は定義されていますが、利用されていない可能性があります。",!
                Set isCorrect = $$$NO
            }
        }
    }
    Return isCorrect
}

Method HasComment(line As %String) As %Boolean [ Private ]
{
    Return ($MATCH(line, "^( )*#;.*") > 0) || ($MATCH(line, "^( )*//.*") > 0)
}

}

クラス内で行っていること ②で行ったようにメソッド単位でチェックを行います。method.FormalSpec でメソッドの引数のリストを含む文字列を取得します。 上記で取得した文字列から、引数のみを抽出して引数リストを作ります。ここまで来たら、メソッドを1行ずつチェックしていきます。 HasCommentメソッドでコメントの場合は読み飛ばすようにしています。まず、「Set」の使用をチェックします。(If ($FIND(line, "Set ") > 0) {) 使用されている場合でもオブジェクトへの参照は対象外とするため、「.」や「$」が使用されている場合は読み飛ばします。(If (($FIND(valNm, ".") = 0) && ($FIND(valNm, "$") = 0)) {) 「.」や「$」が使用されていないかつ、引数のリストに存在しない場合は後のチェックのためにリストに追加します。(value側は$$$NOで登録しておきます) チェックリストを順番にリストのキー項目が定義箇所以外で使用されているかチェックしていきます。(L50~L54) 使用されている場合、該当キー項目のvalueを$$$YESに更新しておきます。 チェック処理としては上記で完了です。あとはvalueが$$$NOの項目を洗い出して、チェック完了となります。

④引数の利用チェック - User.Chk.UseArgsChecker

Class User.Chk.UseArgsChecker Extends %RegisteredObject
{

///  処理概要 :引数の利用チェック
///  <br>IN :clsDef : クラス定義
///  <br>OUT :%Boolean
///  <br>処理詳細:引数が利用されているかをチェックする。
Method UseArgs(clsDef As %Dictionary.ClassDefinition) As %Boolean
{
    Write "*引数の利用チェック",!
    Set ngKeyword = $LISTBUILD(")", """", "}")

    Set isCorrect = $$$YES
    Set count = clsDef.Methods.Count()
    For i = 1: 1: count {
        Set method = clsDef.Methods.GetAt(i)
        Set args = method.FormalSpec

        Do method.Implementation.Rewind()
        Set str = method.Implementation.Read()
        For j = 1: 1: $LENGTH(args, ",") {
            Set arg = $REPLACE($REPLACE($REPLACE($PIECE($PIECE(args, ",", j), ":", 1), "&", ""), "*", ""), "...", "")
            If (arg = "") {
                Continue
            }

            Set isIgnore = $$$NO
            Set ptr = 0
            While $LISTNEXT(ngKeyword, ptr, value) {
                #; NGリストの内容が含まれていると、切り出し対象外。
                If ($FIND(arg, value) > 0) {
                    Set isIgnore = $$$YES
                    Quit
                }
            }
            If (isIgnore) {
                Continue
            }

            If ($FIND(str, arg) = 0) {
                Write "E: 引数が利用されていません。: "_method.Name_"/"_arg,!
                Set isCorrect = $$$NO
            }
        }
    }

    Return isCorrect
}

}

クラス内で行っていること まず、コメントなどを引っ掛けないためにチェックしない文字を定義します。(L10) ③と同様にメソッド単位でチェックをするようにします。(L13~) メソッドの引数を取得します。(L16) メソッドの最初の行からチェックするようにポインタをストリームの先頭にしてメソッドの読込を行います。(L18、L19) 引数の数分チェックをまわしていきます。(L20) 引数の中にチェックしない文字が入っているかチェックします。(L28~L34) チェックしない文字が入っていない場合は、読み込んだメソッドの中で引数が使用されているかチェックを行います。(L39~L42)

3.ソースコントロールへの設定 管理ポータルにて、[システム管理]⇒[構成]⇒[追加の設定]⇒[ソースコントロール] を開くと ソースコントロールの設定画面となります。 imageimage

ソースコントロールクラス名の一覧には「%Studio.SourceControl.Base」クラスを継承したクラスが表示されます。 ソースコントロールを行いたいネームスペースを選択し、使用したいソースコントロールクラスを選択⇒保存します。 今回はUSERのネームスペースにチェック用クラス用意していますが、%SYSにソースコントロールクラスを作成することで全てのネームスペースに対して使用することができます。

4.実際の動作 今回テスト用に用意したクラスが以下のクラスです。

Class User.Test.NewClass1 Extends %RegisteredObject
{

///  処理概要 :テストメソッド
///  <br>IN :Str1 : テスト用文字列1
///  <br>IN :Str2 : テスト用文字列2
///  <br>OUT :%Boolean
Method TestMethod(Str1 As %String, Str2 As %String) As %Boolean
{
   Set test1 = Str1
    Set test2 = "TEST"
    
    Set ^TESTG(test1,"abc") = "hugehuge"
    
    Return $$$OK
}

}

クラス名が「XXXX」始まりでないこと。 - クラスの命名チェック インデントが4の倍数個の半角スペースになっていないこと。(L10) - インデントチェック 定義した変数test2が使用されていないこと。 - 変数の使用チェック TestMethodの引数として用意したStr2が使用されていないこと。 - 引数の使用チェック

実際にコンパイルした結果がこちらです。 image

すべてチェックに引っかかっており、コンパイルもされないようになっています。 では、チェッククラスに指摘された部分を修正したものをコンパイルしてみます。

Class User.Test.XXXXNewClass1 Extends %RegisteredObject
{

///  処理概要 :テストメソッド
///  <br>IN :Str1 : テスト用文字列1
///  <br>IN :Str2 : テスト用文字列2
///  <br>OUT :%Boolean
Method TestMethod(Str1 As %String, Str2 As %String) As %Boolean
{
    Set test1 = Str1
    Set test2 = "TEST"
    Set ^TESTG(test1,test2) = Str2
    Return $$$OK
}

}

image

見事にコンパイルが成功しました。

5.感想 今回参考例として4つのチェックを行いましたが、工夫や組み込み方次第では色々なチェックを組み込めると感じました。 Ex.) 変数がキャメルケースになっているか、利用してほしくないプロパティ等が使用されているか etc… また、他のライブラリでチェックツールは色々とあるかと思いますが、今回はIRISの中だけで完結させており、 チェックだけでなくエラーが出なかった時はコンパイルまで通るところがやはり良い部分に感じました。 今回使用したクラスはGithubにアップしておりますので、興味のある方はご確認いただければと思います。 追記)インデントチェッククラスをEmbedded Pythonで記載してみました。(Githubにもアップしております)

Class User.Chk.IndentCheckerP Extends %RegisteredObject
{

///  処理概要   :インデント不正チェック
///  <br>IN     :clsDef : クラス定義
///  <br>OUT    :%Boolean
///  <br>処理詳細:インデントが4の倍数になっているかをチェックをする。
ClassMethod UseWrongIndentP(clsDef As %Dictionary.ClassDefinition) As %Boolean [ Language = python ]
{
	import iris
	import re
	
	print("*インデント不正チェック\n")
	
	isCorrect = 1
	count = clsDef.Methods.Count()
	for i in range(count):
	    cnt = 0
	    method = clsDef.Methods.GetAt(i + 1)
	    while not method.Implementation.AtEnd:
	        cnt += 1
	        line = method.Implementation.ReadLine()
	        if line == '':
	            continue
	        if len(re.compile("^( {4}){1,}[^ ].*").findall(line)) == 0:
	            isCorrect = 0
	            print("E: インデントが4の倍数になっていません。: " + method.Name + str(cnt) + str(line) + "\n") 
	return isCorrect
}

}

以上になります。ご一読いただき、ありがとうございました。

0
0 165
記事 So Ochi · 10月 13, 2024 10m read

はじめに

生成AIを活用したアプリケーション開発は、Python、JavaScriptなどのメジャー言語による体験記事がよく見られます。一方、IRISのObjectScriptの開発に言及された記事は比較的少ないのが現状です。そこで、本記事では生成AIがObjectScriptの開発にどこまで活用できるのかを検証しました。

特にDevOpsのプロセスにおいて、生成AIは様々なシーンでの活用が期待できます。今回は開発工程に注目し、以下の観点から生成AIの有効性を調査しました。

  • 開発
    • コードの自動生成
    • 環境構築のアシスタント(テーブルの作成)
  • 検証
    • テストデータ生成のサポート

環境

本記事の検証は以下の環境で行いました。

開発環境

  • OS: macOS Sonoma
  • IRIS: 2023.4 (linux)

開発ツール IRISの開発にはStudioやVSCodeなどが利用可能ですが、今回は生成AIの活用に特化したエディタ「Cursor」を使用しました。

Cursorを選定した理由 Cursorは、生成AIによる支援機能に特化したコードエディタで、以下の特徴があります:

  • 生成AIの支援:コードの自動生成や提案、バグの検出、修正提案を行います。また、外部のドキュメントや複数のソースを指定し、生成内容に反映させる簡易なRAG機能も搭載されています。

  • VSCodeとの互換性:VSCodeをフォークして作られており、VSCodeユーザーはスムーズに移行できます。拡張機能もそのまま利用可能です。

IRISではv2024よりStudioは廃止となり、VSCodeが標準ツールとなります。そこで、VSCodeと互換性があり、生成AIとの親和性が高いCursorを選定しました。

選択した生成AIモデル GPT-4を使用しましたが、Claudeでも検証を行ったところ、どのモデルも大差ない結果となりました。 利用しやすいモデルを選んで試してみてください。

検証内容

今回は以下の内容を検証しました。

  • 簡単なプログラムの生成とターミナルでの実行
  • IRISのREST通信機能を使った商品情報検索APIの作成

サンプルプログラムの作成

まず、ユーザーに名前を入力させ、挨拶を返す簡単なルーチンを生成します。CursorでCommand+Lを押してチャットウィンドウを開き、以下のプロンプトを入力します。

あなたはObjectScriptの開発者です。
{仕様}をもとにコードを作成してください。
#仕様
- 以下の処理を実行するRoutineを作成する。
- macファイル名は"TEST.mac"とする。
1. ユーザーに名前の入力を促します。
2. 入力された名前が空であればエラーメッセージを表示します。
3. 名前が入力された場合、その名前を使って挨拶メッセージを表示します。

image

生成されたルーチンをTEST.macにコピーし、ターミナルで実行して動作を確認します。

image

REST APIの作成

簡易なプログラムの生成が確認できたので、次はより複雑なアプリケーションを作成してみます。

アプリケーションの仕様 IRISのREST通信機能を利用したAPIを作成します。ユーザーからのリクエストに基づき、サーバー上のデータベースから該当する商品情報をJSON形式で返します。

テーブルの作成 まずは、テーブルを作成しましょう。DDLの作成をAIに依頼します。

InterSystemsのIRISで{テーブル}を作成するためのDDLを出力してください
#テーブル
##名前
- Sample.Product
##列
- JanCd VARCHAR(13)
- ProductName VARCHAR(100)
- Price INT
## プライマリキー
- JanCd

image

生成されたDDLをターミナルから実行し、テーブルが正常に作成されたことを確認します。

image

テストデータの作成 テストデータの作成もAIにアシストしてもらいましょう。

image

テストデータが正常に登録されたことを確認します。

image

APIの作成 準備が整ったので、APIクラスを生成します。以下のプロンプトを使ってコードを作成します。

あなたはObjectScriptの開発者です。
{仕様}をもとに"Api.Product"クラスを作成してください。
#仕様
- REST通信でJSON形式で商品情報を返す。
- apiのURLは/products/:jancd
- %CSP.RESTクラスを継承する。
- Jsonデータの生成は%DynamicObjectクラスを利用する。
- レスポンスコードは、%responseを利用する。
1. jancdが指定されなかった場合、404を返す。指定された場合、以降の処理を続行する。 
2. "Sample.Product"テーブルをSQLで検索する。
- 取得項目: JanCd,ProductName,Price
- 検索条件: :jancdが指定された場合、テーブルをJanCdが一致するレコードを検索する。
3. 検索結果をJSON形式でREST通信結果として出力する。

image

生成されたコードを確認し、必要に応じて修正を加えます。クエリ結果の取得箇所で%Next()が実行されていなかったため、以下の修正を行いました。

Set tResult = tStatement.%Execute(jancd)
// -*-*-*-*- 処理を追加しました -*-*-*-*-
Do tResult.%Next()

If tResult.%SQLCODE = 100 {

curlコマンドを使用してAPIの動作を確認し、正常にJSONデータが返却されることを確認します。

image

最終的なソースは以下の通りです。今回は一部修正が必要でしたが、基本的な部分は生成AIが正しく対応していました。

  Class Api.Product Extends %CSP.REST
  {

  /// URLマッピング
  XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
  {
  <Routes>
      <Route Url="/products/:jancd" Method="GET" Call="GetProductInfo"/>
  </Routes>
  }

  /// 商品情報を取得するメソッド
  ClassMethod GetProductInfo(jancd As %String) As %Status
  {
      // jancdが指定されていない場合、404を返す
      If jancd = "" {
          Set %response.Status = 404
          Quit $$$OK
      }

      // "Sample.Product"テーブルをSQLで検索する
      Set tStatement = ##class(%SQL.Statement).%New()
      Set tSQL = "SELECT JanCd, ProductName, Price FROM Sample.Product WHERE JanCd = ?"
      Set tStatus = tStatement.%Prepare(tSQL)
      
      If $$$ISERR(tStatus) {
          Set %response.Status = 500
          Quit tStatus
      }
      
      Set tResult = tStatement.%Execute(jancd)
      Do tResult.%Next()
      
      // 検索結果がない場合、404を返す
      If tResult.%SQLCODE = 100 {
          Set %response.Status = 404
          Quit $$$OK
      }
      
      // 検索結果をJSON形式で出力する
      Set tProduct = ##class(%DynamicObject).%New()
      Do tProduct.%Set("JanCd", tResult.%Get("JanCd"))
      Do tProduct.%Set("ProductName", tResult.%Get("ProductName"))
      Do tProduct.%Set("Price", tResult.%Get("Price"))
      
      Write tProduct.%ToJSON(),!
      
      Quit $$$OK
  }

  }

既存コードの活用

次に、生成したAPIに商品名を部分一致で検索するメソッドを追加します。Cursorの外部ファイル参照機能を使い、先ほど生成したクラスを参考にしながら新しいメソッドを作成します。プロンプトは以下の通りです。

@Api.Product.cls 
以下の{仕様}で、"Api.Product"クラスにメソッドを追加してください。
#仕様
- GetProductInfo()の処理を参考にすること。
- apiのURLは/products/name/:productname
- Sample.ProductテーブルからAPIで指定された値が、ProductNameと部分一致するレコードを検索し、検索した結果をJson形式で返す。
- 検索結果は配列にして返す。

image

生成したコードは以下になります。(追加部分のみ抜粋)

  Class Api.Product Extends %CSP.REST
  {
      // ... 既存のコード ...

      /// URLマッピング
      XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
      {
      <Routes>
          // ... 既存のルート ...
          <Route Url="/products/name/:productname" Method="GET" Call="GetProductInfoByName"/>
      </Routes>
      }

      // ... 既存のコード ...

      /// 商品名で商品情報を取得するメソッド
      ClassMethod GetProductInfoByName(productname As %String) As %Status
      {
          // productnameが指定されていない場合、404を返す
          If productname = "" {
              Set %response.Status = 404
              Quit $$$OK
          }

          // "Sample.Product"テーブルをSQLで検索する
          Set tStatement = ##class(%SQL.Statement).%New()
          Set tSQL = "SELECT JanCd, ProductName, Price FROM Sample.Product WHERE ProductName LIKE ?"
          Set tStatus = tStatement.%Prepare(tSQL)
          
          If $$$ISERR(tStatus) {
              Set %response.Status = 500
              Quit tStatus
          }
          
          Set tResult = tStatement.%Execute("%" _ productname _ "%")
          
          // 検索結果がない場合、404を返す
          If tResult.%SQLCODE = 100 {
              Set %response.Status = 404
              Quit $$$OK
          }
          
          // 検索結果をJSON形式で出力する
          Set tProducts = ##class(%DynamicArray).%New()
          While tResult.%Next() {
              Set tProduct = ##class(%DynamicObject).%New()
              Do tProduct.%Set("JanCd", tResult.%Get("JanCd"))
              Do tProduct.%Set("ProductName", tResult.%Get("ProductName"))
              Do tProduct.%Set("Price", tResult.%Get("Price"))
              Do tProducts.%Push(tProduct)
          }
          
          Write tProducts.%ToJSON(),!
          
          Quit $$$OK
      }

      // ... 既存のコード ...
  }

生成されたコードを確認し、curlコマンドで動作を確認します。正常に実行されました。外部ファイル参照機能の利用により、自動生成の精度が向上していることがうかがえます。 image

開発上の課題と解決策

自動生成の精度向上 基本コマンドを用いたプログラムは高い精度を発揮しますが、クラスを利用した複雑な処理では精度が低下する印象を受けました。プロンプトの指示を工夫することで、精度を高めることができそうです。 また、Cursorの外部ドキュメント、ファイル参照機能には大きな可能性を感じました。この機能を使えば、既存のリソースや、AIが学習していないライブラリの活用が期待できます。

セキュリティとプライバシー Cursorはプライバシーモードを備えており、データをサーバーに保持しない設定が可能です。しかし、Cursorに限らず生成AIの業務利用には慎重な調査が必要です。

所感

今回の検証を通じて、生成AIのコード生成能力が向上していることを実感しました。特に、テストデータやDDLの生成は、開発の効率を大幅に向上させる可能性があります。アジャイル開発で迅速なモックアップの作成が求められる場面では、生成AIの効果的な活用が期待できそうです。一方で、既存システムの小規模な改修には、効果が限定的であるという印象を受けました。

この記事を作成したきっかけは、ObjectScriptの初学者向け演習問題を生成AIで作成した際、その問題と解答の品質が非常に高かったことです。業務での活用も十分可能であると思い、今回の検証を行いました。生成AIは、工夫次第でさらなる幅広い活用が期待できるツールだと感じています。

参考資料

0
0 249
記事 Akio Hashimoto · 10月 4, 2024 3m read

IRISはPythonの豊富なライブラリや既存のPythonプログラムをそのまま利用する事も、COS内でネイティブにコーディングする事も可能となりました。 しかし開発において、いくつかの問題点があります。

1. Pythonのバージョン

Pythonを使ったプロジェクトを構築していると、バージョンの問題にあたる時があります。 古いバージョンで開発していたところに、使いたいライブラリが対応していなかった等です。 しかし、IRISのEmbedded Pythonを利用する場合には、Pythonランタイムのバージョンに影響される為、プロジェクトで使用するバージョンは、プロジェクト単位はなく、IRISのバージョン単位で決まってしまいます。 また、現時点ではこのPythonランタイムをアップグレードする事はできません。

2. 外部Pythonファイルの利用

私は既に開発済みのPythonプログラムをそのまま活用したいと思い、外部Pythonファイルを読み込んで利用する方法を取りました。 IRISでは外部Pythonファイルを特定の場所に配置する事で、そのファイルをimportする事が出来ます。 デフォルトは{インストールパス}/lib/python です。 しかし、デフォルトではこの1ヶ所のディレクトリが対象となっていて、さらにサブフォルダは対象外となる為、プロジェクト単位などで管理する事も出来ません。

Python対象パスを指定

PythonPathの値を変更する事で、別のディレクトリを指定できます。 また、複数のディレクトリを指定する事も可能です。 Windowsであればカンマ区切り、linux等であればコロン区切りで複数指定が可能です。 但し、間にスペースを入れると認識されませんので注意して下さい。 また、複数ディレクトリに同じ名前のモジュールが存在すると、最初に読み込まれた物を利用するようです。(筆者実体験から) また、このPythonPathの値は、Pythonの対象ディレクトリを指定した場所だけに変更するのではなく、デフォルトのディレクトリに追加される事に注意して下さい。 PythonPathを書き換えてもデフォルトのディレクトリは読み込まれています。 もしデフォルトのディレクトリに同じ名前のPythonファイルがあると、そちらが先にimportされるようなので注意が必要です。

PythonPathの指定 image ここに記載されていないが、デフォルトのディレクトリも対象となている。

複数指定する場合は、スペースを入れない /opt/iris/python/common: /opt/iris/python/project --> コロンの後にスペースを入れると認識されない。

3. 修正が反映しない

IRISは外部Pythonファイルやライブラリを読み込むと、プロセスが閉じるまで再読み込みをしません。 ですので、外部Pythonファイルを修正しても即時反映しません。 この場合、プロセスを一度閉じて再実行する必要があります。 ターミナル実行時などであれば、対処法が思いつきますが、Webブラウザからの場合は、セッションが閉じられても再読み込みされません。 Webブラウザからのアクセスの場合は、ウェブゲートウェイを閉じる必要があります。それは結構な手間です。 そこで、即時反映に近い動きにする為には、importしたモジュールをリロードする方法があります。

importlib.reload({モジュール名})

これをCOSの中でモジュールをimportしている箇所に記載する事で、実行する毎にモジュールのリロードを行います。

import importlib
import module1
import module2

importlib.reload(module1)
importlib.reload(module2)

以上が、筆者が最近経験したEmbedded Pythonを利用する時に起こった問題点です。

0
0 416
記事 Saori Murata · 9月 30, 2024 19m read

開発者の皆さん、こんにちは! InterSystems IRIS(以下、IRIS)を使用したアプリケーション開発において、皆さんは環境設定をどうされていますか? 私は最近になって、「インストールマニフェスト」という機能があることを知りました。 これは、管理ポータルでポチポチしていた作業をコード化・自動化できる強力なツールです! 最初こそとっつきづらかったものの良いところがたくさんあるなと思ったので、簡単にではありますが皆さんにその良さと始め方をご紹介したいと思います。

なお、私が使用しているIRISバージョンは以下です。

2022.1

バージョンが異なる場合、違う書き方になっているもの等が存在する場合がありますので、 公式ドキュメント等を参照し適宜読み替えていただければと思います。

目次

  1. はじめに
  2. インストールマニフェストとは
  3. インストールマニフェストのメリット・デメリット
  4. インストールマニフェストの始め方と基本構造
    1. マニフェストの作成
    2. マニフェストの編集
    3. マニフェストの実行
  5. インストールマニフェストでできること
    1. 変数の設定
    2. ネームスペースとデータベースの設定
    3. データのインポートとマッピング
    4. セキュリティ設定
    5. InterOperability 機能の設定
  6. インストールマニフェスト以外で行う環境設定
    1. ObjectScriptによる実装
    2. Pythonによる実装
  7. まとめ

1. はじめに

IRISを使用するにあたって、管理ポータルでの環境設定は切っても切れない作業だと思います。 IRIS のインストールマニフェストを使用することで、ネームスペース、データベース、セキュリティ設定、InterOperabilityの有効化、 さらにはカスタムコードの実行まで、一連のプロセスを自動化することができます。

本記事では、実際のマニフェストファイルを例に挙げながら、IRIS の環境設定自動化の方法について解説します。

なお、本記事で解説しているサンプルコードの全文と、付随するフォルダ・ファイルについては、Githubにて公開しています。

2. インストールマニフェストとは

IRIS のインストールマニフェストとは、%Installerというツールのことを指します。 インストールマニフェスト定義を記述するだけで、 IRIS環境設定を変更するために必要なコードを自動生成することができます。 他人に共有する際は、定義したインストールマニフェストを配布するだけで済みます。

インストールマニフェストは XML 形式で記述されます。 主要な要素として <Manifest><Namespace><Configuration><Database> などがあります。

なお、公式ドキュメントは以下です。

インストール・マニフェストの作成および使用

3.インストールマニフェストのメリット・デメリット

私が使ってみて感じた、インストールマニフェストのメリット・デメリットについてお伝えします。 全ての場合でインストールマニフェストが優れているとは言えないと思いますので、下記を参考に使用したほうが良いかどうか判断してもらえたらと思います。

  • メリット

    • IRIS環境構築(管理ポータルで手動で実行していた作業)の自動化ができる
    • 環境構築内容をコードとして管理できる
    • 共通の環境を誰でも簡単に、素早く作れるようになる
    • 事前に内容を定義しておけるので、管理ポータルで操作してうっかり設定ミスや設定忘れをしてしまうといったことがなくなる
  • デメリット

    • 環境構築経験が豊富でない人にとっては、公式ドキュメントを読みながらでもコードが示す内容の把握が難解なところがある
    • マニフェストの記法を理解した人でないと、コードのメンテナンスを実施できない
    • 定義の作成、定義の配布、実行方法の共有など、事前準備に手間がかかるため、少人数の環境が対象だったり、設定項目が少なかったりすると手間のほうが大きくなる可能性がある

4. インストールマニフェストの始め方と基本構造

4-1. マニフェストの作成

インストールマニフェストは、簡単に作成することができます。 例えばあなたがスタジオを使っている場合、下記の手順でテンプレートを作成できます。

ファイル > 新規作成 > 一般 > %Installer マニフェスト > OK

こうして作成されるマニフェストは、以下のようになっています。

Include %occInclude  

/// %Installer Manifest MyApp.MyInstaller
Class MyApp.MyInstaller
{  
  
/// マニフェスト定義.  
XData MyManifest [ XMLNamespace = INSTALLER ]  
{  
<Manifest>
	<Namespace>
		<Configuration>
			<Database>
				<!-- Your Manifest code here -->
			</Database>
		</Configuration>
	</Namespace>
</Manifest>
}  
  
/// これは XGL により生成されたメソッド・ジェネレーターです。.  
ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ]  
{  
    #; XGL ドキュメントでこのメソッドのコードを生成する.  
    Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "MyManifest")  
}  
  
}

4-2. マニフェストの編集

なにやら見覚えのないコードがたくさん生成されますが、安心してください。 そのうち、私たちが編集すればよいのは基本的に下記の部分のみです。

<Manifest>
	<Namespace>
		<Configuration>
			<Database>
				<!-- Your Manifest code here -->
			</Database>
		</Configuration>
	</Namespace>
</Manifest>

■マニフェストの基本構造

詳細については後ほど解説しますが、ここでは基本的な構造について紹介していきます。

  • <Manifest>すべてのタグのルートタグである必要がある。 他のすべてのタグを含む。
  • <Namespace>ネームスペースを定義する。 【親タグ:<Manifest>
  • <Configuration><Namespace>内で構成タグの親タグとして記述する必要がある。【親タグ:<Namespace>
  • <Database>データベースを定義する。 【親タグ:<Configuration>

ここで覚えるべきは、<Manifest>タグは唯一無二ですべてのルートタグとなること、 その中身となるそれぞれのタグにも親子関係があるためそれを守らなければならないこと、の2点です。

これら以外の記述は、インストールマニフェストの作成や実行に必要なコードです。 詳細の説明については、下記のページにあるので任せたいと思います。

%InstallerでInterSystems Cachéにアプリケーションをデプロイする

4-3. マニフェストの実行

このマニフェストを実行したいときは、ターミナルで以下のコマンドを実行してください。 ※マニフェストを実行する時は、%SYSネームスペースで実行することを推奨します。(それ以外のネームスペースでも動作はします)

USER>zn "%SYS"
%SYS>do ##class(MyApp.MyInstaller).setup()

そうすると、マニフェストが環境設定のためのコードを生成し、そのコードが実際にIRISの環境設定を変更していきます。

5. インストールマニフェストでできること

それではさっそく、インストールマニフェストで実際にできることについてみていきましょう。 私が触ったことのある機能を中心に紹介していますが、前述の公式ドキュメントにはそれ以外の設定もできるXMLタグが多数紹介されていますので、参照してみてください。

5-1. 変数の設定

マニフェストでは、変数を設定することができます。 変数設定ができるタグには2種類あります。

  • <Default>:変数値がまだ設定されていない場合のみ、変数値を設定します。(すでに値が設定されている場合、無効になる)【親タグ:<Manifest>
  • <Var>:マニフェストで使用できる変数を定義および設定します。【親タグ:<Manifest>
<Var Name="var1" Value="aaa" />
// 事前に変数 var1 が設定されているので、var1 は aaa のまま
<Default Name="var1" Value="bbb" />
// 事前に変数 var2 は設定されていないので、var2 は ccc になる
<Default Name="var2" Value="ccc" />

5-2. ネームスペースとデータベースの設定

マニフェストを使用して、ネームスペースとそれに関連するデータベースを簡単に作成できます。 関連するタグは3種類です。

  • <Namespace>:ネームスペースを定義する。【親タグ:<Manifest>
    • Name:ネームスペースの名前
    • Create:新しいネームスペースを作成するかどうか(yes/no/overwrite) ※デフォルト:yes
    • Code:コード用データベースの指定
    • Data:データ用データベースの指定
    • Ensemble:InterOperabilityを使用するネームスペースかどうかの指定
  • <Configuration><Namespace> 内で構成タグの親タグとして記述する必要がある。【親タグ:<Namespace>
  • <Database>:データベースを定義する。【親タグ:<Configuration>
    • Name:データベース名
    • Dir:データベース・ディレクトリ
    • Create:新しいデータベースを作成するかどうか
    • InitialSize:データベースの初期サイズ(MB)
    • Resource:データベースへのアクセスを制御するリソース
    • PublicPermissions:リソースに割り当てられる許可の値(新規作成リソースのみ適用)(R/W/RW)
<Default Name="Namespace" Value="TESTNMSP"/>  
<Default Name="DATADB" Value="${Namespace}-GBL"/>  
<Default Name="CODEDB" Value="${Namespace}-RTN"/>
<Default Name="SetupDir" Value="C:\work\git"/>

<!-- ネームスペース作成 -->  
<Namespace Name="${Namespace}" Code="${CODEDB}" Data="${DATADB}" Create="yes" Ensemble="0">  
	<!-- DB作成 -->  
	<Configuration>  
		<Database Name="${DATADB}" Dir="C:\IRISDB\${Namespace}\GBL" Create="yes" InitialSize="100" Resource="%DB_${DATADB}" PublicPermissions="R"/>  
		<Database Name="${CODEDB}" Dir="C:\IRISDB\${Namespace}\RTN" Create="yes" InitialSize="10" Resource="%DB_${CODEDB}" PublicPermissions="R"/>  
	</Configuration>  
</Namespace>

■結果(管理ポータル画面)

(ネームスペース)

(データベース)

5-3. データのインポートとマッピング

マニフェストを使用して、特定のネームスペースに既存のデータやコードをインポートすることもできます。 関連するタグは1種類です。(既出除く)

  • <Import>:ファイルをインポートする。(%SYSTEM.OBJ.ImportDir または %SYSTEM.OBJ.Load を使用する)【親タグ:<Namespace>
    • File:インポートするファイルまたはフォルダ
    • Flags:コンパイル・フラグ(参考:フラグおよび修飾子
    • Recurse:再帰的にインポートするかどうかを指定 ※デフォルト:0
    • IgnoreErrors:エラー時に続行するかどうかを指定 ※デフォルト:0
<Default Name="Namespace" Value="TESTNMSP"/>  
<Default Name="DATADB" Value="${Namespace}-GBL"/>  
<Default Name="CODEDB" Value="${Namespace}-RTN"/>
<Default Name="SetupDir" Value="C:\work\git"/>

<Namespace Name="${Namespace}" Code="${CODEDB}" Data="${DATADB}" Create="yes" Ensemble="0">  
	<!-- グローバル、クラス、ルーチンインポート -->  
	<Import File="${SetupDir}\Test1" Flags="ck" Recurse="1" IgnoreErrors="1"/>  
	<Import File="${SetupDir}\Test2" Flags="ck" Recurse="1" IgnoreErrors="1"/>  
</Namespace>

■結果(管理ポータル画面)

マニフェストを使用して、グローバルやクラスをマッピングすることもできます。 関連するタグは3種類です。(既出除く)

  • <GlobalMapping>:グローバルを現在のネームスペースにマッピングする。【親タグ:<Configuration>
    • Global:グローバル名
    • From:グローバルのソース・ネームスペース
  • <ClassMapping>:パッケージを現在のネームスペースにマッピングする。【親タグ:<Configuration>
    • Package:マップするパッケージ
    • From:マッピングに使用するソース・データベース
  • <RoutineMapping>:ルーチンを現在のネームスペースにマッピングする。【親タグ:<Configuration>
    • Name :ルーチン
    • Type :ルーチン・タイプ
    • From:ルーチンのソース・データベース
<Default Name="Namespace" Value="TESTNMSP"/>
<Default Name="Namespace2" Value="${Namespace}2"/>  
<Default Name="DATADB2" Value="${Namespace2}-GBL"/>  
<Default Name="CODEDB2" Value="${Namespace2}-RTN"/>

<Namespace Name="${Namespace2}" Code="${CODEDB2}" Data="${DATADB2}" Create="yes" Ensemble="0">  
	<Configuration>
		<!-- DB作成 -->  
		<Database Name="${DATADB2}" Dir="C:\IRISDB\${Namespace2}\GBL" Create="yes" InitialSize="100" Resource="%DB_${DATADB2}" PublicPermissions="R"/>  
		<Database Name="${CODEDB2}" Dir="C:\IRISDB\${Namespace2}\RTN" Create="yes" InitialSize="10" Resource="%DB_${CODEDB2}" PublicPermissions="R"/>  
		<!-- グローバル、クラス、ルーチンマッピング設定 -->  
		<GlobalMapping Global="test2" From="${DATADB}"/>  
		<ClassMapping Package="Test2" From="${CODEDB}"/>  
	</Configuration>  
</Namespace>

■結果(管理ポータル画面)

5-4. セキュリティ設定

マニフェストを使用して、ロールやユーザアカウントを複数作成することができます。 関連するタグは2種類です。

  • <Role>:ロールを定義する。【親タグ:<Manifest>
    • Name:ロール名
    • Description:ロールの説明(カンマ不可)
    • Resources:ロールで保持されているリソースと特権。
    • RolesGranted:付与されるロール
  • <User>:ユーザを定義する。【親タグ:<Manifest>
    • Username:ユーザ名
    • PasswordVar:ユーザ・パスワードが含まれる変数の名前(変数名を渡す必要があることに注意)
    • Fullname:ユーザのフルネーム
    • Roles:ユーザを割り当てるロールのリスト
    • Namespace:ユーザの実行開始ネームスペース
    • Enabled:ユーザが有効かどうか
    • Comment:オプションコメント
    • ChangePassword:次回ログイン時にユーザにパスワードの変更を要求するかどうか
    • ExpirationDate:それ以降のユーザ・ログインが無効になる日付
<Default Name="TestUserPw" Value="12345"/>

	<!-- ロール作成・変更 -->  
<Role  
	Name="TestOperator"  
	Description="テスト運用者ロール"  
	Resources="%DB_TESTNMSP-GBL:RW,%DB_TESTNMSP-RTN:RW"  
	RolesGranted="%Developer"/>  
<Role  
	Name="TestAdministrator"  
	Description="テスト管理者ロール"  
	RolesGranted="%All"/>  
 
<!-- ユーザ作成・変更 -->  
<User  
	Username="TestUser1"  
	PasswordVar="TestUserPw"  
	Fullname="テストユーザ1"  
	Roles="TestOperator"  
	Namespace="USER"  
	Enabled="1"  
	Comment="テストユーザ1"/>  
<User  
	Username="TestUser2"  
	PasswordVar="TestUserPw"  
	Fullname="テストユーザ2"  
	Roles="TestAdministrator"  
	Namespace="USER"  
	Enabled="1"  
	Comment="テストユーザ2"/> 

■結果(管理ポータル画面)

(ロール)

(ユーザ)

■クラスメソッドの実行(Invoke)

また、管理ポータルのセキュリティ設定をまるっと読み込むこともできます。 これにより、管理ポータルやターミナル等のログインの有効化や、詳細のセキュリティ設定までを一括で行うことができます。 ロールやユーザアカウントについても、この読み込みにより一括で作成することができます。 関連するタグは2種類です。(既出除く)

  • <Invoke>:クラス・メソッドを呼び出して、実行結果を変数の値として返す。【親タグ:<Namespace>
    • Class:クラス名
    • Method:メソッド名
    • CheckStatus:返されたステータスをチェックするかどうか
    • Return:結果の書き込み先の変数の名前
  • <Arg><Invoke> または <Error> から呼び出されるメソッドに引数を渡す。【親タグ:<Invoke>, <Error>
    • Value:引数の値
<Default Name="SetupDir" Value="C:\work\git"/>

<Namespace Name="%SYS" Create="overwrite">  
	<!-- セキュリティ設定のインポート -->  
	<Invoke Class="Security.System" Method="ImportAll" CheckStatus="false">  
		<Arg Value="${SetupDir}\SecurityExport.xml"/>  
	</Invoke>  
</Namespace>

これらのタグは、セキュリティ設定のインポート以外にも様々な用途に使用することができます。 例えば、タスクスケジュール全体のインポートをセキュリティと同じように行ったり、自作のクラスの処理を実行したり、既存のシステムクラスの処理を実行したりなどです。

※管理ポータルのログインの有効化設定については、2024.3以降のバージョンであればマニフェストのタグにて変更することができます。 (ターミナルのログイン有効化については、現在は<Invoke>を用いる方法か、後述の別途マニフェスト以外のコードを書く方法で実現するしかありません) 具体的には、下記のタグで実現できます。

  • <CSPApplication>:クラス内で定義されている 1 つ以上の Web アプリケーションを定義する。【親タグ:<Namespace>
    • AuthenticationMethods:有効な認証方法(例:32=password、64=unauthenticated)
    • CSPEnabled:CSP が有効かどうか ※デフォルト:1
    • DefaultTimeout:セッション・タイムアウト
    • Description:説明
    • Directory:CSP ファイルへのパス
    • Url:Webアプリケーションの名前

※セキュリティ設定のインポートの事前準備として、管理ポータルのセキュリティ設定(上述の「SecurityExport.xml」にあたるもの)をXMLとしてエクスポートしておく必要があります。 エクスポートは、次のように実施します。 ターミナルで^SECURITY ユーティリティを起動し、12) System parameter setup > 5) Export All Security settings を選択します。 そうすると、C:\InterSystems\[IRISインスタンス名]\mgr\SecurityExport.xml ができているはずです。 (IRISを入れている場所によっては出力場所は異なります)

★4.セキュリティ情報(ユーザ・サービスなど)のインポートInterSystems 製品の設定内容をインポート/エクスポートする方法 > セキュリティについて

%SYS>Do ^SECURITY
:
Option? 12       // System parameter setup
:
Option? 5        // Export All Security settings

Export ALL security records? Yes => Yes

Export to file name SecurityExport.xml =>
Parameters? "WNS" =>
Confirm export of selected security records to SecurityExport.xml? No => Yes

■結果(管理ポータル画面)

(デフォルトでは管理ポータルのログイン時にパスワード認証はないが、それをマニフェストで有効化した例)

5-5. InterOperability 機能の設定

InterOperability機能を使用する場合、専用のネームスペースを作成することができます。 また、プロダクションを自動的に設定することもできます。 関連するタグは2種類です。<Namespace>も改めて紹介します。

  • <Namespace>:ネームスペースを定義する。【親タグ:<Manifest>
    • Name:ネームスペースの名前
    • Create:新しいネームスペースを作成するかどうか(yes/no/overwrite) ※デフォルト:yes
    • Code:コード用データベースの指定
    • Data:データ用データベースの指定
    • Ensemble:InterOperabilityを使用するネームスペースかどうかの指定
  • <Production>:プロダクションを定義する。【親タグ:<Namespace>
    • Name:プロダクション名
    • AutoStart:プロダクションを自動的に起動するかどうか ※デフォルト:0
<Default Name="Namespace3" Value="ENSNMSP"/>
<Default Name="DATADB3" Value="${Namespace3}-GBL"/>  
<Default Name="CODEDB3" Value="${Namespace3}-RTN"/>  
<Default Name="SetupDir" Value="C:\work\git"/>

<Namespace  Name="${Namespace3}"  Code="${CODEDB3}"  Data="${DATADB3}"  Create="yes"  Ensemble="1">
	<!-- Database作成などの設定は省略 -->
	<!-- グローバル、クラス、ルーチンインポート -->  
	<Import File="C:\work\git\Test3" Flags="ck" Recurse="1" IgnoreErrors="1"/>
	<!-- プロダクションの作成 -->
	<Production  Name="Test3.job.Main"  AutoStart="1"  />
</Namespace>

■結果(管理ポータル画面)

6. インストールマニフェスト以外で行う環境設定

マニフェストを作成していると、管理ポータルでは設定できるけどマニフェストではどうやるのだろう?という設定に度々出会います。 公式ドキュメントを見るなどしてマニフェストでの実現方法がわかる場合もありますが、 中にはマニフェストでは実現方法がないもの、後続のバージョンでは修正されたが今使っているバージョンではバグが残っており実現できないもの、 等がある場合があります。

その場合、あきらめて管理ポータルで設定するというのも手ですが、 別途コード化してマニフェストの処理と一緒に実施してしまうのもありです。

実際に、いくつかの設定をマニフェスト以外のコードで実現し、それをマニフェストと一緒に実行するコードの簡単な例をご紹介します。

6-1. ObjectScriptによる実装

下記のコードでは、マニフェストの生成・実行処理であるsetupメソッド(前述のスタジオでの新規作成にて自動作成されるメソッド)を、 自作のsetupExecuteというメソッドでラップしています。 その上で、ロケールの変更や不要タスクの一時停止といった処理をコードで記述し、実行します。

/// <h2>マニフェスト生成・実行処理</h2>  
/// <p><pre>SAMPLES>  
/// Do ##class(MyApp.MyInstaller).setup()  
/// </p></pre>  
ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ]  
{  
	#; XGL ドキュメントでこのメソッドのコードを生成する.  
	Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "MyManifest")  
}  
  
/// <h2>セットアップ開始処理</h2>  
/// <p>return %Status</p>  
/// <p><pre>SAMPLES>  
/// Do ##class(MyApp.MyInstaller).setupExecute()  
/// </p></pre>  
ClassMethod setupExecute(ByRef pVars) As %Status  
{  
	Set tSC = 0  
	New $NAMESPACE  
	Set $NAMESPACE = "%SYS"  
	#; すでにネームスペースがあるときはManifestの処理はスキップ  
	If ('##class(%SYS.Namespace).Exists("TESTNMSP")) {  
		Set tSC = ..setup(.pVars)  
	}  
	  
	#; 日本語ロケールへ変更  
	Do ##class(Config.NLS.Locales).Install("jpuw")  
	#; 不要なタスクを停止  
	Do ..SuspendTask()  
	  
	Return tSC  
}

/// <h2>タスク停止</h2>  
/// <p>不要なタスクスケジュールを停止する。</p>  
/// <p><pre>SAMPLES>  
/// Do ##class(MyApp.MyInstaller).SuspendTask()  
/// </p></pre>  
ClassMethod SuspendTask()  
{  
	Set targetId = -1  
	Set query = 0  
	Set query($INCREMENT(query)) = "SELECT %ID,Name FROM %SYS.Task"  
	Set tStatement = ##class(%SQL.Statement).%New()  
	Do tStatement.%Prepare(.query)  
	Set result = tStatement.%Execute()  
	While (result.%Next()) {  
		If (result.%GetData(2) = "機能トラッカー") {  
			Set targetId = result.%GetData(1)  
			Quit  
		}  
	}  
	If (targetId '= -1) {  
		#; 機能トラッカーを一時停止  
		Do ##class("%SYS.TaskSuper").Suspend(targetId)  
	}  
}

これを実行する時は、setupメソッドではなくsetupExecuteメソッドを、ターミナルから実行します。 %SYSネームスペースから実行してください。

USER>ZN "%SYS"
%SYS>Do ##class(MyApp.MyInstaller).setupExecute()

■結果(管理ポータル画面)

(機能トラッカーを一時停止した結果)

6-2. Pythonによる実装

本題からは逸れてしまいますが、「InterSystems Embedded Python」について私は今まで触ったことがなかったため、この機会にチャレンジしてみました。 簡単にですが、その結果と所感について述べたいと思います。

6-1の内容を、Embedded Pythonを用いて書き換えたコードは以下です。 ※setupメソッドについては「objectgeneratorメソッド」という特別なメソッドのため、ObjectScriptのみでしか動作しません。そのため、Pythonへの書き換えはできないようでした。

/// <h2>マニフェスト生成・実行処理</h2>
/// <p><pre>SAMPLES>
/// Do ##class(MyApp.MyInstaller).setup()
/// </p></pre>
ClassMethod setup(ByRef pVars, pLogLevel As %Integer = 3, pInstaller As %Installer.Installer, pLogger As %Installer.AbstractLogger) As %Status [ CodeMode = objectgenerator, Internal ]
{
     #; XGL ドキュメントでこのメソッドのコードを生成する.
     Quit ##class(%Installer.Manifest).%Generate(%compiledclass, %code, "MyManifest")
}

/// <h2>セットアップ開始処理</h2>
/// <p>return %Status</p>
/// <p><pre>SAMPLES>
/// Do ##class(MyApp.MyInstaller).setupExecute()
/// </p></pre>
ClassMethod setupExecute(pVars As %SYS.Python = "") As %Status [ Language = python ]
{
	import iris
	tSC = 0
	# すでにネームスペースがあるときはManifestの処理はスキップ
	if not iris.cls('%SYS.Namespace').Exists('TESTNMSP') == 1:
		tSC = iris.cls(__name__).setup(pVars)

	# 日本語ロケールへ変更
	iris.cls('Config.NLS.Locales').Install('jpuw')
	# 不要なタスクを停止
	iris.cls(__name__).SuspendTask()

	return tSC
}

/// <h2>タスク停止</h2>
/// <p>不要なタスクスケジュールを停止する。</p>
/// <p><pre>SAMPLES>
/// Do ##class(MyApp.MyInstaller).SuspendTask()
/// </p></pre>
ClassMethod SuspendTask() [ Language = python ]
{
	import iris
	
	targetId = -1
	df = iris.sql.exec('SELECT %ID,Name FROM %SYS.Task').dataframe()
	for i in range(len(df)):
		if df.iloc[i, 1] == '機能トラッカー':
			targetId = df.iloc[i, 0]
			break

	if not targetId == -1:
    	# 機能トラッカーを一時停止
		iris.cls('%SYS.TaskSuper').Suspend(int(targetId))
}

※SuspendTaskメソッドの実行に当たっては、事前にpandasライブラリのインストールが必要です。 未インストールの場合、下記のコマンドを実行してインストールを実行してください。 (IRISを入れている場所によっては対象のパスは異なります)

> cd C:\InterSystems\[IRISインスタンス名]\bin
> irispip install --target ..\mgr\python pandas

Embededd Pythonを少しだけ使用してみた所感としては、 純粋にPythonを書くところは知っている記法をそのまま書けるので苦なく書けましたが、 IRISとの連携部分(IRISのクラスを利用するなどIRIS独自の機能を利用したいとき)は都度書き方を調べる必要があったので少し大変でした。 一度書き方を覚えてしまえばより多くのコードを書く時でも問題なさそうですが、慣れが必要だと思います。 ObjectScriptの記法に慣れていると、ObjectScriptで当たり前にできることがPythonでは実装が難しい、直感的に書けない場合もあるようなので、注意が必要です。

しかし、それを踏まえてもコードをPythonで書けるのは良いと思いました! Pythonの記法のメリットとしてObjectScriptよりもシンプルに記載できる箇所も多いですし、 前述のPythonでは実装が難しい部分についても、バージョンがあがっていくことで機能は徐々に追加されていくと思いますので、これからに期待ができます。 なにより、ObjectScriptの経験がない人に対しても共通の言語を持てるというのはとても素晴らしいことだと思います。

これを実行する時は、ObjectScriptのときと同じで問題ありません。 %SYSネームスペースから実行してください。 ※そうでないと、「Config.NLS.Locales」の実行時にエラーとなります(%SYSにあるパッケージのため)

USER>ZN "%SYS"
%SYS>Do ##class(MyApp.MyInstaller).setupExecute()

7. まとめ

IRIS のインストールマニフェストを使用することで、環境設定の自動化が可能になり、共通の環境を素早く構築できます。 これにより、開発チームの生産性が向上し、人為的なミスも減らすことができそうです。

本記事で興味を持っていただいた方は、ぜひインストールマニフェストを使ってみてください! 以上、ここまでお読みいただきありがとうございました。

0
1 309
記事 Kosaku Ikeda · 9月 23, 2024 6m read

コミュニティの皆さんこんにちは。

突然ですが、皆さんはIRISの機能にある「ユニットテスト」は利用されているでしょうか。
筆者はまだ実装まで行えていませんが、各関数の品質保証を担保するため導入を検討している段階です。

現状、IRISのユニットテストには下記2点の対応すべき点があると考えています。

  1. テスト結果の可読性が低い(先日vscodeで拡張機能が出ていましたが、やはり見ずらいと感じました)
  2. ユニットテストを自動で実行する手段がない

特にテストが継続的に自動で実施されないと、ユニットテスト自体が次第に陳腐化し、実行されなくなり忘れ去られる恐れがあると考えます。
ただし、意味もなく定期的にテストを実行しても効果がありません。
そこで、Gitのpushのタイミングで行おうと考えました。

次にテスト環境です。
テスト環境の構築は、テスト自動化の観点からみるとCI/CDツール等を利用するのが一般的だと思います。
ただ今回は、テスト環境の構築を簡易にすませたいと考え、IRISの既存技術を組み合わせて構築しようと考えました。

そこで運用幅の広いInteroperabilityとユニットテストを組み合わせて、テストの自動化が可能か考察していきたいと思います。

【ユニットテスト全体概要】

【全体の流れ】

 ■ユーザの開発環境

  ①ユーザは改修したクラスをGitへpushする

 ■Git用のサーバ

0
0 210
記事 Yusuke Kojima · 9月 17, 2024 5m read

開発者の皆さん、こんにちは。

突然ですが、2024年6月25日に開発者向けセミナー「FHIR 新機能のご紹介~2024.1~」が開催されました。
ご視聴になられた方も多数いらっしゃると思います。
まだご視聴になられていない方は是非一度、ご覧になってみてください。
YouTubeリンク

さて、こちらのセミナーにおいてご紹介された、IRIS for Health 2024.1からの新機能「FHIR Object Model」を用いて、リポジトリタイプのInteroperability開発の具体的なサンプルを作成してみました。
自身の備忘のため、すぐ開発環境を構築できるよう、コンテナ環境かつGitHubの公開もしております。
利用方法は、GitHub内のREADMEを参照ください。
GitHubリンク

目次

  1. FHIR Object Modelとは?

  2. メリット・デメリットを深堀り

  3. GitHub公開ソースについて

  4. 所感

1. FHIR Object Modelとは?

0
0 193
お知らせ Mihoko Iijima · 9月 2, 2024

開発者の皆さん、こんにちは!

USコミュニティのコンテスト情報が更新されました。今回は、コミュニティメンバーの開発の手助けになるような便利ツールの作成がテーマです。

🏆 InterSystemsデベロッパーツールコンテスト 🏆

※ 日本のコミュニティの 第2回 InterSystems Japan 技術文書ライティングコンテスト 開催!とは異なるコンテストです。ご注意ください!

InterSystems IRIS を使用して、より迅速な開発、より質的なコードの貢献、ソリューションのテスト、デプロイ、サポート、または監視に役立つアプリケーションをご応募ください。

期間:2024年9月9日~29日

賞品総額: $14,000


0
0 80