クリアフィルター
記事
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部: ロギング
記事
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でウェブインターフェースを簡単に開発できるようになることを願っています。
追伸 最後までお読みいただき、ありがとうございました!