4D v14SPベースのサービス (例題) |
||||||||||
|
4D v14
SPベースのサービス (例題)
|
値 | 説明 |
1 | リクエストは送られたが、まだ処理されていない。 |
0 | リクエストは正常に処理された。 |
< 0 | リクエストは処理されたが、エラーが発生した。 |
Note: これらの値は、この例題のため任意に選ばれたものであり、4D から与えられた値ではありません。
クライアントプロセスとストアドプロシージャの間の通信はGET PROCESS VARIABLE、SET PROCESS VARIABLE、VARIABLE TO VARIABLEコマンドを使用して実現できます。SPベースの読み込み (例題)の節や、前述のSTOP SP SERVICESプロジェクトメソッドで使用したソリューションがこの例です。
今回の場合は、ストアドプロシージャがさまざまな量のデータを送受信できるようにシステムが設定されていなければなりません。テキスト配列やピクチャ配列等の配列を使用することもできますが、次の2つの理由からテーブルを使用します:
Client post request プロジェクトメソッドは、リクエストを送るための汎用的なメソッドです:
` Client post request プロジェクトメソッド
` Client post request ( String { ; Text } ) -> Long
` Client post request ( Request type { ; Parameters } ) -> Request ID
CREATE RECORD([SP Requests])
[SP Requests]reqID:=Sequence number([SP Requests])
[SP Requests]reqType:=$1
[SP Requests]reqStatus:=1
If(Count parameters>=2)
[SP Requests]reqParams:=$2
End if
SAVE RECORD([SP Requests])
$0:=[SP Requests]reqID
このメソッドからリクエストID 番号が返されますが、Sequence numberコマンドを使用することにより、この番号は必ずユニークになります。レコードが[SP Requests]テーブルに追加された後、クライアントはフィールド[SP Requests]reqStatus を調べ、ストアドプロシージャが完全にリクエストを処理するまで待機します。
Client get resultプロジェクトメソッドは、リクエストステータスを調べるための汎用的なメソッドです。前述したように、[SP Requets]redStatusフィールドが1以外の値になるとすぐに、クライアントはストアドプロシージャがリクエストを処理したことが (成功しても失敗しても) 分かります。
` Client get result プロジェクトメソッド
` Client get result ( Long ; ->BLOB {; Long } ) -> Long
` Client get result ( Request ID ; ->Data {; Delay } ) -> Error Code
C_LONGINT($0;$1;$vlDelay)
$0:=1
$vlDelay:=0
If(Count parameters>=3)
$vlDelay:=$3
End if
READ ONLY([SP Requests])
Repeat
QUERY([SP Requests];[SP Requests]reqID=$1)
If(Records in selection([SP Requests])>0)
If([SP Requests]reqStatus?#?1)
$2->:=[SP Requests]reqData
READ WRITE([SP Requests])
While(Locked([SP Requests]))
DELAY PROCESS(Current process;$vlDelay)
LOAD RECORD([SP Requests])
End while
DELETE RECORD([SP Requests])
$0:=[SP Requests]reqStatus
End if
Else
` リクエストレコードが失われた!
` これは発生すべきではないが、とにかくerrorを-2に設定 (任意の値)
$0:=-2
End if
` リクエストはまだ処理されていない
If($0=1)
WAITING LOOP($vlDelay)
End if
Until($0?#?1)
READ ONLY([SP Requests])
リクエストがストアドプロシージャにより正常に処理された場合、このメソッドはレコードからBLOB へ結果をコピーします (ある場合)。BLOB へのポインタは引数として渡されます。次に、呼び出し元であるメソッドでリクエストタイプに応じ、BLOB データが解析されます。リクエストの処理が終了したら、[SP Requests]レコードの削除を行うのはクライアントである点に注意してください。
小さなWAITING LOOPプロジェクトメソッドは、指定したtick数が経過するまでループします:
` WAITING LOOP Project Method
` WAITING LOOP ( Long )
` WAITING LOOP ( Delay in ticks )
C_LONGINT($1)
$vlStartTicks:=Tickcount
Repeat
IDLE
Until((Tickcount-$vlStartTicks)>=$1)
Reminder: WAITING LOOP プロジェクトメソッドは、クライアントマシンのユーザ環境プロセスからリクエストされた場合でも、必要なだけ時間を待つために使用されています。
SP SERVICESプロジェクトメソッドは、サーバマシン上でストアドプロシージャとして実行されるメソッドです。疑似コードを次に示しますが、総体的なアーキテクチャは簡単です:
“stop” 変数の初期化
以下繰り返す
[SP Requests]reqStatus フィールドが1であるリクエストを検索
リクエストごとに
リクエストのタイプに応じて、サブルーチンを呼び出し、
[SP Requests]reqData フィールドに結果を格納する
リクエストのステータスを変更し、処理の終了をクライアントに通知
リクエストごとの繰り返しここまで
再開始するまで少々の時間停止する
“stop” 変数がTrueになるまで
以下は実際のコードです:
` SP SERVICES プロジェクトメソッド
` ストアドプロシージャの開始
vbStopSPServices:=False
` ストアドプロシージャはテーブルに対し読み書きアクセスを必要としない
READ ONLY(*)
` ただし[SP Requests] テーブルを除く
READ WRITE([SP Requests])
Repeat
` まだ処理していないリクエストを検索
QUERY([SP Requests];[SP Requests]reqStatus=1)
` これらのリクエストをひとつづつ処理
For($vlRecord;1;Records in selection([SP Requests]))
` リクエストレコードがロックされていれば、ロック解除まで待つ
While(Locked([SP Requests]))
` 再試行まで1秒待つ
DELAY PROCESS(Current process;60)
` 読み書きアクセスを試行
LOAD RECORD([SP Requests])
End while
` 処理が成功したと仮定する
[SP Requests]reqStatus:=0
Case of
:([SP Requests]reqType="Server Information")
SP DO SERVER INFORMATION
:([SP Requests]reqType="Volume List")
SP DO VOLUME LIST
:([SP Requests]reqType="Browse Directory")
SP DO BROWSE DIRECTORY([SP Requests]reqParams)
` ...
` 他のリクエストタイプをここに追加可能!
` ...
Else
` 未知のリクエストタイプ, エラー -1を返す (任意の値)
[SP Requests]reqStatus:=-1
End case
` リクエストステータスが1でないようにする
` (サブルーチンが1にしてしまった場合)
If([SP Requests]reqStatus=1)
[SP Requests]reqStatus:=-3
End if
` リクエストレコードを更新
SAVE RECORD([SP Requests])
` 次の未処理レコードに移動
NEXT RECORD([SP Requests])
End for
` 最後に処理したレコードをアンロード
UNLOAD RECORD([SP Requests])
` 再び処理を開始する前に1秒待つ
DELAY PROCESS(Current process;60)
` 停止を指示されるまでループする
Until(vbStopSPServices)
SP SERVICESプロジェクトメソッドは、データベースに新しいサービスを実現するためのテンプレートとして使用することができます。この節では、SP DO SERVER INFORMATIONサブルーチンおよびSP DO VOLUME LISTサブルーチンの詳細について説明します。SP DO BROWSE DIRECTORY ([SP Requests]reqParamsフィールドに納めて送られた引数を引数として取得するサブルーチン) の詳細については、このドキュメントでは説明されていません。
リクエストのタイプによってSP SERVICESプロジェクトメソッドは、結果データを[SP Requests]reqDataフィールドに保存する処理を行うサブルーチンを呼び出します。レコードの保存やリクエストステータスの変更は、SP SERVICESプロジェクトメソッドによって実行されます。
次に示すのはSP DO SERVER INFORMATIONサブルーチンです。このサブルーチンはサーバ関連の情報をBLOB に保存します。別のプロジェクトメソッドを使用して、クライアントマシン上でBLOB データを取り出します。
` SP DO SERVER INFORMATION プロジェクトメソッド
TEXT TO BLOB(Application version(*);[SP Requests]reqData;UTF8 C string)
TEXT TO BLOB(Structure file;[SP Requests]reqData;UTF8 C string;*)
TEXT TO BLOB(Data file;[SP Requests]reqData;UTF8 C string;*)
PLATFORM PROPERTIES($vlPlatform;$vlSystem;$vlMachine)
VARIABLE TO BLOB($vlPlatform;[SP Requests]reqData;*)
VARIABLE TO BLOB($vlSystem;[SP Requests]reqData;*)
VARIABLE TO BLOB($vlMachine;[SP Requests]reqData;*)
次に示すのはSP DO VOLUME LISTサブルーチンです。このサブルーチンは、ボリューム関連の情報をBLOB に保存します。別のプロジェクトメソッドを使用して、クライアントマシン上でBLOB データを取り出します。
` SP DO VOLUME LIST プロジェクトメソッド
VOLUME LIST($asVName)
$vlSize:=Size of array($asVName)
REAL($arVSize;$vlSize)
REAL($arVUsedSpace;$vlSize)
REAL($arVFreeSpace;$vlSize)
For($vlElem;1;$vlSize)
VOLUME ATTRIBUTES($asVName{$vlElem};$arVSize{$vlElem};$arVUsedSpace{$vlElem}
;$arVFreeSpace{$vlELem})
End for
VARIABLE TO BLOB($asVName;[SP Requests]reqData)
VARIABLE TO BLOB($arVSize;[SP Requests]reqData;*)
VARIABLE TO BLOB($arVUsedSpace;[SP Requests]reqData;*)
VARIABLE TO BLOB($arVFreeSpace;[SP Requests]reqData;*)
汎用的なClient post requestとClient get resultプロジェクトメソッドを使用して、M_SERVER_INFORMATIONプロジェクトメソッドはストアドプロシージャより返されたサーバ情報をクライアントマシン上に表示します。このメソッドは、メニューに割り当てる、あるいはボタンのオブジェクトメソッドで呼び出してもいいでしょう。
` M_SERVER_INFORMATION
C_BLOB(vxData)
C_LONGINT($vlReqID;$vlErrCode;$vlOffset)
` リクエストを送信
$vlReqID:=Client post request("Server Information")
` リクエストステータスを見て、結果を取得
$vlErrCode:=Client get result($vlReqID;->vxData;60)
` リクエストが正しく処理されていれば、結果を表示
If($vlErrCode=0)
` BLOBから情報を取り出し
$vlOffset:=0
vsServerVersion:=BLOB to text(vxData;UTF8 C string;$vlOffset)
vsStructureFile:=BLOB to text(vxData;UTF8 C string;$vlOffset)
vsDataFile:=BLOB to text(vxData;UTF8 C string;$vlOffset)
BLOB TO VARIABLE(vxData;$vlPlatform;$vlOffset)
BLOB TO VARIABLE(vxData;$vlSystem;$vlOffset)
BLOB TO VARIABLE(vxData;$vlMachine;$vlOffset)
` プラットフォームプロパティを解析
vs4DPlatform:="Unknown 4D Server Version"
vsSystem:="Unknown System Version"
vsMachine:="Unknown Machine"
`...
` $vlSystem と $vlMachineを取得するコードをここに記述
` (PLATFORM PROPERTIES コマンドの例題参照)
` ...
` 結果を表示
DIALOG([SP Requests];"SERVER INFORMATION")
Else
ALERT("Request error "+String($vlErrCode))
End if
` BLOBは必要ない
CLEAR VARIABLE(vxData)
以下は実行された[SP Requests];"SERVER INFORMATION"フォームです:
汎用的なClient post requestとClient get resultプロジェクトメソッドを使用して、M_SERVER_INFORMATIONプロジェクトメソッドはストアドプロシージャより返されたボリューム一覧をクライアントマシン上に表示します。このメソッドをメニューに割り当てたり、あるいはボタンのオブジェクトメソッドで呼び出してもいいでしょう:
` M_SERVER_VOLUMES
C_BLOB(vxData)
` リクエストを送信
$vlReqID:=Client post request("Volume List")
` リクエストステータスを見て、結果を取得
$vlErrCode:=Client get result($vlReqID;->vxData;120)
` リクエストが正しく処理されていれば、結果を表示
If($vlErrCode=0)
` BLOBから情報を取り出し
$vlOffset:=0
BLOB TO VARIABLE(vxData;asVName;$vlOffset)
BLOB TO VARIABLE(vxData;arVSize;$vlOffset)
BLOB TO VARIABLE(vxData;arVUsedSpace;$vlOffset)
BLOB TO VARIABLE(vxData;arVFreeSpace;$vlOffset)
For($vlElem;1;Size of array(arVSize))
` バイトをMBに変換
arVSize{$vlElem}:=arVSize{$vlElem}/1048576
arVUsedSpace{$vlElem}:=arVUsedSpace{$vlElem}/1048576
arVFreeSpace{$vlElem}:=arVFreeSpace{$vlElem}/1048576
End for
` 結果を表示
DIALOG([SP Requests];"VOLUME LIST")
Else
ALERT("Request error "+String($vlErrCode))
End if
` BLOBは必要ない
CLEAR VARIABLE(vxData)
以下は実行された[SP Requests];"VOLUME LIST"フォームです:
プロダクト: 4D
テーマ: 4D Serverと4Dランゲージ
4D Server ( 4D v13)
4D Server ( 4D Server v12)
4D Server ( 4D Server v11 SQL Release 6)
4D Server ( 4D v14 R2)
4D Server ( 4D v14)
4D Server ( 4D v14 R3)
4D Server ( 4D Server v14 R4)