データベースのオープン毎に処理を CLで行う (Exit プログラム)

ちょっと用があって「データベースのオープン毎に処理を行う (Exit プログラム)」で紹介した DB のオープン時に呼び出される EXIT プログラムをインフォメーションセンターの情報を見ながら CL で改めて書き直してみました。

参照したインフォメーション・センターの情報は↓です。 (V5R4)

http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp?topic=/apis/xopendbf.htm

今回は前回のプログラムを参照できない状況だったので全然ロジック等が異なっていますが、そのあたりは悪しからずご了承くださいませ。

パフォーマンスは RPG などで書いた方がよさそうですが、データベースのオープンというイベントに応じて様々な処理をさせるには CL の方が融通が利きそうでもあります。
たとえば、DELETE に先立ってコピーを強制的に取ってしまうとか、いわばアスペクト指向的にも使えそうな気もします。

ということで、こんなふう↓に書いてみました。

             PGM        PARM(&DATA &RC)                                         
                                                                                
             DCL        VAR(&RC) TYPE(*INT) LEN(4)                              
             DCL        VAR(&DATA) TYPE(*CHAR) LEN(32767)                       
             DCL        VAR(&HDRSIZ) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&DATA 1)                                
             DCL        VAR(&FMTNAM) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(8) DEFVAR(&DATA 5)                                
             DCL        VAR(&ARROFS) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&DATA 13)                               
             DCL        VAR(&FILCNT) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&DATA 17)                               
             DCL        VAR(&ELMLEN) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&DATA 21)                               
             DCL        VAR(&JOBNAM) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(10) DEFVAR(&DATA 25)                              
             DCL        VAR(&USRNAM) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(10) DEFVAR(&DATA 35)                              
             DCL        VAR(&JOBNBR) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(10) DEFVAR(&DATA 45)                              
             DCL        VAR(&CURUSR) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(10) DEFVAR(&DATA 51)                              
             DCL        VAR(&QRYOPN) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(1) DEFVAR(&DATA 61)                               
                                                                                
             DCL        VAR(&ELEMP) YPE(*PTR)                                  
             DCL        VAR(&ELEMSTR) TYPE(*PTR)                                
             DCL        VAR(&ELEM) TYPE(*CHAR) STG(*BASED) LEN(44) +            
                          BASPTR(&ELEMP)                                        
             DCL        VAR(&FILE) TYPE(*CHAR) STG(*DEFINED) LEN(10) +          
                          DEFVAR(&ELEM 1)                                       
             DCL        VAR(&LIB) TYPE(*CHAR) STG(*DEFINED) LEN(10) +           
                          DEFVAR(&ELEM 11)                                      
             DCL        VAR(&MBR) TYPE(*CHAR) STG(*DEFINED) LEN(10) +           
                          DEFVAR(&ELEM 21)                                      
             DCL        VAR(&FILTYP) TYPE(*UINT) STG(*DEFINED) +                
                          LEN(4) DEFVAR(&ELEM 33)                               
             DCL        VAR(&BASPF) TYPE(*UINT) STG(*DEFINED) LEN(4) +          
                          DEFVAR(&ELEM 37)                                      
             DCL        VAR(&READ) TYPE(*CHAR) STG(*DEFINED) LEN(1) +           
                          DEFVAR(&ELEM 41)                                      
             DCL        VAR(&WRITE) TYPE(*CHAR) STG(*DEFINED) LEN(1) +          
                          DEFVAR(&ELEM 42)                                      
             DCL        VAR(&UPDATE) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(1) DEFVAR(&ELEM 43)                               
             DCL        VAR(&DELETE) TYPE(*CHAR) STG(*DEFINED) +                
                          LEN(1) DEFVAR(&ELEM 44)                               
                                                                                
             DCL        VAR(&I) TYPE(*UINT) LEN(4)                              
             DCL        VAR(&OFFSET) TYPE(*UINT) LEN(4)                         
             DCL        VAR(&NEWNAME) TYPE(*CHAR) LEN(10)                       
                                                                                
             CHGVAR     VAR(&ELEMP) VALUE(%ADDR(&DATA))                         
             CHGVAR     VAR(%OFFSET(&ELEMP)) VALUE(%OFFSET(&ELEMP) + +          
                          &ARROFS)                                              
             CHGVAR     VAR(&ELEMSTR) VALUE(&ELEMP)                             
                                                                                
             DOFOR      VAR(&I) FROM(1) TO(&FILCNT)                             
             CHGVAR     VAR(&OFFSET) VALUE((&I - 1) * &ELMLEN)                  
             CHGVAR     VAR(%OFFSET(&ELEMP)) VALUE(%OFFSET(&ELEMSTR) + +        
                          &OFFSET)                                              
                                                                                
             IF         COND(&DELETE = '1') THEN(DO)                            
             IF         COND(&LIB = 'PROD') THEN(DO)                            
             CRTDUPOBJ  OBJ(&FILE) FROMLIB(&LIB) OBJTYPE(*FILE) +               
                          TOLIB(TRASH) DATA(*YES)                               
             MONMSG     MSGID(CPF2130) EXEC(DO)                                 
             CHGVAR     VAR(&NEWNAME) VALUE(&FILE |< '1')                       
             CRTDUPOBJ  OBJ(&FILE) FROMLIB(&LIB) OBJTYPE(*FILE) +               
                          TOLIB(TRASH) NEWOBJ(&NEWNAME) DATA(*YES)              
             ENDDO                                                              
             GOTO       CMDLBL(EXIT)                                            
             ENDDO                                                              
             ENDDO                                                              
                                                                                
             IF         COND(&READ = '1') THEN(DO)                              
             IF         COND(&FILE = 'SECRET') THEN(DO)                         
             IF         COND(&CURUSR = 'USER') THEN(DO)                         
             CHGVAR     VAR(&RC) VALUE(0)                                       
             GOTO       CMDLBL(EXIT)                                            
             ENDDO                                                              
             ENDDO                                                              
             ENDDO                                                              
                                                                                
             ENDDO                                                              
                                                                                
 EXIT:       RETURN                                                             
             ENDPGM

