ステップ7. iiiFN08サーバーのデータベース・ロジックとSET機能をコード化する
このステップでは、論理ビューPSLMST1 (部門ごとの人材)を使用して社員リストを取得するSELECTと、データベース・ファイルPSLSKL (人材スキル)で社員のスキル・リストを取得するSELECTを実行するRDMLXを作成します。サーバー側SETのRDMLXは、この内部ロジック中にインラインで行われます。これは、内部ロジックとSETコマンドが順に分けられていた以前の演習とは異なります。
この演習では、内部ロジックの終了後、各コマンドを順番に実行しません。代わりに、アウトバウンドBINDとルート・フラグメントSETが、インバウンドBINDコマンドとGETコマンドの直後に来ます(データベース・アクセスの前)。さらに2つのSETコマンドが、外部のSELECTステートメントに入ります。最後に、WRITEコマンドとSENDコマンドが最後のENDSELECTの後に続きます。
iiiFN08ファンクションの構造全体は以下のようになります。
1. JSMX_OPEN 2. SERVICE_LOAD (HTTPInboundXMLBindService) 3. BIND (インバウンド) 4. GET (部門コードのフラグメント) 5. BIND (アウトバウンド) 6. SET (社員リストのフラグメント) 7. PSLMST1に対するSELECT |
a. PSLSKLに対するSELECT b. SKLTABからのFETCH c. ENDSELECT d. SET (社員のフラグメント) e. SET (社員のスキル・リスト) |
8. ENDSELECT 9. WRITE 10. SEND 11. JSMX_CLOSE |
1. ファンクションiiiFN08で、以下のコードを探して削除します。
* Bind service to create HTTP response content
CHANGE
FIELD(#JSMXCMD) TO('BIND SERVICE( <<<outbound.class>>> )
TYPE(*OUTBOUND)')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD)
TO_GET(#JSMXSTS #JSMXMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS
#JSMXMSG)
2. スタジオでiii Trainingプロジェクトが開いている状態で、Server XML Employees Response/samples/RDMLX/SAMPLE_RDMLX_OUTBOUND_HTTP.txtファイルをテキスト・エディタで開きます。強調表示されたコードを探します。
強調表示されたコードをコピーしてファンクションに貼り付け、削除されたコード・ブロックを置き換えます。
3. EMPWORKという作業リスト定義を、フィールドSKILDESCを含むファンクションの上部に追加します。これは、返される各社員のスキル・リストです。コードは以下のようになります。
DEF_LIST NAME(#EMPWORK) FIELDS(#SKILDESC)
TYPE(*WORKING) ENTRYS(9999)
4. アウトバウンドBINDとSETロジックを追加したら、以下の操作を行うRDMLXコードを作成します。
a. DEPTMENTキー・フィールドを使用して、論理ファイルPSLMST1から社員の番号と名前を選択(SELECT)します。
b. SELECT内部で、姓名をFull Nameフィールドに連結します。
c. SELECTループ内で、PSLSKLに対してSELECTを実行し、社員番号を使用して各社員のスキル・コードのリストを取得します。
d. 内部の(ネストされた) SELECT内で、各スキル・コードについてSKLTABからスキル記述を取得(FETCH)します。
e. 社員のスキル作業リストEMPWORKにエントリーを追加(ADD)します。このリストは、ファンクション上部のSKILDESCフィールドで定義します。
f. 両方のSELECTを終了します。
RDMLXコードは以下のように表示されます。
SELECT FIELDS(#EMPNO #SURNAME #GIVENAME) FROM_FILE(PSLMST1) WITH_KEY(#DEPTMENT)
#FULLNAME := #GIVENAME + ' ' + #SURNAME
CLR_LIST NAMED(#EMPWORK)
SELECT FIELDS(#SKILCODE) FROM_FILE(PSLSKL) WITH_KEY(#EMPNO)
FETCH FIELDS(#SKILDESC) FROM_FILE(SKLTAB) WITH_KEY(#SKILCODE)
ADD_ENTRY TO_LIST(#EMPWORK)
ENDSELECT
* Set employee fragment
* Set employeeskills list
ENDSELECT
注:次のステップで明確になるように、コメントがこのコードに追加されています。
5. 以前と同様に、SAMPLE_RDMLX_OUTBOUND_HTTP.txtファイルで生成されたコードを使用してファンクションを終了します。強調表示されたコードを探します。
6. 上記の強調表示されたコードをファンクションにコピーして、ステップ4fのコメントを置き換えます。
* Set employee fragment
* Set employeeskills list
7. リスト#EMPWORKを参照するように、TO_GET()キーワードの作業リスト名を変更します。コードは以下のようになります。
*set list - EMPLOYEESKILL
CHANGE FIELD(#JSMXCMD) TO('SET LIST(EMPLOYEESKILL)')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG #EMPWORK)
8. ファンクションのRDMLXコードと、その後に続く最後のENDSELECTを確認します。最初にコピーした生成済みコードに、必要なWRITE、SEND、CLOSEロジックが含まれています。
9. CHECKサブルーチンで、エラーが発生した場合はプログラムが終了するようにABORTコマンドをIF..ENDIFステートメントに追加します。
10. ファンクションを保存し、コンパイルします。IBM i のJSMサーバーを使用している場合は、ファンクションをIBM i に登録してコンパイルします。
完了したRDMLXコードは以下のように表示されます。
FUNCTION OPTIONS(*DIRECT)
* The following fields are used by the XMLバインディング
map
* #DEPTMENT
* The following fragments are used by the XMLバインディング
map
GROUP_BY NAME(#DEPTREQ) FIELDS(#DEPTMENT)
*
DEF_LIST NAME(#empwork)
FIELDS(#skildesc) ENTRYS(200)
* Open service
USE BUILTIN(JSMX_OPEN)
TO_GET(#JSMXSTS #JSMXMSG #JSMXHDLE1)
EXECUTE SUBROUTINE(CHECK)
WITH_PARMS(#JSMXSTS #JSMXMSG)
* Load service
CHANGE FIELD(#JSMXCMD)
TO('SERVICE_LOAD SERVICE(HTTPInboundXMLBindService) SERVICE_CONTENT(*HTTP)
TRACE(*YES)')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD)
TO_GET(#JSMXSTS #JSMXMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS
#JSMXMSG)
* Bind service to read HTTP request content
CHANGE
FIELD(#JSMXCMD) TO('BIND SERVICE(IIIPRO06_REQUEST) TYPE(*INBOUND)
BINDTRACE(*YES)')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD)
TO_GET(#JSMXSTS #JSMXMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS
#JSMXMSG)
* Get fragment - DEPARTMENTREQUEST
CHANGE FIELD(#JSMXCMD)
TO('GET FRAGMENT(DEPARTMENTREQUEST) SERVICE_EXCHANGE(*FIELD)')
USE
BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS
#JSMXMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
*
Bind service to create HTTP request content
CHANGE FIELD(#JSMXCMD) TO('BIND
SERVICE(IIIPRO06_RESPONSE) TYPE(*OUTBOUND)')
USE BUILTIN(JSMX_COMMAND)
WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
EXECUTE
SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
* Set fragment -
EMPLOYEELIST
CHANGE FIELD(#JSMXCMD) TO('SET FRAGMENT(EMPLOYEELIST)
SERVICE_EXCHANGE(*FIELD)')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1
#JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
EXECUTE SUBROUTINE(CHECK)
WITH_PARMS(#JSMXSTS #JSMXMSG)
SELECT FIELDS(#EMPNO #SURNAME #GIVENAME)
FROM_FILE(PSLMST1) WITH_KEY(#DEPTMENT)
#FULLNAME := #GIVENAME + ' ' +
#SURNAME
CLR_LIST NAMED(#EMPWORK)
SELECT FIELDS(#SKILCODE)
FROM_FILE(PSLSKL) WITH_KEY(#EMPNO)
FETCH FIELDS(#SKILDESC) FROM_FILE(SKLTAB)
WITH_KEY(#SKILCODE)
ADD_ENTRY TO_LIST(#EMPWORK)
ENDSELECT
* Set
fragment - EMPLOYEE
CHANGE FIELD(#JSMXCMD) TO('SET FRAGMENT(EMPLOYEE)
SERVICE_EXCHANGE(*FIELD)')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1
#JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG)
EXECUTE SUBROUTINE(CHECK)
WITH_PARMS(#JSMXSTS #JSMXMSG)
* Set list - EMPLOYEESKILL
CHANGE
FIELD(#JSMXCMD) TO('SET LIST(EMPLOYEESKILL)')
USE BUILTIN(JSMX_COMMAND)
WITH_ARGS(#JSMXHDLE1 #JSMXCMD) TO_GET(#JSMXSTS #JSMXMSG #EMPWORK)
EXECUTE
SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS #JSMXMSG)
ENDSELECT
* Write
content
CHANGE FIELD(#JSMXCMD) TO('WRITE INDENT(*YES)
BINDTRACE(*YES)')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD)
TO_GET(#JSMXSTS #JSMXMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS
#JSMXMSG)
* Send HTTP response content
CHANGE FIELD(#JSMXCMD)
TO('SEND')
USE BUILTIN(JSMX_COMMAND) WITH_ARGS(#JSMXHDLE1 #JSMXCMD)
TO_GET(#JSMXSTS #JSMXMSG)
EXECUTE SUBROUTINE(CHECK) WITH_PARMS(#JSMXSTS
#JSMXMSG)
* Close service
USE BUILTIN(JSMX_CLOSE)
WITH_ARGS(#JSMXHDLE1) TO_GET(#JSMXSTS #JSMXMSG)
EXECUTE SUBROUTINE(CHECK)
WITH_PARMS(#JSMXSTS #JSMXMSG)
* Check routine
SUBROUTINE NAME(CHECK)
PARMS((#JSMXSTS *RECEIVED) (#JSMXMSG *RECEIVED))
IF COND('#JSMXSTS *NE
OK')
USE BUILTIN(JSMX_CLOSE) WITH_ARGS(#JSMXHDLE1) TO_GET(#JSMXSTS
#JSMXMSG)
ENDIF
ENDROUTINE