クリアフィルター
記事
Mihoko Iijima · 2020年11月20日
これはInterSystems FAQ サイトの記事です。
現在ご覧いただいている開発者コミュニティの中では、初心者(beginner)タグ があり、下記セルフラーニング用資料/ビデオをご用意しています。ぜひご参照ください。
【はじめての InterSystems IRIS】セルフラーニングビデオ 索引
【はじめてのInterSystems IRIS】セルフラーニングビデオ:アクセス編:IRIS で作成する REST サーバの仕組み
Python から IRIS にアクセスしてみよう!
Python の NativeAPI に挑戦
Python から PyODBC を使って IRIS に接続してみよう
【はじめてのInterSystems IRIS】Interoperability(相互運用性)を使ってみよう!
【はじめてのInterSystems IRIS】Embedded Python セルフラーニングビデオシリーズ公開!
ObjectScript クックブック
「ObjectScript」の基本の使い方から、困ったときのヒント集、エラーの読み方などを解説しています。
この他、Developer Hubに特別な準備なしに開始できるチュートリアルを4種類ご用意しています。
チュートリアルで試せる内容については「InterSystems Developer Hub:クリック1回で開始できるチュートリアル(4種)のご紹介」をご覧ください。
また 5分で試せる QuickStarts では、サンプルコードの実行方法などを解説しています。ビデオは日本語字幕付きに切り替えができます。
日本語字幕への切り替えは以下のように行います。
IRIS または IRIS for Health はコンテナ版も用意があり InterSystems コンテナレジストリより自由に pull できます。
InterSystems コンテナレジストリの使い方やコンテナ開始までの流れは、「InterSystemsコンテナレジストリの使い方とコンテナ開始までの流れ(解説ビデオ付き)」をご参照ください。
この他、開発者コミュニティが開催している IRIS プログラミングコンテストでは、コンテナを利用した開発環境のテンプレートをご用意しています。使い方のイメージについては、こちらの記事のビデオ(8:26~)をご参照ください。
また、AWS、Azure、GCPのマーケットプレイスで IRIS または IRIS for Health の Community Edition をご利用いただけます。各クラウドでのご利用方法についてはこちらのビデオ(日本語字幕付き)をご参照ください(字幕の切り替えは上図をご参照ください)。
この他、オンラインラーニング、クラスルームラーニング(*) もございます。(*) 2020年4月より、ブラウザ経由でアクセスできる演習環境を利用した 対面形式 ではない ”オンライン” のクラスルームトレーニングを開催しています。
InterSystems 製品の使い方がちょっとわからない・・・というときは、ぜひ開発者コミュニティへご質問ください!
そして、良い解決方法をご存知の開発者のみなさま!ぜひ、回答にご協力ください!☺
お知らせ
Toshihiko Minamoto · 2020年12月21日
コミュニティの皆さん、こんにちは!
[グローバルマスターズ](https://intersystems.influitive.com/)に**ビジネスサービスリワード**を導入したことにより、お客様のアプリケーション、ソリューション、サービスの概要を開発者コミュニティや当社のソーシャルメディアに掲載していただけるようになったほか、OEX アプリケーションの宣伝に Google AdWords のキャンペーンをご利用いただけるようになりました!
$1,000 分の Google AdWords キャンペーンバウチャー
この賞品を使って Google Adwords で OEX アプリケーションを宣伝しましょう。キャンペーンのセットアップ (キーワード、説明、オーディエンス) は当社におまかせください。キャンペーン終了後にはレポートをお送りします。
注意: アプリケーションは InterSystems IRIS/IRIS for Health で動作する、または IRIS で管理 / 開発するツールである必要があります。
3,000 ポイント
開発者コミュニティの「ニュース」プロモーションブロック
この賞品を使ってディベロッパーコミュニティでサービスやイベント、空きページについて宣伝しましょう。 期間: 1 週間。 すべてのウェブページの右側のスペースが対象です。 当社のデザイナーがバナーを制作いたします。
注意: 開発サービス、イベント、空きページは InterSystems のテクノロジーに関連したものである必要があります。
1,500 ポイント
開発者コミュニティにおける Open Exchange プロジェクトのプロモーション
この賞品を使って開発者コミュニティで OEX プロジェクトを宣伝しましょう。
クリックすればお客様のプロジェクトに移動するリンクが付けられたバナーが 1 週間続けてすべてのウェブページの右側にある「App of the week」(今週のアプリ) ブロックに表示されるので、開発者コミュニティにアクセスされるすべての訪問者にご覧いただくことができます。
1,000 ポイント
InterSystems がサポートするウェビナー
プロのディベロッパー向けのウェビナーを開催し、お客様の会社が提供するソリューション、ツール、サービスを紹介することに興味をお持ちの方は、 この賞品をお使いください。当社がウェビナーの準備をお手伝いいたします。
得られる特典:
InterSystems のチームによるオンラインウェビナーのセットアップ
開発者コミュニティおよびソーシャルメディアを使ったウェビナーのプロモーション
開発者コミュニティのランディングページの制作
ウェビナー前のリハーサルおよびウェビナー開催中のテクニカルサポート
注意: アプリケーションは InterSystems IRIS/IRIS for Health で動作する、または IRIS で管理 / 開発するツールである必要があります。
3,000 ポイント
インターシステムズ開発者 YouTube チャンネルへの動画の投稿
インターシステムズデータプラットフォームに関連するツール、ソリューション、体験について解説した YouTube 動画をお持ちではないですか? Video Boost Pack を注文して YouTube 動画へのトラフィックを増やしましょう 。
Video Boost Packの内容
インターシステムズ開発者YouTube チャンネルでの動画のプロモーション
月間ダイジェストの「InterSystems ディベロッパー動画」への掲載 (サンプルはこちら)
グローバルマスターズや InterSystems 開発者向けソーシャルメディアでのプロモーション
1,500 ポイント
開発者コミュニティで会社のタグを紹介
この賞品を使い開発者コミュニティで会社のタグを入手すれば、会社の説明を掲載できるほか、記事を掲載するセクション、さらには独自の購読者をゲットできます。
5,000 ポイント
まだグローバルマスターズのメンバーになっていない方が賞品を使用する方法
➡️ 当社からの招待を受信してから
1. 開発者コミュニティで使用する同じ認証情報を使って[グローバルマスターズ](http://intersystems.influitive.com/)にログインします。
2. 「[Customize your program. START HERE!](http://intersystems.influitive.com/challenges/75)」と題したチャレンジで 4 つの質問に答えます (質問はその時に表示されます)。
3. OEX や 開発者コミュニティへの貢献に対するポイントは自動的に 3 日以内に付与されます。
4. 賞品は、[リワード](http://intersystems.influitive.com/rewards)カタログでご使用ください。
インターシステムズの開発者コミュニティには、毎月 35000 人を超えるオーディエンスがアクセスしています。InterSystems のデータプラットフォームで構築したアプリケーション、ソリューション、そしてサービスを世界中の人々と共有しましょう!
ご質問がある方は、お気軽に本記事のコメント欄よりお問い合わせください。
* * *
グローバルマスターズの追加情報: グローバルマスターズとは? ここからスタート
記事
Toshihiko Minamoto · 2021年6月23日
この記事では、InterSystems Cachéにおけるマクロについて説明します。 マクロは、コンパイル中に一連の命令に置き換えられるシンボリック名です。 マクロは、渡されたパラメーターとアクティブ化したシナリオに応じて、呼び出されるたびに一連の命令セットに「展開」されます。 これは、静的コードの場合もあれば、ObjectScriptを実行して得られる結果である場合もあります。 それでは、アプリケーションでマクロをどのように使用できるのかを見てみましょう。
コンパイル

まず、ObjectScriptコードがどのようにコンパイルされているのかを見てみましょう。
クラスコンパイラはクラス定義を使用してMACコードを生成します。
場合によっては、コンパイラはクラスを元に追加クラスを生成します。 これらのクラスはStudioで閲覧できますが、変更してはいけません。 この動作は、たとえば、WebサービスやWebクライアントのクラスを生成する際に発生します。
クラスコンパイラはランタイム時にCaché が使用するクラス記述子も生成します。
プリプロセッサ(マクロプロセッサまたはMPPとも呼ばれます)が、INCファイルを使用してマクロを置き換えます。 さらに、ObjectScriptルーチンにある埋め込みSQLも処理します。
これらの変更はすべてメモリで発生するため、ユーザーのコードに変化はありません。
その後、コンパイラはObjectScriptルーチンのINTコードを作成します。 このレイヤーは中間コードとして知られるレイヤーです。 このレベルでのデータへのすべてのアクセスは、グローバルを介して提供されます。
INTコードはコンパクトで、人間が読み取ることができます。 Studioで閲覧するには、Ctrl+Shift+Vを押してください。
INTコードを使用して、OBJコードが生成されます。
OBJコードは、Caché仮想マシンが使用するコードです。 OBJコードが生成されるとCLS/MAC/INTコードは不要になるため、不要となったそれらのコードは削除することができます(ソースコードを含めずに製品を出荷する場合など)。
1. クラスが[永続](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GOBJ_persobj_intro)クラスである場合、SQLコンパイラは対応するSQLテーブルを作成します。
マクロ
前に述べたように、マクロは、プリプロセッサによって命令セットに置き換えられるシンボリック名です。 マクロは[#Define](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros#GCOS_macros_mpp_lbDefine)コマンドにマクロ名(おそらく引数のリストを含む)とその値を続けて定義します。
#Define Macro[(Args)] [Value]
マクロはどこに定義されるのでしょうか。 マクロの定義は、コード内か、マクロのみを含む独立した[INCファイル](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GORIENT_ch_intro#GORIENT_intro_includefiles)で行われます。 必要なファイルは、クラス定義の最初にInclude MacroFileNameコマンドを使用してクラスに含められます。これがマクロをクラスに含めるための推奨される主な方法です。 この方法で含められるマクロは、クラスのどの部分にでも使用できます。 #Include MacroFileNameコマンドを使ってマクロを含むINCファイルをMACルーチンや特定のクラスメソッドのコードに含めることができます。
マクロをコンパイル時に使用する場合、またはクラスに[IncludeGenerator](https://docs.intersystems.com/latest/csp/docbook/Doc.View.cls?KEY=ROBJ_classdef_class#ROBJ_C191929)キーワードを使用する場合は、メソッドジェネレーターの本文に#Includeを使用する必要があることに注意してください。
Studioの自動補完でマクロを使用できるようにするには、前の行に///を追加します。
///
#Define Macro[(Args)] [Value]
例
_例1_
では、例をいくつか見てみましょう。標準的な「Hello World」メッセージから始めます。 COSコードは次のようになります。
Write "Hello, World!"
HWという、次の行を書き込むマクロを作成します。
#define HW Write "Hello, World!"
後は、$$$HW(マクロを呼び出す$$$と、その後にマクロ名を指定)を記述するのみです。
ClassMethod Test()
{
#define HW Write "Hello, World!"
$$$HW
}
これは、コンパイル中に次のINTコードに変換されます。
zTest1() public {
Write "Hello, World!" }
このメソッドが呼び出されると、ターミナルに次のテキストが表示されます。
Hello, World!
_例2_
次の例では、変数を使用し見ましょう。
ClassMethod Test2()
{
#define WriteLn(%str,%cnt) For ##Unique(new)=1:1:%cnt { ##Continue
Write %str,! ##Continue
}
$$$WriteLn("Hello, World!",5)
}
上記のコードでは、%str文字列が%cnt回書き込まれます。 変数名は%で始まる必要があります。 [##Unique(new)](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros#GCOS_macros_mpp_lblbUnique) コマンドで、生成されたコードに新しい一意の変数を作成し、[##Continue](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros#GCOS_macros_mpp_lblbContinue)によって、次の行にマクロの定義が続くことを示します。 このコードは、次のINTコードに変換されます。
zTest2() public {
For %mmmu1=1:1:5 {
Write "Hello, World!",!
} }
ターミナルには次のように表示されます。
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
_例3_
より複雑な例に進みましょう。 [ForEach](https://ja.wikipedia.org/wiki/Foreach%E6%96%87)演算子は、グローバルを反復処理する上で非常に役立ちます。それでは作成してみましょう。
ClassMethod Test3()
{
#define ForEach(%key,%gn) Set ##Unique(new)=$name(%gn) ##Continue
Set %key="" ##Continue
For { ##Continue
Set %key=$o(@##Unique(old)@(%key)) ##Continue
Quit:%key=""
#define EndFor }
Set ^test(1)=111
Set ^test(2)=222
Set ^test(3)=333
$$$ForEach(key,^test)
Write "key: ",key,!
Write "value: ",^test(key),!
$$$EndFor
}
INTコードでは次のようになります。
zTest3() public {
Set ^test(1)=111
Set ^test(2)=222
Set ^test(3)=333
Set %mmmu1=$name(^test)
Set key=""
For {
Set key=$o(@%mmmu1@(key))
Quit:key=""
Write "key: ",key,!
Write "value: ",^test(key),!
} }
これらのマクロでは何が起こっているのでしょうか。
1. グローバルの名前を新しい%mmmu1変数に書き込みます([$name](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_fname)関数)。
2. キーは、初期の空の文字列値です。
3. 反復サイクルが開始します。
4. [間接演算子](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_operators#GCOS_operators_indirection)と[$order](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_forder)関数を使って、キーに次の値が割り当てられます。
5. キーが""値を取っているかどうかを、[事後条件](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_commands#GCOS_commands_pc)を使ってチェックします。取っている場合は反復が完了し、サイクルが終了します。
6. 任意のユーザーコードが実行されます。この場合、キーと値が出力されます。
サイクルが終了します。
このメソッドが呼び出されると、ターミナルには次のように表示されます。
key: 1
value: 111
key: 2
value: 222
key: 3
value: 333
[%Collection.AbstractIterator](http://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%25Collection.AbstractIterator)クラスから継承したリストと配列を使用している場合は、同様のイテレーターを記述できます。
_例4_
マクロにはさらに、コンパイル段階で任意のObjectScriptコードを実行し、マクロの代わりにその結果に置き換えるという別の機能があります。 コンパイル時間を示すマクロを作成してみましょう。
ClassMethod Test4()
{
#Define CompTS ##Expression("""Compiled: " _ $ZDATETIME($HOROLOG) _ """,!")
Write $$$CompTS
}
これは、次のINTコードに変換されます。
zTest4() public {
Write "Compiled: 18.10.2016 15:28:45",! }
このメソッドが呼び出されると、ターミナルには次の行が表示されます。
Compiled: 18.10.2015 15:28:45
[##Expression](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros#GCOS_macros_mpp_lblbExpression)は、コードを実行して結果を置き換えます。 入力には、ObjectScript言語の次の要素を使用できます。
* 文字列: "abc"
* ルーチン: $$Label^Routine
* クラスメソッド: ##class(App.Test).GetString()
* COS関数: $name(var)
* 上記の要素の任意の組み合わせ
_例5_
コンパイル時に、ディレクティブの後に続く式の値に応じてソースコードを選択するには、プリプロセッサディレクティブの[#If、#ElseIf、#Else、#EndIf](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros#GCOS_macros_mpp_lbIf)を使用します。 たとえば、次のメソッドがあるとします。
ClassMethod Test5()
{
#If $SYSTEM.Version.GetNumber()="2016.2.0" && $SYSTEM.Version.GetBuildNumber()="736"
Write "You are using the latest released version of Caché"
#ElseIf $SYSTEM.Version.GetNumber()="2017.1.0"
Write "You are using the latest beta version of Caché"
#Else
Write "Please consider an upgrade"
#EndIf
}
Cachéバージョン2016.2.0.736では、このメソッドは次のINTコードにコンパイルされます。
zTest5() public {
Write "You are using the latest released version of Caché"
}
ターミナルには次のように表示されます。
You are using the latest released version of Caché
ベータポータルからダウンロードしたCachéを使用している場合、コンパイルされたINTコードは異なります。
zTest5() public {
Write "You are using the latest beta version of Caché"
}
ターミナルには次のように表示されます。
You are using the latest beta version of Caché
古いバージョンのCachéは、次のようにプログラムの更新を提案するINTコードをコンパイルします。
zTest5() public {
Write "Please consider an upgrade"
}
ターミナルには次のように表示されます。
Please consider an upgrade
この機能は、クライアントアプリケーションで古いバージョンと新しいバージョンとの互換性を保証したい場合に、Cachéの新機能が使用される可能性があるときなどに役立ちます。 プリプロセッサディレクティブの[#IfDef](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros#GCOS_macros_mpp_lbIfDef)と[#IfNDef](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros#GCOS_macros_mpp_lbIfNDef)は、順にマクロの存在と不在を検証することで、同じ目的を果たすことができます。
まとめ
マクロは、コンパイル段階で、頻繁に使用される構造を単純化することでコードを読みやすくして一部のアプリケーションのビジネスロジックを実装しやすくするため、ランタイム時の負荷を軽減することができます。
次の内容
次の記事では、アプリケーションにおけるマクロのより実用的な使用例について説明します。ロギングシステムです。
リンク
* [コンパイルについて](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GORIENT_ch_intro#GORIENT_intro_work_together)
* [プリプロセッサディレクティブ一覧](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros)
* [システムマクロ一覧](http://docs.intersystems.com/latestj/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros#GCOS_macros_syssupplied)
* [この記事の例を使ったクラス](https://gist.githubusercontent.com/eduard93/bbc88b85f03def7c3e15/raw/b1f0ad69863934139bd7d1dba7f76e1a54600d72/App.Test.cls.xml/App.Test.cls.xml)
第2部: ロギング
記事
Tomoko Furuzono · 2021年6月29日
これは、InterSystems FAQサイトの記事です。
InterSystems IRIS の Community Edition をご利用いただけます。
Community Edition を利用する方法は、以下の4つからご選択いただけます。
インターシステムズ開発者コミュニティ(https://jp.community.intersystems.com/)からダウンロード(Linux版/Windows版)し、インストールする
コンテナ版 IRIS(Docker がインストールされている環境があればすぐに利用を開始できます)
クラウド(AWS/Azure/GCP)のマーケットプレイスを利用する(コンテナ版 IRIS が動作します。クラウド使用料はお客様負担です。)
InterSystems Sandbox(3 日間限定の専用 IDE 付き無料体験環境)を利用する
1~3 の利用方法詳細は、こちらの記事のビデオでご紹介しています。ぜひご参照ください。
4 の使い方はこちらの記事をご参照ください。
この他、オンラインラーニング(英語) が提供する InterSystems Learning Labs(7日間限定のオンラインラーニング用) もあります(使用感は InterSystems Sandbox と同一です)。
記事
Toshihiko Minamoto · 2021年8月18日
PHP はその公開当初から、多くのライブラリや市場に出回っているほぼすべてのデータベースとの統合をサポートしていることでよく知られています(またそのことで批判を受けてもいます)。 にもかかわらず、何らかの不可解な理由により、グローバル変数については階層型データベースをサポートしませんでした。
グローバル変数は階層情報を格納するための構造です。 Key-Value型データベースにある程度似ていますが、キーを次のようにマルチレベルにできるという点で異なっています。
Set ^inn("1234567890", "city") = "Moscow"
Set ^inn("1234567890", "city", "street") = "Req Square"
Set ^inn("1234567890", "city", "street", "house") = 1
Set ^inn("1234567890", "year") = 1970
Set ^inn("1234567890", "name", "first") = "Vladimir"
Set ^inn("1234567890", "name", "last") = "Ivanov"
この例では、マルチレベルの情報は、ビルトインのObjectScript言語を使用して、グローバル変数の**^inn**に保存されています。 グローバル変数**^inn**は、ハードドライブに保存されています(これは、最初の「^」記号で示されています)。
PHP からグローバル変数を操作するには、PHP モジュールによって追加される新しい関数が必要となります。これについて、以下で説明します。
グローバル変数は、階層を操作するための多数の関数をサポートしています。固定レベルと縦型のトラバーサルツリーでツリー全体と個別のノードの削除、コピー、および貼り付けを行えます。 また、質の高いデータベースと同様に、ACID トランザクションもサポートされています。 これらは次の2つの理由により、非常に迅速に行われます(一般的なPCで、1秒間に105~106の挿入が行われます)。
1. グローバル変数は SQL に比べると、より低レベルの抽象化である。
2. ベースは数十年もの間グローバルスコープで稼働しており、この間に洗練され、コードは完全に最適化されてきた。
グローバル変数について詳しくは、「グローバル変数: データ管理の魔法の剣」という連載記事をご覧ください。
[パート1.](https://community.intersystems.com/post/globals-are-magic-swords-managing-data-part-1)
[ツリー。 パート2.](https://habr.com/ru/company/intersystems/blog/264173/)
[スパースアレイ。 パート3.](https://habr.com/ru/company/intersystems/blog/268465/)
この業界では、グローバル変数は主に、医療、個人データ、銀行などの構造化されていないまばらな情報のストレージシステムで使用されています。
私はPHPを気に入っており、開発作業でも使用しているため、グローバル変数を使って色々と試してみたいと思いました。 IRISとCaché用のPHPモジュールは存在しなかったため、 InterSystemsに問い合わせ、作成するよう依頼しました。 InterSystemsは教育助成金の一環として開発を後援してくれたおかげで、私の院生とともにモジュールを作成することになりました。
一般的に、InterSystems IRISはマルチモデルDBMSであるため、ODBCを通じてSQLを使ってPHPから操作することができますが、私が興味を持っていたのはグローバルであったため、それに使用できるコネクタは存在しなかったのです。
それはさておき、このモジュールはPHP 7.xで利用できます(7.0~7.2でテストしました)。 現在、同じホストにインストールされているInterSystems IRISとCachéでのみ動作します。
[OpenExchangeのModuleページ](https://openexchange.intersystems.com/package/PHP-module-for-IRIS)(InterSystems IRISとCachéの開発者向けのプロジェクトとアドオンのディレクトリ)。
開発者同士で関連する体験をシェアできるDISCUSSセクションが設けられています。
こちらからダウンロードしてください。
> [https://github.com/intersystems-community/php\_ext\_iris](https://github.com/intersystems-community/php_ext_iris) コマンドラインからリポジトリをダウンロードする場合:
git clone https://github.com/intersystems-community/php_ext_iris
[モジュールのインストール手順(英語・ロシア語)。](https://github.com/intersystems-community/php_ext_iris/blob/master/iris/INSTALL.md)
モジュールの関数:
PHP関数
説明
データの操作
iris_set($node, value)
ノードの値を設定します。iris_set($global, $subscript1, ..., $subscriptN, $value); iris_set($global, $value); 戻り値: true または false(エラーの場合)。この関数のすべてのパラメーターは文字列か数値です。 最初のパラメーターはグローバルの名前で、次にインデックス、そして最後のパラメーターは値です。 iris_set('^time',1); iris_set('^time', 'tree', 1, 1, 'value'); ObjectScript equivalent: Set ^time = 1 Set ^time("tree", 1, 1) = "value" iris_set($arrayGlobal, $value);パラメーターは2つしかありません。1つ目はグローバルの名前とすべてのインデックスを含む配列で、2つ目は値です。 $node = ['^time', 'tree', 1, 1]; iris_set($node,'value');
iris_get($node)
ノードの値を取得します。 戻り値: 値(数値または行)、NULL(値が定義されていません)、またはFALSE(エラーの場合)。 iris_get($global, $subscript1, ..., $subscriptN); iris_get($global); この関数のすべてのパラメーターは行または数値です。 1つ目はグローバルの名前で、残りはサブスクリプトです。 グローバルにはサブスクリプトがない場合があります。 $res = iris_get('^time'); $res1 = iris_get('^time', 'tree', 1, 1); iris_get($arrayGlobal); 唯一のパラメーターは、グローバルの名前とそのすべてのサブスクリプトが格納されている配列です。 $node = ['^time', 'tree', 1, 1]; $res = iris_get($node);
iris_zkill($node)
ノードの値を削除します。 戻り値: TRUEまたはFALSE(エラーの場合)。 この関数はノードの値のみを削除し、下位のブランチには影響しないことに注意してください。 iris_zkill($global, $subscript1, ..., $subscriptN); iris_zkill($global); この関数のすべてのパラメーターは行または数値です。 1つ目はグローバルの名前で、残りはサブスクリプトです。 グローバルにはサブスクリプトがない場合があります。 $res = iris_zkill('^time'); // 下位ブランチは削除されません。 $res1 = iris_zkill('^time', 'tree', 1, 1); iris_zkill($arrayGlobal); 唯一のパラメーターは、グローバルの名前とそのすべてのサブスクリプトが格納されている配列です。 $a = ['^time', 'tree', 1, 1]; $res = iris_zkill($a);
iris_kill($node)
ノードとすべての子孫ブランチを削除します。 戻り値: TRUEまたはFALSE(エラーの場合)。 iris_kill($global, $subscript1, ..., $subscriptN); iris_kill($global); この関数のすべてのパラメーターは行または数値です。 1つ目はグローバルの名前で、残りはインデックスです。 グローバルにはインデックスがない場合があり、その場合は完全に削除されます。 $res1 = iris_kill('^example', 'subscript1', 'subscript2'); $res = iris_kill('^time'); // グローバルは完全に削除されます。 iris_kill($arrayGlobal); 唯一のパラメーターは、グローバルの名前とそのすべてのサブスクリプトが格納されている配列です。 $a = ['^time', 'tree', 1, 1]; $res = iris_kill($a);
iris_order($node)
指定されたレベルでグローバルのブランチをトラバースします。戻り値: 同じレベルのグローバルの前のノードのフルネームが格納されている配列、またはFALSE(エラーの場合)。 iris_order($global, $subscript1, ..., $subscriptN); この関数のすべてのパラメーターは文字列または数値です。 1つ目のパラメーターはグローバルの名前で、残りはサブスクリプトです。PHPとObjectScript相当の使用方法: iris_order('^ccc','new2','res2'); // $Order(^ccc("new2", "res2")) iris_order($arrayGlobal); 唯一のパラメーターは、グローバルの名前と最初のノードのサブスクリプトが格納されている配列です。 $node = ['^inn', '1234567890', 'city']; for (; $node !== NULL; $node = iris_order($node)) { echo join(', ', $node).'='.iris_get($node)."\n"; } Returns: ^inn, 1234567890, city=Moscow ^inn, 1234567890, year=1970
iris_order_rev($node)
指定されたレベルでグローバルのブランチを逆順にトラバースします。戻り値: 同じレベルのグローバルの前のノードのフルネームが格納されている配列、またはFALSE(エラーの場合)。 iris_order_rev($global, $subscript1, ..., $subscriptN); この関数のすべてのパラメーターは行または数値です。 1つ目はグローバルの名前で、残りはサブスクリプトです。 PHPとObjectScript相当の使用方法: iris_order_rev('^ccc','new2','res2'); // $Order(^ccc("new2", "res2"), -1) iris_order_rev($arrayGlobal); 唯一のパラメーターは、グローバルの名前と最初のノードのサブスクリプトが格納されている配列です。 $node = ['^inn', '1234567890', 'name', 'last']; for (; $node !== NULL; $node = iris_order_rev($node)) { echo join(', ', $node).'='.iris_get($node)."\n"; } 戻り値: ^inn, 1234567890, name, last=Ivanov ^inn, 1234567890, name, first=Vladimir
iris_query($CmdLine)
グローバルの縦型トラバース 戻り値: 下位ノード(使用可能な場合)またはグローバルの次のノード(埋め込みノードがない場合)のフルネームが含まれている配列。 iris_query($global, $subscript1, ..., $subscriptN); この関数のすべてのパラメーターは文字列または数値です。 1つ目はグローバルの名前で、残りはサブスクリプトです。 PHPとObjectScript相当の使用方法: iris_query('^ccc', 'new2', 'res2'); // $Query(^ccc("new2", "res2")) iris_query($arrayGlobal); 唯一のパラメーターは、グローバルの名前と最初のノードのインデックスが格納されている配列です。 $node = ['^inn', 'city']; for (; $node !== NULL; $node = iris_query($node)) { echo join(', ', $node).'='.iris_get($node)."\n"; } 戻り値: ^inn, 1234567890, city=Moscow ^inn, 1234567890, city, street=Req Square ^inn, 1234567890, city, street, house=1 ^inn, 1234567890, name, first=Vladimir ^inn, 1234567890, name, last=Ivanov ^inn, 1234567890, year=1970 この順序は挿入時にグローバル内で自動的に昇順にソートされるため、設定した順序とは異なります。
サービス関数
iris_set_dir($FullPath)
データベースのディレクトリをセットアップします。戻り値: TRUEまたはFALSE(エラーの場合)。 iris_set_dir('/InterSystems/Cache/mgr'); これはデータベースに接続する前に実行する必要があります。
iris_exec($CmdLine)
データベースコマンドを実行します。戻り値: TRUEまたはFALSE(エラーの場合)。 iris_exec('kill ^global(6)'); // グローバルを削除するObjectScriptコマンド
iris_connect($login, $pass)
データベースに接続します。
iris_quit()
DBとの接続を閉じます。
iris_errno()
エラーコードを取得します。
iris_error()
エラーのテキストによる説明を取得します。
モジュールを試してみたい場合は、dockerコンテナーの実装などを確認してください。
git clone https://github.com/intersystems-community/php_ext_iris
cd php_ext_iris/iris
docker-compose build
docker-compose up -d
ブラウザで
localhost:52080のデモページをテストしてください。編集して試せるPHPファイルはphp/demoフォルダにあります。コンテナー内にマウントされます。
IRISをテストするには、ログイン「admin」とパスワード「SYS」を使用してください。
IRISの設定にアクセスするには、次のURLを使用してください。http://localhost:52773/csp/sys/UtilHome.csp
このコンテナーのIRISコンソールにアクセスするには、次のコマンドを使用してください。
docker exec -it iris_iris_1 iris session IRIS
特にDCや使用したい方のために、Caché用php-moduleがセットアップされた仮想マシンを実行しています。
英語のデモページ。 ロシア語のデモページ。 ログイン: habr_test パスワード: burmur#@8765
InterSystems Cachéにモジュールを自分でインストールする場合
Linuxを用意してください。 私はUbuntuでテストしました。Windowsでもモジュールをコンパイルして動作できるはずですが、テストは行っていません。
無料バージョンをダウンロードします。
InterSystems Caché(登録が必要です)。 Linuxに関しては、Red HatとSuseは初期設定のままでサポートされていますが、ほかの配布パッケージでもインストールできます。
指示に従って、PHPにcach.soモジュールをインストールします。
単なる好奇心で、私のPC(AMD FX-9370@4700Mhz 32GB、LVM、SATA SSD)のdockerコンテナーで新しい値をデータベースに挿入する速度をチェックするプリミティブテストを2つ実行しました。
* 100万個の新しいノードをグローバルに挿入するのに、1.81秒掛かりました(1秒あたり552Kの挿入)。
* 同じグローバルの値を1,000,000回更新するのに、1.98秒掛かりました(1秒当たり505Kの更新)。 興味深かったのは、挿入が更新よりも早く行われたということです。 どうやらこれは、迅速な挿入を目的としたデータベースの初期最適化の結果のようです。
明らかに、これらのテストは原始的であり、コンテナー内で実行されるため、100%の正確性または有用性があるとは考えられません。 PCIe SSDにディスクシステムを備えたより強力なハードウェアでは、1秒あたり数千万の挿入を達成可能です。
### 作成中の機能とその状況
1. トランザクションを操作するための便利な関数を追加できます(iris_execで使用できます)。
2. グローバル構造全体を返す関数は実装されていません。PHPからグローバルをトラバースする関数についても同様です。
3. PHP配列をサブツリーとして保存する関数は実装されていません。
4. ローカルデータベース変数へのアクセスは実装されていません。 iris\_setを使用した方が良いですが、iris\_execのみを使用してください。
5. 逆順での縦型グローバルトラバースは実装されていません。
6. メソッドを使ったオブジェクト経由のデータベースアクセス(現在の関数に類似)は実装されていません。
現在のモジュールはまだ本番対応とは言えません。高負荷やメモリリークについてのテストは行われていません。 ただし、必要だという方がいらっしゃれば、いつでもご連絡ください(Sergey Kamenev宛: sukamenev@gmail.com)。
### 結論
グローバルは特定のデータタイプ(医療、個人データなど)に強力で高速な機能を提供しているにも関わらず、長い間、PHPの世界とグローバル変数での階層型データベースの世界では、実質的に重なることがありませんでした。
このモジュールをきっかけに、PHPプログラマーがグローバル変数を試すようになり、ObjectScriptプログラマーがPHPでウェブインターフェースを簡単に開発できるようになることを願っています。
追伸 最後までお読みいただき、ありがとうございました!
記事
Mihoko Iijima · 2021年8月16日
InterSystems Reportsでレポートを作成するのは難しいですか?
ネタバレ
Super easy!
InterSystems IRIS + InterSystems Reports を使用して 2 つの簡単な例を作成し、2 つのアプリケーションのセットアップがいかに簡単だったかを共有しようと思います!
次のいくつかの段落で、このプロセスが簡単でシンプルであることを示すステップバイステップのガイドをご紹介します。
Logi Report Designer のインストール後、InterSystems IRIS のアイコンを開いて選択します。
2番目のステップでは、既存のカタログを選択するか、新しいカタログを作成するか選択できます。
新しいカタログを作成し、お好みのフォルダに保存したあと、新しいデータソースを作成します。
フィールドは、サーバの IP または DSN 名、ポート、ネームスペース、ユーザ、パスワードを入力します。
データソースにテーブル、ビュー、クエリを追加することができます。
接続情報、テーブル、ビュー、クエリの設定が完了したら次のステップに進みましょう。
New アイコンをクリックし New Report を選択します。
今回のレポートでは、下図のように「Table (Group Left) 」を選びました。
テーブルウィザードでは、データソース、データ表示、グループ化、サマリ、チャート、フィルター、スタイルを選択できます。
ここでは、@Evgeny.Shvarov さんが作成した iris-analytics-template を使用して Covidテーブルをレポートサンプルデータソースとして使用しています。
選択したフィールドは、Confirmed と Deaths です。
このレポートのグループは Contry_Region です。
Country_Region グループの Summary は、集計機能(SUM)で確認され、フッターの位置にある Country_Region が区切りのフィールドとなります。
図では、カテゴリに「Country_Region」を指定したバーチャートを選択し、「Confirmed」フィールドに値を表示しました。
下図で適用しているスタイルは既存スタイルの1つで、「Classic」を選択しました。
下図は、ウィザード終了後にレポートが表示された様子です。
このファイル:covid19_cases_-_WorldCount-Sample.pdf は、報告書用のサンプルです。
別のシンプルなサンプルが必要な場合は、このファイル refugees_CitiesImpacted_ReportSample.pdf もあります。
この記事の作者であるエンリケさんの Gitリポジトリにあります。
このデータセット(Refugee Admission to the US Ending FY 2018 - dataset by associatedpress | data.world)では、2018 年度末の米国への難民受け入れのデータセットのレポートを表示しています。
記事
Toshihiko Minamoto · 2021年10月12日
[前の記事](https://jp.community.intersystems.com/node/492151)では、マクロの潜在的なユースケースををレビューしました。そこで、マクロの使用方法についてより包括的な例を見てみることにしましょう。 この記事では、ロギングシステムを設計して構築します。
### ロギングシステム
ロギングシステムは、アプリケーションの作業を監視するための便利なツールで、デバッグや監視にかける時間を大幅に節約してくれます。 これから構築するシステムは2つの部分で構成されます。
* ストレージクラス(レコードをログ記録するためのクラス)
* 新しいレコードをログに自動的に追加する一連のマクロ
### ストレージクラス
保存する必要のあるもののテーブルを作成し、コンパイル中やランタイム時に、このデータを取得できるタイミングを指定しましょう。 これは、システムの2つ目の部分であるマクロで作業するときに必要となります。そこでは、コンパイル中にできるだけ多くの記録可能な詳細を取得することを目指します。
情報
取得タイミング
イベントタイプ
コンパイル
クラス名
コンパイル
メソッド名
コンパイル
メソッドに渡される引数
コンパイル
clsソースコードの行番号
ランタイム
生成されたintコードの行番号
ランタイム
ユーザー名
ランタイム
日付/時刻
ランタイム
メッセージ
ランタイム
IPアドレス
ランタイム
上記のテーブルのプロパティを含むApp.Logクラスを作成しましょう。 App.Logオブジェクトが作成されると、ユーザー名、日付/時刻、およびIPアドレスプロパティは、自動的に入力されます。
App.Logクラス:
Class App.Log Extends %Persistent
{
/// イベントのタイプ
Property EventType As %String(MAXLEN = 10, VALUELIST = ",NONE,FATAL,ERROR,WARN,INFO,STAT,DEBUG,RAW") [ InitialExpression = "INFO" ];
/// クラスの名前、イベントが起きた場所
Property ClassName As %Dictionary.Classname(MAXLEN = 256);
/// メソッドの名前、イベントが起きた場所
Property MethodName As %String(MAXLEN = 128);
/// intコードの行
Property Source As %String(MAXLEN = 2000);
/// clsコードの行
Property SourceCLS As %String(MAXLEN = 2000);
/// Cacheユーザー
Property UserName As %String(MAXLEN = 128) [ InitialExpression = {$username} ];
/// メソッドに渡された引数の値
Property Arguments As %String(MAXLEN = 32000, TRUNCATE = 1);
/// 日付と時刻
Property TimeStamp As %TimeStamp [ InitialExpression = {$zdt($h, 3, 1)} ];
/// ユーザーメッセージ
Property Message As %String(MAXLEN = 32000, TRUNCATE = 1);
/// ユーザーのIPアドレス
Property ClientIPAddress As %String(MAXLEN = 32) [ InitialExpression = {..GetClientAddress()} ];
/// ユーザーIPアドレスの特定
ClassMethod GetClientAddress()
{
// %CSP.Session source is preferable
#dim %request As %CSP.Request
If ($d(%request)) {
Return %request.CgiEnvs("REMOTE_ADDR")
}
Return $system.Process.ClientIPAddress()
}
}
###
### ロギングマクロ
通常、マクロは、その定義を含む個別の *.incファイルに保存されます。 必要なファイルは、Include MacroFileNameコマンドを使って、クラスに含めることができます。この場合、Include App.LogMacroとなります。
初めに、ユーザーがアプリケーションコードに追加するメインのマクロを定義しましょう。
#define LogEvent(%type, %message) Do ##class(App.Log).AddRecord($$$CurrentClass, $$$CurrentMethod, $$$StackPlace, %type, $$$MethodArguments, %message)
このマクロは、イベントタイプとメッセージの2つの入力引数を受け入れます。 メッセージ引数はユーザーが定義しますが、イベントタイプパラメーターには、イベントタイプを自動的に識別する、別の名前による追加のマクロが必要となります。
#define LogNone(%message) $$$LogEvent("NONE", %message)
#define LogError(%message) $$$LogEvent("ERROR", %message)
#define LogFatal(%message) $$$LogEvent("FATAL", %message)
#define LogWarn(%message) $$$LogEvent("WARN", %message)
#define LogInfo(%message) $$$LogEvent("INFO", %message)
#define LogStat(%message) $$$LogEvent("STAT", %message)
#define LogDebug(%message) $$$LogEvent("DEBUG", %message)
#define LogRaw(%message) $$$LogEvent("RAW", %message)
したがって、ロギングを実行するには、ユーザーはアプリケーションコードに$$$LogError("Additional message")のみを配置するだけで済みます。
後は、$$$CurrentClass、$$$CurrentMethod、$$$StackPlace、$$$MethodArgumentsマクロを定義するのみです。 では、最初の3つから始めましょう。
#define CurrentClass ##Expression($$$quote(%classname))
#define CurrentMethod ##Expression($$$quote(%methodname))
#define StackPlace $st($st(-1),"PLACE")
%classnameと%methodname変数は、[ドキュメント](http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=GCOS_macros)に記載されています。 [$stack](http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_fstack)関数はINTコードの行番号を返します。 これをCLS行番号に変換するには、このコードを使用できます。
%Dictionaryパッケージを使用して、メソッド引数とその値のリストを取得しましょう。 これにはメソッドの説明を含む。クラスに関するすべての情報が含まれています。 特に関心があるのは%Dictionary.CompiledMethodクラスとFormalSpecParsedプロパティで、これはリストです。
$lb($lb("Name","Classs","Type(Output/ByRef)","Default value "),...)
これはメソッドのシグネチャに対応しています。 たとえば次のコードがあるとします。
ClassMethod Test(a As %Integer = 1, ByRef b = 2, Output c)
このコードには、次のFormalSpecParsed値があります。
$lb(
$lb("a","%Library.Integer","","1"),
$lb("b","%Library.String","&","2"),
$lb("c","%Library.String","*",""))
$$$MethodArgumentsマクロを次のコードに展開する必要があります(Testメソッド)。
"a="_$g(a,"Null")_"; b="_$g(b,"Null")_"; c="_$g(c,"Null")_";"
これを行うには、コンパイル中に次のことを行う必要があります。
クラス名とメソッド名を取得する
%Dictionary.CompiledMethodクラスの対応するインスタンスを開いて、そのFormalSpecプロパティを取得する
それをソースコード行に変換する
対応するメソッドをApp.Logクラスに追加しましょう。
ClassMethod GetMethodArguments(ClassName As %String, MethodName As %String) As %String
{
Set list = ..GetMethodArgumentsList(ClassName,MethodName)
Set string = ..ArgumentsListToString(list)
Return string
}
ClassMethod GetMethodArgumentsList(ClassName As %String, MethodName As %String) As %List
{
Set result = ""
Set def = ##class(%Dictionary.CompiledMethod).%OpenId(ClassName _ "||" _ MethodName)
If ($IsObject(def)) {
Set result = def.FormalSpecParsed
}
Return result
}
ClassMethod ArgumentsListToString(List As %List) As %String
{
Set result = ""
For i=1:1:$ll(List) {
Set result = result _ $$$quote($s(i>1=0:"",1:"; ") _ $lg($lg(List,i))_"=")
_ "_$g(" _ $lg($lg(List,i)) _ ","_$$$quote(..#Null)_")_"
_$s(i=$ll(List)=0:"",1:$$$quote(";"))
}
Return result
}
次に$$$MethodArgumentsマクロを以下のように定義しましょう。
#define MethodArguments ##Expression(##class(App.Log).GetMethodArguments(%classname,%methodname))
ユースケース
それでは、ロギングシステムの機能を示すために、Testメソッドを使ってApp.Useクラスを作成しましょう。
Include App.LogMacro
Class App.Use [ CompileAfter = App.Log ]
{
/// Do ##class(App.Use).Test()
ClassMethod Test(a As %Integer = 1, ByRef b = 2)
{
$$$LogWarn("Text")
}
}
上記の結果、intコードの$$LogWarn("Text")マクロは次の行に変換されます。
Do ##class(App.Log).AddRecord("App.Use","Test",$st($st(-1),"PLACE"),"WARN","a="_$g(a,"Null")_"; b="_$g(b,"Null")_";", "Text")
このコードを実行すると、新しいApp.Logレコードが作成されます。
改善点
ロギングシステムを作成したところで、次のような改善のアイデアがあります。
まず、オブジェクト型引数を処理するようにすることができます。現在の実装では、オブジェクトorefしか記録しないためです。
次に、呼び出しで、保存された引数値からメソッドのコンテキストを復元するようにできます。
オブジェクト型引数の処理
引数の値をログに入れる行は、ArgumentsListToStringメソッドに生成され、次のようになります。
"_$g(" _ $lg($lg(List,i)) _ ","_$$$quote(..#Null)_")_"
リファクタリングを行って、それを、変数名とクラス(FormalSpecParsedから知ることができます)を受け入れる別のGetArgumentValueメソッドに移動し、変数を行に変換するコードを出力してみましょう。 データ型には既存のコードを使用し、オブジェクトは、SerializeObject(ユーザーコードから呼び出すため)とWriteJSONFromObject(オブジェクトをJSONに変換するため)メソッドを使ってJSONに変換されます。
ClassMethod GetArgumentValue(Name As %String, ClassName As %Dictionary.CacheClassname) As %String
{
If $ClassMethod(ClassName, "%Extends", "%RegisteredObject") {
// オブジェクトです
Return "_##class(App.Log).SerializeObject("_Name _ ")_"
} Else {
// データ型です
Return "_$g(" _ Name _ ","_$$$quote(..#Null)_")_"
}
}
ClassMethod SerializeObject(Object) As %String
{
Return:'$IsObject(Object) Object
Return ..WriteJSONFromObject(Object)
}
ClassMethod WriteJSONFromObject(Object) As %String [ ProcedureBlock = 0 ]
{
Set OldIORedirected = ##class(%Device).ReDirectIO()
Set OldMnemonic = ##class(%Device).GetMnemonicRoutine()
Set OldIO = $io
Try {
Set Str=""
//IOを現在のルーチンにリダイレクト。以下に定義するラベルを利用。
Use $io::("^"_$ZNAME)
//リダイレクトを有効にします
Do ##class(%Device).ReDirectIO(1)
Do ##class(%ZEN.Auxiliary.jsonProvider).%ObjectToJSON(Object)
} Catch Ex {
Set Str = ""
}
//元のリダイレクト/ニューモニックルーチンの設定に戻ります
If (OldMnemonic '= "") {
Use OldIO::("^"_OldMnemonic)
} Else {
Use OldIO
}
Do ##class(%Device).ReDirectIO(OldIORedirected)
Quit Str
// IOリダイレクトが可能なラベル
// 文字の読み取り。読み取りは重要ではありません
rchr(c) Quit
// 文字列の読み取り。読み取りは重要ではありません
rstr(sz,to) Quit
// 文字の書き込み。出力ラベルを呼び出します
wchr(s) Do output($char(s)) Quit
// フォームフィードの書き込み。出力ラベルを呼び出します
wff() Do output($char(12)) Quit
// 改行の書き込み。出力ラベルを呼び出します
wnl() Do output($char(13,10)) Quit
// 文字列の書き込み。出力ラベルを呼び出します
wstr(s) Do output(s) Quit
// タブの書き込み。出力ラベルを呼び出します
wtab(s) Do output($char(9)) Quit
// 出力ラベル。ここで、実際に行いたいことを処理します。
// ここではStrに書き込みます
output(s) Set Str = Str_s Quit
}
オブジェクト型引数のログエントリは次のようになります。

### コンテキストの復元
このメソッドの主旨は、すべての引数を現在のコンテキストで(主にデバッグ用のターミナルで)使用できるようにすることです。 これを行うために、ProcedureBlockメソッドパラメーターを使用することができます。 0に設定すると、そのようなメソッドに宣言されたすべての変数はメソッドを終了してもそのまま使用することができます。 ここでのメソッドは、App.Logクラスのオブジェクトを開いて、Argumentsプロパティを逆シリアル化します。
ClassMethod LoadContext(Id) As %Status [ ProcedureBlock = 0 ]
{
Return:'..%ExistsId(Id) $$$OK
Set Obj = ..%OpenId(Id)
Set Arguments = Obj.Arguments
Set List = ..GetMethodArgumentsList(Obj.ClassName,Obj.MethodName)
For i=1:1:$Length(Arguments,";")-1 {
Set Argument = $Piece(Arguments,";",i)
Set @$lg($lg(List,i)) = ..DeserializeObject($Piece(Argument,"=",2),$lg($lg(List,i),2))
}
Kill Obj,Arguments,Argument,i,Id,List
}
ClassMethod DeserializeObject(String, ClassName) As %String
{
If $ClassMethod(ClassName, "%Extends", "%RegisteredObject") {
// オブジェクトです
Set st = ##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(String,,.obj)
Return:$$$ISOK(st) obj
}
Return String
}
ターミナルでは次のように表示されます。
> zw
> do ##class(App.Log).LoadContext(2)
> zw
a=1 b=<OBJECT REFERENCE> [2@%ZEN.proxyObject]
> zw b
b=<OBJECT REFERENCE> [2@%ZEN.proxyObject]
+----------------- general information ---------------
| oref value: 2
| class name: %ZEN.proxyObject
| reference count: 2
+----------------- attribute values ------------------
| %changed = 1
| %data("prop1") = 123
| %data("prop2") = "abc"
| %index = ""
### この続きは?
鍵となる潜在的な改善点は、メソッド内に作成された任意の変数リストを使用して、ログクラスに別の引数を追加することです。
### まとめ
マクロはアプリケーション開発に非常に役立ちます。
### 質問
コンパイル中に行番号を取得する方法はありますか?
### リンク
* [パート1. マクロ](https://jp.community.intersystems.com/node/492151)
* [GitHubリポジトリ](https://github.com/intersystems-ru/Log)
記事
Toshihiko Minamoto · 2021年12月24日
皆さん、こんにちは。私の最新のプロジェクトの1つをご紹介します。 [Grafana用データソースプラグイン](https://openexchange.intersystems.com/package/Grafana-Plugin-for-InterSystems)です。これは、InterSystems IRISに直接接続して(将来的に)あらゆるデータを収集できるプラグインです。
.png)
### 機能
* 定期的に更新される履歴付きのSAM メトリクスで、Grafanaが直接収集したメトリクスを、表示中にリクエストされた場合にのみ表示できます。
* messages.logとalerts.logを表示します。
* ^ERRORSグローバルのアプリケーションエラー
#### 後日追加予定の機能
* DateTimeフィールドの有無に関わらずテーブルをクエリするすべてのSQL SELECT
* グローバルからデータを直接表示
* IRIS側でカスタムSQLクエリを呼び出す
* MDXクエリ
つまり、アプリケーション内でログを記録するためのカスタムロジックが存在する場合、Grafanaをそれらのログに接続して、そこで表示することが可能ということです。
### テスト
自分でテストしてみるには、リポジトリをクローンして、docker-composeで環境を開始します。 docker-compose環境はポート3000、3081、3082を使用して構成されるようになっているため、システム上でこれらのポートがすでに使用されている場合は、docker-compose.ymlファイルでポートを変更してください。
git clone https://github.com/caretdev/grafana-intersystems-datasource.git
cd grafana-intersystems-datasource
docker-compose up -d
イメージをプルしたら、2つのコンテナでGrafanaとIRISが開始します。
Grafanaはhttp://localhost:3000/で開きます。
[DataSources]に移動すると、InterSystems IRIS接続が自動プロビジョニングによって追加されています。
.png)
中を覗くと、基本設定付きの単純なフォームと接続を確認するための[Test]ボタンがあります。 IRISが起動すると、緑色の「OK」が表示されます。
.png)
ダッシュボードとパネルを作成しましょう

[Query Type]で「Metrics」を選択します。

例としてiris\_db\_latencyを選択しましょう

デフォルトの更新間隔は選択した時間間隔に応じますが、クエリオプションの[Min Interval]フィールドで変更することができます。
.png)
ログファイルとアプリケーションエラーは、ログの視覚化とともにテーブルとして表示することができます。

[プロジェクトに投票](https://openexchange.intersystems.com/contest/current)してください
プラグインにほかの機能の追加を希望する場合は、私にご連絡ください。
記事
Hiroshi Sato · 2022年7月11日
CPU:サポート対象OSが問題なく動作するもの以下のページをご参考ください。
サポート対象プラットフォーム
ディスク容量:アプリケーションの要件を除外した場合、 IRISをインストールするためには、最低1.5GB以上の空き容量が必要です。
ディスク容量の最小要件
実際に必要となる容量は、インストーラでセットアップタイプで "カスタム(Custom)"
を選択すると、インストールコンポーネント毎にご確認いただけます。
メモリ:推奨メモリー値は、アプリケーションや物理メモリサイズによるため
一概には言えませんが、IRISの全プロセスで使用するメモリサイズは以下になります。
①プロセスパーティション * ⑤プロセス数
+
②データベースキャッシュ
+
③ルーチンキャッシュ
+
④一般ヒープメモリ
計算式でのこれらのパラメータは、業務アプリケーションの特性により異なってきます。
以前に導入実績のある業務アプリケーションの場合、既存システムでどの様に設定されたかも参考にしてください。
①プロセスパーティション(プロセスあたりの最大メモリ)
管理ポータルで設定します。既定値は 262,144(KB)です。
[システム管理] > [構成 > [システム構成] > [メモリと開始設定] > [プロセスあたりの最大メモリ(KB)]
プロセス当たりの最大メモリ設定
②データベースキャッシュ
業務アプリケーションにて必要と思われるサイズに調整します。
以下FAQトピックをご参照ください
データベースキャッシュおよびルーチンキャッシュの最適値
③ルーチンキャッシュ
業務アプリケーションにて必要と思われるサイズに調整します。
以下FAQトピックをご参照ください
データベースキャッシュおよびルーチンキャッシュの最適値④一般ヒープメモリ 既定値は 37,568(KB)です。
ロックテーブルを大きくする場合など調整する必要があります。
⑤プロセス数
業務で同時にIRIS使用するプロセス数。
パラメータとして最大数の指定はありません。
以下もあわせて参考にしてください。
構成マネージャのメモリ関連設定項目について教えてください。
InterSystems製品のプロセスが使用するメモリ量を教えてください。
データベースキャッシュおよびルーチンキャッシュの最適値を設定したいです
メモリ要件の見積もり
お知らせ
Mihoko Iijima · 2023年1月15日
開発者の皆さん、こんにちは!
2023年最初のコンテストの開催が決定しました!今回は、開発者の皆さんの開発が快適になるような便利ツールをご応募いただくコンテストです!
🏆 InterSystems デベロッパーツールコンテスト🏆
InterSystems IRISを使用して、開発のスピードアップ、より定性的なコードの貢献、テスト、デプロイ、サポート、ソリューションのモニタリングを支援するアプリケーションを提出してください。
期間: 2023年1月23日~2月12日
賞金: $13,500
コンテストのテーマ
💡 InterSystems IRIS 開発者ツール 💡
このコンテストでは、IRISを使用する開発者のエクスペリエンスを向上させ、より速く開発し、より定性的なコードに貢献し、InterSystems IRISを使用するソリューションのテスト、デプロイ、サポート、モニタリングに役立つアプリケーションをご応募ください。
要件:
応募可能なアプリケーション
Open Exchange アプリケーションの新規作成、または既存アプリケーションであっても大幅に改善されているものであればご応募いただけます。
コミュニティの担当チームは、コンテストへの応募を承認する前に申請された全アプリケーションをレビューします。
全てのアプリケーションは、IRIS for Health Community Edition で動作する必要があります。
アプリケーションは、以下いずれかのタイプで作成してください。
UIフレームワーク
IDE
データベース管理
モニタリング
デプロイツール
etc...
アプリケーションはオープンソースであり、GitHubで公開されている必要があります。
アプリケーションの README ファイルは、英語で記述してください(日本語で記述したものがあればそのまま掲載いただき、英文の追記をお願いします。翻訳アプリを使用しますが翻訳をお手伝いすることもできますのでお気軽にお知らせください!)。また、インストール手順や、アプリケーションがどのように動作するかの説明、またはビデオデモを含めてください
入賞特典:
1. Experts Nomination – 審査員から多く票を集めたアプリケーションには、以下の賞金が贈られます
🥇 1位 - $5,000
🥈 2位 - $3,000
🥉 3位 - $1,500
🏅 4位 - $750
🏅 5位 - $500
🌟 6-10位 - $100
2. Community winners - 開発者コミュニティで多く票を集めたソリューションには、以下の賞金が贈られます。
🥇 1位 - $750
🥈 2位 - $500
🥉 3位 - $250
複数の参加者が同数の票を獲得した場合、全参加者が勝者となり賞金は勝者間で分配されます
スケジュール:
🛠 アプリケーション開発と応募期間:
2023年1月23日(00:00 EST): コンテスト開始!
2023年2月5日(23:59 EST): 応募締め切り日
✅ 投票期間:
2023年2月6日 (00:00 EST): 投票開始!
2023年2月12日 (23:59 EST): 投票終了日
応募、投票期間中、アップロードしたアプリケーションは改良できます。
参加資格:
どなたでもご参加いただけます!(InterSystems 開発者コミュニティのアカウントを作成するだけでご応募いただけます)
👥開発者がチームを組んで共同でアプリケーションを作成し、応募することもできます! 1チーム 2~5名 までご参加いただけます。
チームでご応募いただく場合は、アプリケーションの README にチームメンバー名の記載をお忘れなく!!(開発者コミュニティのプロファイルのリンクもお願いします)
Helpful resources
✓ Example applications:
iris-rad-studio - RAD for UI
cmPurgeBackup - backup tool
errors-global-analytics - errors visualization
objectscript-openapi-definition - open API generator
Test Coverage Tool - test coverage helper
and many more.
✓ Templates we suggest to start from:
iris-dev-template
rest-api-contest-template
native-api-contest-template
iris-fhir-template
iris-fullstack-template
iris-interoperability-template
iris-analytics-template
テンプレート一覧(日本語解説ページへのリンク入り)
✓ For beginners with IRIS:
Build a Server-Side Application with InterSystems IRIS
Learning Path for beginners
【はじめての InterSystems IRIS】セルフラーニングビデオ 索引
【はじめてのInterSystems IRIS】Interoperability(相互運用性)を使ってみよう!
ObjectScript クックブック
✓ For beginners with ObjectScript Package Manager (ZPM):
How to Build, Test and Publish ZPM Package with REST Application for InterSystems IRIS
Package First Development Approach with InterSystems IRIS and ZPM
✓コンテストへの応募方法
Need Help?
ご質問がある場合は、この投稿へコメントいただくか、InterSystems の Discord server チャンネルにご参加ください!
皆様からのアプリケーションのご応募、お待ちしております!👍
❗️ コンテストに参加された場合、こちらに記載されているコンテスト規約に同意したものとみなされます。ご応募の際、ご一読いただきますよう、お願い申し上げます❗️
ご応募方法について
以下の応募方法ビデオをご参照ください。
以下、コンテストに応募する迄の手順をご説明します。
コンテスト応募までの流れは以下の通りです(※ビデオでは、3番以降の内容をご紹介しています)。
1、IRISプログラミングコンテスト用テンプレートを使用して、開発環境を準備します。
2、コンテスト用アプリケーションを作成します。
3、コンテストの準備が完了したら、ソースコードをローカルのGitリポジトリへコミットします。
初回コミット時に、Gitの初期設定がないためコミットが失敗することがあります。その場合は、以下のコマンドでGitユーザ名とEmailを設定します。
git config --global user.name "ここにユーザ名"
git config --global user.email "ここにメールアドレス”
4、ローカルのGitリポジトリのコミットが完了したら、リモートのGitリポジトリを作成します。
リポジトリ作成後、リモートリポジトリのURLをコピーします。
5、リモートのGitリポジトリへPushします。
git push ここにリモートのリポジトリのURL
6、OpenExchangeにログインし、アプリケーションを追加します。
※事前にDeveloper communityでユーザアカウントを作成する必要があります。ログイン後、Profile→Applications から Application をクリックし、4 でコピーしたリモートのGitリポジトリのURLを設定します。
アプリケーションを登録すると、画面右上に「Send Approval」のボタンが表示されるので、クリックします。
再度作成したアプリケーションを開くと、「Apply for Contest」ボタンが表示されるので、クリックすると応募が完了します。
記事
Toshihiko Minamoto · 2020年6月3日
先週、私たちはInterSystems IRIS Data Platformを発表しました。これは、トランザクション、分析、またはその両方に関係なく、あらゆるデータの取り組みに対応する新しい包括的なプラットフォームです。 CachéとEnsembleでお客様が慣れ親しんでいる多くの機能が取り込まれていますが、この記事では、プラットフォームの新機能の1つであるSQLシャーディングについてもう少し詳しく説明します。これはスケーラビリティに関する強力な新機能です。
ちょうど4分41秒の時間がある方は、スケーラビリティに関するこちらの詳しい動画をご覧ください。 ヘッドホンがない方や聞き心地の良いナレーションが同僚の方の迷惑になると思う方は、どうぞ読み進めてください!
スケールアップとスケールアウト
1日に何百万件という株取引を処理する場合でも、1日に数万人の患者を治療する場合でも、このような業務を支えているデータプラットフォームは、こういった大きなスケールに透過的に対処できなければなりません。 「透過的に」というのは、プラットフォームがスケーリングの面を請け負い、開発者やビジネスユーザーは処理量を気にすることなく、それぞれが専門とする業務とアプリケーションに専念することができるという意味です。
長年にわたり、Cachéは垂直スケーラビリティをサポートしてきました。ハードウェアの進歩がソフトウェアによって透過的に利用され、非常に高いコア数と大量のRAMを効率的に活用したスケーラビリティです。 これは「スケールアップ」と呼ばれており、十分なサイジングの取り組みをあらかじめ行うことで、均衡のとれた完璧なシステムを得る一方で、単一のシステムでコスト効率よく達成できることには固有の制限があります。
そして、そこに水平スケーラビリティが登場します。ワークロードが単一のサーバーではなく、クラスタで稼働する複数の個別のサーバーに分散される方法です。 Cachéは、すでにしばらくの間、スケールアウトの手段としてECPアプリケーションサーバーをサポートしてきましたが、InterSystems IRISは、SQLシャーディングも追加しました。
何が新しいのか?
では、ECPアプリケーションサーバーと新しいシャーディング機能の違いは何でしょうか。 これらの違いを理解するために、ワークロードを詳しく見てみましょう。 ワークロードは、数万個の小さなデバイスが小さなバッチのデータを連続的にデータベースに書き込む処理で構成されたり、少数のアナリストが一度に数ギガバイトのデータにまたがる分析クエリを発行する処理で構成されていたりします。 どちらの規模が大きいでしょうか。 これは、釣り竿とビール樽のどちらが大きいかを答えるくらいわかりにくいものです。 ワークロードには複数の次元があるため、これらをサポートするためのスケーリングには、もう少し微妙さが必要です。
大まかに単純化して、アプリケーションワークロード内の次のコンポーネントについて考えてみましょう。Nはユーザーワークロード、Qはクエリサイズを表します。 前の例では、最初のワークロードのNが高くてQが低く、後者ではNが低くてQが高くなっています。ECPアプリケーションサーバーではアプリケーションユーザーを様々なサーバーに分割できるため、大きなNをサポートするのに非常に適しています。 しかし、データセットが非常に大きくなり、ワーキングセットが単一マシンのメモリに収まらなくなると、それほど役に立つとは限りません。 シャーディングは大きなQに対処し、サーバー間でデータセットを分割できるようにします。作業も可能な限りシャードサーバーに押し込まれます。
SQLシャーディング
では実際のところシャーディングは何を行うのでしょうか。 これは、シャーディングされたテーブルのデータをシャードサーバーに格納されるばらばらのセットの行に分割するSQL機能です。 シャードマスターに接続すると、このテーブルはすべてのデータを含む1つのテーブルのように見えますが、これに対するクエリはすべてのシャードサーバーに送信されるシャードローカルクエリに分割されます。 そこで、シャードサーバーはローカルに保管されたデータに基づいて結果を計算し、その結果をシャードマスターに送り返します。 シャードマスターはこれらの結果を集計して関連する組み合わせ論理を実行し、アプリケーションに結果を戻します。
このシステムは単純な「SELECT * FROM table」の場合は簡単ですが、並列処理を最大化するために(ほぼ)あらゆるSQLクエリを使用して最大量の作業がシャードにプッシュされるようにその中身には多くのスマートロジックが存在します。 シャードキーにはどの行がどこに保存されるかが定義されており、典型的なクエリパターンを使用できます。 最も重要なのは、JOINされることの多いテーブルが同じキーにシャーディングされる場合、JOINはシャードレベルで解決されるため、求めている高いパフォーマンスを得られるということです。
もちろん、これはシャーディングのほんの一部であり、ほかにもさまざまなことができますが、本質は上に示したとおりで、SQLシャーディングは、InterSystems IRISで作ることのできる非常にスケーラブルな料理がつまったレシピ本の新しい一品と言えます。 ECPアプリケーションサーバーを補完するものであり、データセットのサイズに焦点を当てているため、多くの分析ユースケースに適しています。 ECPアプリケーションサーバーと同様に、アプリケーションに対して完全に透過的であり、非常に具体的なシナリオに対応できるより創造的なアーキテクチャを備えています。
さらなる学習のためのリソース
以下のグローバルサミット2017でのセッションの録画を http://learning.intersystems.com でご覧いただけます。
「What's Lurking in Your Data Lake」スケーラビリティと特にシャーディングに関する技術概要
「We Want More! Solving Scalability」非常にスケーラブルなプラットフォームを必要とする関連ユースケースの概要
新しいプラットフォームのその他の機能については、learning.intersystems.com に掲載のInterSystems IRISのリソースガイドもご覧ください。 特定のユースケースでシャーディングを試してみるには、http://www.intersystems.com/iris をご覧ください。ページの下にあるフォームに必要事項をご入力の上アーリーアダプタープログラムにお申込みいただくか、今年後半に公開予定のフィールドテストバージョンをご期待ください。
記事
Toshihiko Minamoto · 2020年7月14日
誓約
開放的で友好的な環境を促進するために、貢献者および管理者として、年齢、体格、障害、民族、性別のアイデンティティと表現、経験のレベル、国籍、外見、人種、宗教、または性的なアイデンティティと志向に関係なく、すべての人に対してInterSystems 開発者コミュニティへの参加についてハラスメントがないようにすることを誓います。
基準
肯定的な環境づくりに貢献する行動の例としては、以下のようなものがあります。
友好的な、包容力のある言葉を使う
異なる視点や経験を尊重すること
建設的な批判を快く受け入れる
コミュニティにとって何が一番いいのかを重視する
コミュニティの他のメンバーへの共感を示す
参加者による容認できない行動の例としては、以下のようなものがあります。
性的な言葉やイメージの使用、歓迎されない性的な注意や誘い。
荒らし、侮辱的/嘲笑的なコメント、個人的または政治的な攻撃
公私のハラスメント
物理的または電子的なアドレスなど、他人の個人情報を明示的な許可なく公開すること。
その他、職業上不適切と合理的に考えられる行為
私たちは、インターシステムズのデータ・プラットフォームの動作や機能に関するあらゆる主張や評価を受け入れますが、インターシステムズのいかなる部署や従業員による行為やサービスレベルについて、受け入れたり、議論することはありません。
責任
プロジェクトメンテナは、受け入れられる行動の基準を明確にする責任があり、受け入れられない行動があった場合には、適切かつ公正な是正措置をとることが期待されています。
プロジェクトメンテナは、この行動規範に沿っていないコメント、コミット、コード、wiki編集、問題、その他の投稿を削除、編集、拒否したり、不適切、脅迫的、攻撃的、有害と判断したその他の行動に対して、一時的または恒久的に投稿者を追放する権利と責任を有します。
範囲
この行動規範は、community.intersystems.com、es.community.intersystems.com、jp.community.intersystems.com、およびopenexchange.intersystems.comに掲載されているInterSystems Developers Communityへの公的な貢献に適用されます。コミュニティの代表は、InterSystems開発者コミュニティの管理者によってさらに定義され、明確にされることがあります。
施行
虐待、嫌がらせ、その他の容認できない行為があった場合は、jpcommunity@intersystems.comのプロジェクトチームに連絡して報告することができます。コミュニティチームは、すべての苦情を検討、調査し、状況に応じて適切と思われる方法で対応します。コミュニティチームは、事件の報告者に関して守秘義務を負います。具体的な実施方針の詳細については、別途掲載する場合があります。
行動規範を誠実に守らない、または施行しないInterSystems開発者コミュニティのメンバーは、コミュニティ管理の他のメンバーによって決定される一時的または恒久的な措置を実施する可能性があります。
帰属
この行動規範は、http://contributor-covenant.org/version/1/4 で入手可能なコントリビューター規約のバージョン 1.4 を参考にしています。