データベース

43. ファイルがキーつき索引ファイルであるかどうか判断するには? (C言語)

あるデータ・ベース(ファイル)がキーつきの索引ファイルであるか
順次ファイルであるかを判断するのは以外は簡単なことではない。
この判断のためのコマンドはIBMによって用意されていないのと
莫大なAPI: QDBRTVFD に登録があるもののビットで管理されているために
少しはAPIのわかる人でもなかなか判断のビットまで
辿りつけないからである。
_

そこでここではAPI : QDBRTVFD を使ってファイルのキーつきかどうかの
判断する方法とAPIのビットの判断の方法も合わせて解説する。
C言語の苦手な方のためにCLPでの解説も追って紹介する予定である。

[TESTACP: ファイルのキーつきかどうかを判定する ]

ソースはこちらから

0001.00 #include                                                       
0002.00 #include                                                      
0003.00 #include                                                      
0004.00 #include   /* DATABASE API */                               
0005.00                                                                         
0006.00 #define TRUE         0                                                  
0007.00 #define FALSE       -1                                                  
0008.00 typedef struct {                                                        
0009.00    int  BYTESPRO;                                                       
0010.00    int  BYTESAVL;                                                       
0011.00    char MSGID[7];                                                       
0012.00    char RESRVD;                                                         
0013.00    char EXCPDATA[100];                                                  
0014.00 } ERRSTRUCTURE;     /* Define the error return structure            */  
0015.00 ERRSTRUCTURE  errcode;/* Error Code Structure for RCVMSG      */        
0016.00                                                                         
0017.00 void main(void){                                                        
0018.00   char FILE[11], FILLIB[11], FILFILLIB[21], point[24], *formatBuf;      
0019.00   Qdb_Qdbfh_t  qdb_qdbfh_t;   /* ファイル定義ヘッダー */                
0020.00   Qdb_Qdbfh_t* qdb_qdbfh;     /* ファイル定義ヘッダー */                                        
0021.00   Qdb_Qdbfhflg_t* qdb_qdbfhflg;  /*標識構造体 */                                       
0022.00   int res, format_size;                                                 
0023.00                                                                         
0024.00   printf("** TESTACP: キーつきかどうか判断する **n");                          
0025.00   getchar();                                                                    
0026.00                                                                                 
0027.00   errcode.BYTESAVL = 0;                                                         
0028.00   errcode.BYTESPRO = sizeof(errcode);                                           
0029.00   strcpy(FILFILLIB, "SEQTRN    QTRFIL    ");                                    
0030.00   QDBRTVFD(&qdb_qdbfh_t, sizeof(Qdb_Qdbfh_t), FILFILLIB, "FILD0200",            
0031.00             FILFILLIB, "*FIRST    ", "0", "*FILETYPE ", "*EXT      ", &errcode);
0032.00   if(errcode.BYTESAVL != 0){/*ERR*/                                             
0033.00       printf("TESTACP[%d] QBRTVFD のエラー n", __LINE__);                      
0034.00       getchar();                                                                
0035.00       exit(-1);                                                                 
0036.00   }/*ERR*/                                                                      
0037.00   else{/* 長さの取得は成功 */                                                   
0038.00     format_size = qdb_qdbfh_t.Qdbfyavl;                                         
0039.00     formatBuf = (char*)malloc(format_size + 1);                                 
0040.00     QDBRTVFD((char*)formatBuf, format_size, FILFILLIB, "FILD0100",              
0041.00             FILFILLIB, "*FIRST    ", "0", "*FILETYPE ", "*EXT      ", &errcode);
0042.00     if(errcode.BYTESAVL != 0){/*ERR*/                                           
0043.00       free(formatBuf);                                                          
0044.00       printf("TESTACP[%d] QBRTVFD のエラー n", __LINE__);                      
0045.00       getchar();                                                                
0046.00       exit(-1);                                                                 
0047.00     }/*ERR*/                                                                    
0048.00     else{/*API バッファー取得成功 */                                                           
0049.00       qdb_qdbfh = (Qdb_Qdbfh_t*)(char*)formatBuf;                                              
0050.00       qdb_qdbfhflg = (Qdb_Qdbfhflg_t*)(qdb_qdbfh + qdb_qdbfh->Qdbfjorn);                       
0051.00       if(qdb_qdbfhflg->Qdbfhfky == 1) res = TRUE;                                               
0052.00       else res = FALSE;                                                                        
0053.00       free(formatBuf);                                                                         
0054.00       memcpy(FILE, FILFILLIB, 10); FILE[10] = 0x00;                                            
0055.00       memcpy(FILLIB, &FILFILLIB[10], 10); FILLIB[10] = 0x00;                                   
0056.00       if(res == TRUE){                                                                         
0057.00         printf("TESTIDX[%d] %s/%s はキーつきの索引ファイルです。 n", __LINE__, FILLIB, FILE); 
0058.00       }                                                                                        
0059.00       else{                                                                                    
0060.00         printf("TESTIDX[%s] %s/%s は順次ファイルです。 n", __LINE__, FILLIB, FILE);           
0061.00       }                                                                                        
0062.00       getchar();                                                                               
0063.00       exit(0);                                                                                 
0064.00     }/*API バッファー取得成功 */                                                               
0065.00   }/* 長さの取得は成功 */                                                                      
0066.00 }      


                                                                                        

