ステップ7. iiiFN08サーバーのデータベース・ロジックとSET機能をコード化する

LANSA Integrator

ステップ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