C400

147. QUSLRCDを使わないレコード名検索

ファイルのレコード名を検索するには
毎度、API;QUSLRCDを使うのが一般的で
IBM のAPIの紹介でもレコード名の検索APIは
QUSLRCD としか紹介されていない。
_

しかしQUSLRCDを使ってファイルのレコード名を
検索するには
(1) ユーザー・スペースを作成する
(2) API: QUSLRCDを使ってレコード名を
ユーザー・スペースに出力する
(3) ユーザー・スペースをAPI; QUSRTVUSを
使って読み取る。

という3段階の手順が必要である。
一般のIBMユーザーが使うのであれば
面倒でもこの方法でよいのだが
ソフトウェア製品の一部にレコード検索が必要と
なった場合にパフォーマンスが要求される製品に
このようなユーザー・スペースを作るような
パフォマンス低下を招くような仕組みを採用することは
できない。
やはりAPIだけによる検索でパフォーマンスの良い検索を
行いたい。

そこで調べたのがここに紹介するAPI: QDBRTVFD を
使った方法である。

API : QDBRTVFDはデータ・ベースの構造体を調べるための
莫大な構造を持つAPIである。
その中の ファイルスコープ配列 の中にデータ・ベースの
レコード名が記述されているのでこれを使うと
APIだけでレコード名を検索することができるようになる。

[ TESTRCD: レコード名の検索テスト]

ソースはこちらから

0001.00 #include                                                          
0002.00 #include                                                         
0003.00 #include                                                         
0004.00 #include  /* triml */                                          
0005.00 #include   /* データ・ベース検索 API */                        
0006.00                                                                            
0007.00 #define TRUE         0                                                     
0008.00 #define FALSE       -1                                                     
0009.00                                                                            
0010.00 typedef struct {                                                           
0011.00    int  BYTESPRO;                                                          
0012.00    int  BYTESAVL;                                                          
0013.00    char MSGID[7];                                                          
0014.00    char RESRVD;                                                            
0015.00    char EXCPDATA[100];                                                     
0016.00 } ERRSTRUCTURE;     /* Define the error return structure            */     
0017.00 ERRSTRUCTURE  errcode;/* Error Code Structure for RCVMSG      */           
0018.00                                                                            
0019.00 void main(void){                                                           
0020.00    char FILFILLIB[21], RECORD[11];                                         
0021.00   int  format_size, fldsu, fldbuf_len, i, j, len;                          
0022.00   char* formatBuf;                                                         
0023.00   Qdb_Qdbfh_t  qdb_qdbfh_t;                                                
024.00   Qdb_Qdbfh_t* qdb_qdbfh;       /* ファイル定義ヘッダー */                          
025.00   Qdb_Qdbfb_t* qdb_qdbfb;       /* ファイルスコープ配列 */                          
026.00                                                                                     
027.00    errcode.BYTESPRO = 0;                                                            
028.00    printf("** TESTRCD:  レコード名の検索テスト **n");                              
029.00    getchar();                                                                       
030.00    strcpy(FILFILLIB, "SEIKYU    QTRFIL    ");                                       
031.00   QDBRTVFD(&qdb_qdbfh_t, sizeof(Qdb_Qdbfh_t), FILFILLIB, "FILD0100",                
032.00             FILFILLIB, "*FIRST    ", "0", "*FILETYPE ", "*EXT      ", &errcode);    
033.00   if(errcode.BYTESAVL != 0){/*ERR*/                                                 
034.00     printf("QDBRTVFD エラー n");                                                   
035.00     exit(-1);                                                                       
036.00   }/*ERR*/                                                                          
037.00   format_size = qdb_qdbfh_t.Qdbfyavl;                                               
038.00   formatBuf = (char*)malloc(format_size + 1);                                       
039.00   QDBRTVFD((char*)formatBuf, format_size, FILFILLIB, "FILD0100",                    
040.00           FILFILLIB, "*FIRST    ", "0", "*FILETYPE ", "*EXT      ", &errcode);      
041.00   if(errcode.BYTESAVL != 0){/*ERR*/                                                 
042.00     printf("QDBRTVFD エラー n");                                                   
043.00     exit(-1);                                                                       
044.00   }/*ERR*/                                                                          
045.00   qdb_qdbfh    = (Qdb_Qdbfh_t*)formatBuf;                                           
046.00   qdb_qdbfb    = (Qdb_Qdbfb_t*)((char*)qdb_qdbfh + qdb_qdbfh->Qdbfos);              
047.00   for(i = 0; iQdbflbnum; i++){/*for-loop-i*/                            
0048.00     memcpy(RECORD, qdb_qdbfb->Qdbft, 10);                               
0049.00     RECORD[10] = 0x00;                                                  
0050.00     printf("RECORD = [%s]n", RECORD);                                  
0051.00     getchar();                                                          
0052.00     qdb_qdbfb  = (Qdb_Qdbfb_t*)((char*)qdb_qdbfb + sizeof(*qdb_qdbfb)); 
0053.00   }/*for-loop-i*/                                                       
0054.00   free(formatBuf);                                                      
0055.00   exit(0);                                                              
0056.00 }       


                                                                

[解説]

最初に QDBRTVFD でフォーマット : FILD0100 が必要とする構造体の大きさを調べて
その分の大きさを formatBuf として動的メモリとして確保する。

045.00   qdb_qdbfh    = (Qdb_Qdbfh_t*)formatBuf;                                           
046.00   qdb_qdbfb    = (Qdb_Qdbfb_t*)((char*)qdb_qdbfh + qdb_qdbfh->Qdbfos); 

で qdb_qdbfh; /* ファイル定義ヘッダー */
を取得して
次に qdb_qdbfb; /* ファイルスコープ配列 */
を取得するとこの中の qdb_qdbfb->Qdbft にレコード名が保管されている。
物理ファイルのときはひとつのレコードしか存在していないが
複数の物理ファイルから成る論理ファイルであれば複数のレコードを
含む場合がある。
長年 QUSLRCDを使ってきたがこの方法でレコード名を取得できるようになったのは
製品開発のひとつの進歩である。
_