[解説]

最初に

0004.00 #include   /* DATABASE API */ 

を宣言してAPI QDBRTVFD のプロトタイプをインクルードできるようにしておく。
次に

0030.00   QDBRTVFD(&qdb_qdbfh_t, sizeof(Qdb_Qdbfh_t), FILFILLIB, "FILD0200",            
0031.00             FILFILLIB, "*FIRST    ", "0", "*FILETYPE ", "*EXT      ", &errcode);

によってバッファーに必要な長さを取得してから

0038.00     format_size = qdb_qdbfh_t.Qdbfyavl;                                         
0039.00     formatBuf = (char*)malloc(format_size + 1);                                 
0040.00     QDBRTVFD((char*)formatBuf, format_size, FILFILLIB, "FILD0100",              
0041.00             FILFILLIB, "*FIRST    ", "0", "*FILETYPE ", "*EXT      ", &errcode);

によって API QDBRTVFD を実行してバッファーを取得する。
_

0049.00       qdb_qdbfh = (Qdb_Qdbfh_t*)(char*)formatBuf;                                              
0050.00       qdb_qdbfhflg = (Qdb_Qdbfhflg_t*)(qdb_qdbfh + qdb_qdbfh->Qdbfjorn);                       
0051.00       if(qdb_qdbfhflg->Qdbfhfky = 1) res = TRUE;                                               
0052.00       else res = FALSE; 

取得したバッファー全体を

0020.00   Qdb_Qdbfh_t* qdb_qdbfh;     /* ファイル定義ヘッダー */

にキャストしてその中から

0050.00       qdb_qdbfhflg = (Qdb_Qdbfhflg_t*)(qdb_qdbfh + qdb_qdbfh->Qdbfjorn); 

として

0021.00   Qdb_Qdbfhflg_t* qdb_qdbfhflg;  /*標識構造体 */ 

を取り出す。これによって

0051.00       if(qdb_qdbfhflg->Qdbfhfky = 1) res = TRUE;                                               
0052.00       else res = FALSE;

を判断することができる。

[キャストとは]

C言語でよく使われる「キャスト」という用語はあるメモリ・バッファーを
別に定義しておいた構造体として重ね合わせてその構造体の要素を
判断して取り出すことを言う。
これはあたかも透明なプラスチック製の定規をある場所に当てて
そこから定規の目盛りを読取る操作に良く似ている。
C言語を知っているというだけでは不十分でAPIをC言語で解析するには
このような高度なテクニックを必要とする。
IBM のQSYSINCのソースはユーザヘがキャストして解析することを
前提として用意されているがいちいちキャストの方法などの
解析はない。
キャストの知識がある高度なユーザーのみを対象としているからである。
_