今回は、データベースのオープン時にチェックさせる処理として READ 時と DELETE 時の処理をそれぞれサンプルとして書いてみました。

DELETE 時に別のライブラリーに複製を作ってしまう、というものと、

             IF         COND(&DELETE = '1') THEN(DO)                            
             IF         COND(&LIB = 'PROD') THEN(DO)                            
             CRTDUPOBJ  OBJ(&FILE) FROMLIB(&LIB) OBJTYPE(*FILE) +               
                          TOLIB(TRASH) DATA(*YES)                               
             MONMSG     MSGID(CPF2130) EXEC(DO)                                 
             CHGVAR     VAR(&NEWNAME) VALUE(&FILE |< '1')                       
             CRTDUPOBJ  OBJ(&FILE) FROMLIB(&LIB) OBJTYPE(*FILE) +               
                          TOLIB(TRASH) NEWOBJ(&NEWNAME) DATA(*YES)              
             ENDDO                                                              
             GOTO       CMDLBL(EXIT)                                            
             ENDDO                                                              
             ENDDO                                                              

前回と同様の、特定ユーザーでないとあるテーブルにはアクセスできない、というものの、

             IF         COND(&READ = '1') THEN(DO)                              
             IF         COND(&FILE = 'SECRET') THEN(DO)                         
             IF         COND(&CURUSR = 'USER') THEN(DO)                         
             CHGVAR     VAR(&RC) VALUE(0)                                       
             GOTO       CMDLBL(EXIT)                                            
             ENDDO                                                              
             ENDDO                                                              
             ENDDO                                                              

2 つになっています。

ちなみに、DELETE 時の処理は、同じ名前のものが複製先のライブラリーにあった場合は(一回だけ)別の名前をつけて複製させる、というようになっています。
名前が 10桁あった場合とか二回以上の場合とかの考慮はまた別途工夫してみてください。(ここでの本筋ではないので割愛しました)


プログラムの作成

CRTBNDCL コマンドで ACTGRP(*NEW) を指定してコンパイルします。

登録

WRKREGINF コマンドでの登録方法は前回とまったく同じです。(↑のプログラム名は CHK_DBOPEN としました)

READ 時のアクセス制限

まず前回の実行例と同様の READ 時のアクセス制限から見てみましょう。

STRSQL 画面から実行してみると↓のようなエラーになりました。

ちょっとメッセージが違いますが、OS のバージョンの違いによるものか CL プログラムだからかは今回確認する時間がありませんでした。

ジョブログから見てみると↓のようなメッセージが続けて出されています。
こちらのメッセージに関しては、CPF428E ということで同じになっていますね。

続けて STRSQL の画面で見たものと同じメッセージが出されています。

DELETE 時のコピー取得

今回新たに作ってみた、DELETE が実行された時に別ライブラリにコピーを作るという処理を見てみましょう。

条件にあう DELETE 文を発行してみます。

確認画面が出てきます。
これは STRSQL 画面で DELETE を実行する場合には毎回出てくるものです。

何事もなく終了してしまったように見えますが、、

(プログラムで指定したとおりに)TRASH ライブラリにコピーが取られていることがわかります。

何事もなく実行されてしまったように見えるのはリターンコードに 0 をセットせずに終了しているからですね。

             CHGVAR     VAR(&RC) VALUE(0)    

↑の行を挿入すれば READ 時のアクセス制限の例のようにエラーを返すようになります。

ログ

CHGJOB コマンドで STRSQL を実行しているジョブを LOGCLPGM(*YES) に変更してみましょう。

実行されているのがよくわかりますね。

ちなみに DROP TABLE はあっさりできてしまうので、あしからず。

[Top Pageに戻る]

Ads by TOK2