cache.node NoSQL メソッドの使用
この章では、基本的概念を紹介し、cache.node とデータベースの接続方法について説明します。以下の項目について説明します。
グローバルと JSON オブジェクトの比較
このセクションでは、Node.js 環境内の JSON オブジェクトと Caché の基本的な関係について説明します。
以下のグローバル・ノードを考えてみます。
^Customer(1)="Jane K. White"
Caché では、規約により、グローバル名の先頭には ^ 文字を付けます。ただし、対応する JSON 表記法ではこの規約に従う必要はありません。
同等の JSON 構成は以下のようになります。
{global: "Customer", subscripts: [1], data: "Jane K. White"}
このデータ構造にノードを追加するには、以下のようにします。
^Customer(1)="Jane K. White"
^Customer(1, "Address", 1)="London"
^Customer(1, "Address", 2)="UK"
^Customer(1, "DateOfRegistration")="1 May 2010"
{ global: "Customer",
subscripts: [1],
data: "Jane K. White"
}
{ global: "Customer",
subscripts: [1, "Address", 1],
data: "London"
}
{ global: "Customer",
subscripts: [1, "Address", 2],
data: "UK"
}
{ global: "Customer",
subscripts: [1, "DateOfRegistration"],
data: "1 May 2010"
}
cache.node メソッド: (同期および非同期)
cache.node によって提供されるすべてのメソッドは、同期または非同期で呼び出すことができます。同期処理は、概念的に理解しやすく、デバッグに役立つ可能性がありますが、Node.js 環境における想定では、すべての処理は、コールバック関数によって発生する完了イベントと非同期に実装されていることになっています。このような理由により、このガイドで示す例の大部分は、非同期に実行されるようにコード化されています。それらを同期的に実行するには、単に引数リストからコールバック関数を削除します。
-
同期処理 — 処理が完了するまで、メソッドは制御を戻しません。
-
非同期処理 — メソッドは即座に制御を戻し、プログラムには処理が完了したときに通知されます。通知を受け取るには、元のメソッド呼び出しにコールバック関数を引数として渡す必要があります。規約により、コールバックは必ずリストの最後の引数にします。
使用している cache.node モジュールのバージョンを判別するメソッドを考えてみます。
同期処理:
var result = mydata.version();
非同期処理:
mydata.version(
function(error, result) {
if (error) { // error
}
else { // success
}
}
);
Node.js におけるエラー報告の標準規約は、cache.node に実装されています。処理が成功した場合は、error は false になります。エラーが発生した場合は、error は true になり、result オブジェクトに、以下の JSON 構造に従った詳細が格納されます。
{
"ErrorMessage": [error message text],
"ErrorCode": [error code],
"ok": [true|false]
}
同期処理の場合、結果オブジェクト内にこれらのプロパティが存在しているか確認して、エラーが発生したかどうかを判別する必要があります。
Caché データベースを開くおよび閉じる
他のメソッドを呼び出すには、その前に cache.node モジュールをロードする必要があり、データ (または Caché 機能) にアクセスする前に、作成した Caché オブジェクトのインスタンスおよびターゲット Caché データベースを開く必要があります。
cache.node モジュールが Node.js インストールの適切な場所にインストールされている場合、既定の場所から以下の行にそれが正常にロードされます。
var cachedb = require('cache');
そのモジュールが別の場所にインストールされている場合、フル・パスを指定する必要があります。以下はその例です。
var cachedb = require('/opt/cm/node0120/build/default/cache');
次のタスクは、cache.node オブジェクトのインスタンスを作成することです。
var mydata = new cachedb.Cache();
Caché に接続する方法は 2 つあります。まず最初に、ローカル Caché インスタンスに API レベルで接続するオプションがあり、2 つ目に、ローカルまたはリモート Caché インスタンスにネットワーク・ベースで接続する方法があります。
Caché API を使用した接続
Caché API を使用して Caché のローカル・インスタンスに接続すると、Node.js と Caché 間の高性能な統合が実現します。
mydata.open(parameters[, function(error, result){}]);
詳細は以下のとおりです。
-
parameters.path — ターゲット Caché インストールの mgr ディレクトリのパス。
-
parameters.username — アクセスするためのユーザ名。
-
parameters.password — アクセスするためのパスワード。
-
parameters.namespace — ターゲット Caché ネームスペース。
mydata.open({ path:"/cache20151/mgr",
username: "_SYSTEM",
password: "SYS",
namespace: "USER"
}
[, function(error, result){}]
);
input_device および output_device プロパティを定義することにより、cache.node セッション用の Caché 入出力主デバイスを指定できます。
mydata.open({ path: '/opt/cache20151/mgr',
username: "_system",
password: "SYS",
namespace: "user",
input_device: "stdin",
output_device: "stdout"}
[, function(error, result){}]
);
既定では、cache.node セッションに対し NULL デバイスを使用します。
ネットワークを使用した Caché への接続
Caché のローカルまたはリモート・インスタンスに接続するには、Caché へのネットワーク・ベース接続を使用できます。この方法は、Node.js がネイティブで提供されていないプラットフォームにインストールされた Caché システムに接続する場合に特に有用です。
また、Node.js が公衆 Web アプリケーションをホストしている場合、Caché へのネットワーク・ベース接続により、データベースが Web サーバ層から物理的に分離した安全なアーキテクチャの基盤が提供されます。
mydata.open(parameters[, function(error, result){}]);
詳細は以下のとおりです。
-
parameters.ip_address — ターゲット Caché インストールのネットワーク名または IP アドレス。
-
parameters.tcp_port — ターゲット Caché インストールのスーパーサーバ TCP ポート。
-
parameters.username — アクセスするためのユーザ名。
-
parameters.password — アクセスするためのパスワード。
-
parameters.namespace — ターゲット Caché ネームスペース。
mydata.open({ ip_address: "127.0.0.1",
tcp_port: 56773,
username: "_SYSTEM",
password: "SYS",
namespace: "USER"
}
[, function(error, result){}]
);
Caché 接続の複数インスタンス
Caché への TCP ベース接続が使用されている場合 (およびその場合のみ)、cache.node モジュールは、ホストする Node.js プロセスごとに Caché クラスの複数インスタンスを作成できます。
var cachedb = require('cache');
var user = new cachedb.Cache();
var samples = new cachedb.Cache();
user.open({ ip_address: "127.0.0.1",
tcp_port: 1972,
username: "_SYSTEM",
password: "SYS",
namespace: "USER",
}
);
samples.open({ ip_address: "127.0.0.1",
tcp_port: 1972,
username: "_SYSTEM",
password: "SYS",
namespace: "SAMPLES",
}
);
console.log("'user' instance in namespace: " + user.get_namespace());
console.log("'samples' instance in namespace: " + samples.get_namespace());
user.close();
samples.close();
Caché API ベース接続が使用されている場合、単一の Node.js プロセスに作成できるのは 1 つのインスタンスのみです。なぜなら、ホストする Node.js プロセスが結合されている Caché 実行可能ファイルは、元来単一スレッドであるためです。ただし、1 つ以上の TCP ベース接続と共に API ベース接続を使用する単一の接続を作成できます。
var cachedb = require('cache');
var user = new cachedb.Cache();
var samples = new cachedb.Cache();
// API based connection to Cache
user.open({ path:"/cache20152/mgr",
username: "_SYSTEM",
password: "SYS",
namespace: "USER",
}
);
// TCP based connection to Cache
samples.open({ ip_address: "127.0.0.1",
tcp_port: 1972,
username: "_SYSTEM",
password: "SYS",
namespace: "SAMPLES",
}
);
console.log("'user' instance in namespace: " + user.get_namespace());
console.log("'samples' instance in namespace: " + samples.get_namespace());
user.close();
samples.close();
Caché データベースへのアクセスのクローズ
以下の方法により、事前に開いた Caché データベースを正常に閉じます。
mydata.close([function(error, result){}]);
オプションの open() 設定
文字エンコードの指定
cache.node で使用される既定の文字エンコードは UTF-8 です。ただし、open() メソッドにこの文字エンコードを定義することにより、16 ビット Unicode (UTF-16) を使用することもできます。
mydata.open({ path:"/cache20151/mgr",
username: "_SYSTEM",
password: "SYS",
namespace: "USER",
charset: "UTF-16"
}
[, function(error, result){}]
);
Caché シリアル化ロックの無効化
Caché プロセスは元来単一スレッドです。Node.js 環境内で非同期に発生したイベントは、複数スレッドを使用して、単一プロセスのコンテキスト内で並行してタスクを実行します。そのため、すべての Caché 処理 (cache.node を使用して呼び出し) にシリアル化ロックを適用することで、関連する Caché プロセスに一度に 1 つのコマンドのみが送信されるようにします。
ただし、ロックは高コストです。Node.js アプリケーションが Caché に一度に 1 個のタスクのみを送信することが確認できる場合、パフォーマンス強化のために、open() メソッドでシリアル化ロックを無効化できます。cache.node メソッドが非同期に使用される場合には、ロックを無効化してはなりません。(cache.node メソッドに関して) 常に同期モードが使用されていても、同期的に発生した Caché の呼び出しが、アプリケーションの別の箇所で非同期的に発生しているイベントの結果と重複する可能性がないことを確認する必要があります。疑わしい場合、ロックは有効のままにしてください。ロックが無効な状態でアプリケーション・クラッシュが発生した場合、問題診断の最初の段階でロックを再有効化してください。
mydata.open({ path:"/cache20151/mgr",
username: "_SYSTEM",
password: "SYS",
namespace: "USER",
lock: 0
}
[, function(error, result){}]
);
デバッグ・モードの有効化
cache.node モジュールには、問題発生時にデバッグを容易に行うためのトレース機能が組み込まれています。このトレースは、Caché コールイン API へのすべての呼び出し、使用された入力引数、返された結果を記録します。TCP ベースの接続が使用されている場合、トレースは、送信されたすべての要求バッファと Caché から受け取った応答バッファを記録します。
トレース機能を有効にするには、open() メソッドの debug プロパティを定義します。
mydata.open({ path:"/cache20151/mgr",
username: "_SYSTEM",
password: "SYS",
namespace: "USER",
debug: 1
}
[, function(error, result){}]
);
mydata.open({ path:"/cache20151/mgr",
username: "_SYSTEM",
password: "SYS",
namespace: "USER",
debug: "debug.log"
}
[, function(error, result){}]
);
Node.js コード:
var cachedb = require('cache');
var mydata = new cachedb.Cache();
mydata.open({ path:"/opt/cache20151/mgr",
username: "_SYSTEM",
password: "SYS",
namespace: "USER"
debug: "debug.log",
});
mydata.set("Person", "1", "Jane K. White");
var data = mydata.get("Person ", 1));
mydata.close();
これにより、以下の (ような) トレースが作成されます。
>>> 000007FEF9E39340==fopen(debug.log, "a")
(Debug trace file opened)
>>> cache_open
>>> 0000000180000000==sys_dso_load(
/opt/cache20151/bin/libcache.so)
>>> 0==CacheSetDir(/opt/cache20151/mgr)
>>> 0==CacheSecureStartA(0000000000126CC0(_SYSTEM),
0000000000116CA0(SYS),
000000000010EC90(Node.JS), 56, 15,
0000000000106C80(//./nul), 000000000012ECD0(//./nul))
>>> cache_set
>>> 0==CachePushGlobal(6, Person)
>>> 00000000269E7010==CacheExStrNew(000000002682D770, 2)
>>> 0==CachePushExStr(000000002682D770)
>>> 1
>>> 00000000269E7010==CacheExStrNew(000000002682D788, 11)
>>> 0==CachePushExStr(000000002682D788)
>>> Jane K. White
>>> 0==CacheGlobalSet(1)
>>> 0==CacheExStrKill(000000002682D770)
>>> 0==CacheExStrKill(000000002682D788)
>>> cache_get
>>> 0==CachePushGlobal(6, Person)
>>> 00000000269E7010==CacheExStrNew(000000002682D770, 2)
>>> 0==CachePushExStr(000000002682D770)
>>> 1
>>> 0==CacheGlobalGet(1, 0)
>>> 0==CachePopExStr(000000000013F410)
>>> 0==CacheExStrKill(000000000013F410)
>>> Jane K. White
>>> 0==CacheExStrKill(000000002682D770)
>>> cache_close
>>> 0==CacheEnd()
割り込みシグナル・ハンドラの指定
cache.node モジュールには、Caché に接続された Node.js プロセスのクリーン割り込みを簡易にする、オプションのシグナル・ハンドラが組み込まれています。実際は、この機能に頼らずに、アプリケーションの JavaScript コードに適切な終了シグナル・ハンドラを組み込むのが最適な方法です。
例えば、JavaScript コードで SIGINT シグナル (Control-C) に応答するには、以下のようにします。
process.on( 'SIGINT', function() {
// clean up and close down gracefully
});
このようなアプリケーション・レベルのシグナル・ハンドラがない場合には、cache.node モジュールに、独自の終了シグナル・ハンドラを登録するように指示できます。open() メソッドの stop_signal プロパティを使用して、シグナル SIGINT または SIGTERM (またはその両方) を受け取ったら cache.node が実行を終了するように指定します。
例えば、シグナル SIGINT または SIGTERM を受け取ったら Node.js プロセスをクローズするように cache.node に指示するには、以下のようにします。
user.open({path: "/cache20163/mgr",
username: "_SYSTEM",
password: "SYS",
namespace: "USER",
stop_signal: "SIGINT,SIGTERM"
}
);
cache.node モジュールに実装されたシグナル・ハンドラは、Caché への接続のクローズとホスト Node.js プロセスの停止のみを行います。
ユーティリティ関数
Node.js 処理の一時停止: sleep()
Node.js アプリケーション (特に非同期完了の手法を多用するアプリケーション) をトラブルシューティングするときには、多くの場合、関数を一時停止すると便利です。cache.node モジュールには、引数で定義された一定時間 (ミリ秒単位)、現在の実行スレッドを一時停止する sleep() メソッドが組み込まれています。
mydata.sleep(5000);
この機能はトラブルシューティングのみに使用してください。なぜなら Node.js は、メイン実行スレッドをブロックする処理はなしという原則に従って構築されているためです。
バージョン情報の取得: version() および about()
version() および about() メソッドは、使用している cache.node モジュールとそれに関連する Caché データベース (開いている場合) に関する基本的なバージョン情報を返します。
同期:
var result = mydata.version();
または
var result = mydata.about();
非同期:
mydata.version(function(error, result){});
または
mydata.about(function(error, result){});
mydata.version(
function(error, result) {
if (error) { // error (see result.ErrorMessage and result.ErrorCode)
}
else { // success
}
}
);
結果:
Caché データベースが開いていない場合:
Node.js Adaptor for Cache: Version: 1.1.112 (CM)
Caché データベースが開いている場合:
Node.js Adaptor for Cache: Version: 1.1.112 (CM); Cache Version: 2016.3 build 168
Caché 関数の呼び出し: function()
Caché 環境に含まれる関数は、function() メソッドを使用して直接呼び出すことができます。
同期:
var result = mydata.function(cache_function);
非同期:
var result = mydata.function(cache_function, function(error, result){});
このセクションの例は、以下の Caché ルーチンの呼び出しを基にしています。
Math ; Math Functions
;
Add(X,Y) ; Add two numbers
Quit (X * Y)
;
Multiply(X,Y) ; Add two numbers
Quit (X * Y)
;
これは、基本的な算術関数 (Add や Multiply) を実行する関数を含む Math と呼ばれる単純な Caché ルーチンです。
result = mydata.function("Add^Math", 3, 4);
結果: 7
result = mydata.function({function: "Add^Math", arguments: [3, 4]},
結果:
{
"function": "Add^Math",
"arguments": [3, 4],
"result": 7
}
mydata.lock(
{function: "Add^Math", arguments: [3, 4]},
function(error, result) {
if (error) { // error (see result.ErrorMessage and result.ErrorCode)
}
else { // success
}
}
);
結果:
{
"ok": 1
"function": " Add^Math ",
"arguments": [3, 4],
"result": 7
}