MUSASHI C source: xtnjoin.c


0001: /*============================================================================*/ 
0002: /* 変更履歴                                                                   */ 
0003: /*----------------------------------------------------------------------------*/ 
0004: /* 1.0 : 新しいAPIに対応 2003/06/20                                           */ 
0005: /* 1.1 : 数値でソートしたキーを持つデータの動作不具合対処(API) 2003/08/07     */ 
0006: /*============================================================================*/ 
0007:  
0008: #include <musashi.h
0009: #include <stdlib.h> 
0010:  
0011: #include "xtnjoinHelp.h" 
0012: struct mssComHelp comHelp={ 
0013:   "xtnjoin",      /* コマンド名       */ 
0014:   "1.1",          /* バージョン       */ 
0015:   HELPT,          /* コマンドタイトル */ 
0016:   HELPS,          /* 要約             */ 
0017:   HELPE,          /* 利用例           */ 
0018:   HELPR,          /* 参照コマンド     */ 
0019:   HELPA,          /* 作者情報         */ 
0020:   HELPB,          /* バグレポート情報 */ 
0021:   HELPH           /* ホームページ     */ 
0022: }; 
0023:  
0024: extern struct mssGlobalVariables mssGV;                                        
0025:  
0026: /*--グローバル変数*/ 
0027: static int fcT;          /*入力データの項目数*/ 
0028: static int fcM;          /*参照データの項目数*/ 
0029: static int statT;        /*mssReadFRK(Tra)のステータス*/ 
0030: static int statM;        /*mssReadFRK(Mst)のステータス*/ 
0031: static struct mssFPW *op; 
0032: static MssOptKEY *OPTTKY; 
0033: static MssOptKEY *OPTMKY; 
0034: static MssOptFLD *OPTFLD; 
0035:  
0036: /** 
0037:  * # FUNCTION # 
0038:  * 現在読み込まれているTraとMstのキーの値を比較する 
0039:  */ 
0040: int keyCmp( 
0041:   struct mssFldRecKey *frkT, 
0042:   struct mssFldRecKey *frkM){ 
0043:   int cmp; 
0044:   int i; 
0045:   int fnT; 
0046:   int fnM; 
0047:  
0048:   if(statT==EOF) return(1);  /*T>M*/ 
0049:   if(statM==EOF) return(-1); /*T<M*/ 
0050:  
0051:   for(i=0; i<OPTTKY->flds->cnt; i++){ 
0052:     fnT=MssFlds2num(OPTTKY->flds,i); 
0053:     fnM=MssFlds2num(OPTMKY->flds,i); 
0054:     cmp = strcmp( *(frkT->pnt+fnT), *(frkM->pnt+fnM) ); 
0055:     if(cmp>0) return(1); /*T>M*/ 
0056:     if(cmp<0) return(-1);/*T<M*/ 
0057:   } 
0058:   return(0); 
0059: } 
0060:  
0061: /** 
0062:  * # FUNCTION # 
0063:  * マスター項目としてstr配列のcnt個の要素を書き出す。 
0064:  * 行末の改行を出力する。 
0065:  */ 
0066: void writeMstFld(int cnt, char **str){ 
0067:   int i; 
0068:   for(i=0; i<cnt-1; i++){ 
0069:     mssWriteStr(*(str+MssFlds2num(OPTFLD->flds,i)),op); 
0070:     mssWriteDlm(op); 
0071:   } 
0072:   mssWriteStr(*(str+MssFlds2num(OPTFLD->flds,i)),op); 
0073:   mssWriteRet(op); 
0074: } 
0075:  
0076: /** 
0077:  * # FUNCTION # 
0078:  * マスター項目として、cnt個のNULL値として書き出す。 
0079:  * 行末の改行を出力する。 
0080:  */ 
0081: void writeMstNul(int cnt){ 
0082:   int i; 
0083:   for(i=0; i<cnt-1; i++){ 
0084:     mssWriteNull(op); mssWriteDlm(op); 
0085:   } 
0086:   mssWriteNull(op); mssWriteRet(op); 
0087: } 
0088:  
0089: /** 
0090:  * # FUNCTION # 
0091:  * トランザクション項目としてstr配列のcnt個の要素を書き出す。 
0092:  * 行末はスペースを出力する。 
0093:  */ 
0094: void writeTraFld(int cnt, char **str){ 
0095:   int i; 
0096:   for(i=0; i<cnt; i++){ 
0097:     mssWriteStr(*(str+i),op); 
0098:     mssWriteDlm(op); 
0099:   } 
0100: } 
0101:  
0102: /** 
0103:  * # FUNCTION # 
0104:  * トランザクションキー項目の値が、にマスターキー項目に存在しないとき、 
0105:  * トランザクションのキー項目は、マスターの項目(str)を参照しながら出力し、 
0106:  * その他のトランザクション項目はNULL値を出力する。 
0107:  */ 
0108: void writeTraByMst(char **str){ 
0109:   int kv; 
0110:   int i; 
0111:   for(i=0; i<fcT; i++){ 
0112:     kv=*(OPTTKY->fldNo2optNo+i); 
0113:     if(kv!=-1){ 
0114:       mssWriteStr(*(str+MssFlds2num(OPTMKY->flds,kv)),op); 
0115:       mssWriteDlm(op); 
0116:     }else{ 
0117:       mssWriteNull(op); mssWriteDlm(op); 
0118:     } 
0119:   } 
0120: } 
0121:  
0122: /** 
0123:  * # FUNCTION # 
0124:  * 現在のトランザクションとマスターを自然結合し、その結果を出力する。 
0125:  * frkTもしくはfrkMのいずれかにNULLを与えることにより、outerJOINを行い、 
0126:  * その結果を出力する。 
0127:  */ 
0128: void writeTM(struct mssFldRecKey *frkT,struct mssFldRecKey *frkM){ 
0129:  
0130:   /*マスターがEOFの時*/ 
0131:   if(frkM==NULL){ 
0132:     mssSeekTopFRK(frkT); 
0133:     while( EOF != mssReadFldRecFRK(frkT) ){ 
0134:       writeTraFld(frkT->fldCnt,frkT->pnt); 
0135:       writeMstNul(OPTFLD->flds->cnt); 
0136:       mssGV.outCnt++; 
0137:     } 
0138:  
0139:   /*トラがEOFの時*/ 
0140:   }else if(frkT==NULL){ 
0141:     mssSeekTopFRK(frkM); 
0142:     while( EOF != mssReadFldRecFRK(frkM) ){ 
0143:       writeTraByMst(frkM->pnt); 
0144:       writeMstFld(OPTFLD->flds->cnt,frkM->pnt); 
0145:       mssGV.outCnt++; 
0146:     } 
0147:  
0148:   /*トラ、マスターの両方ある場合*/ 
0149:   }else{ 
0150:     mssSeekTopFRK(frkT); 
0151:     while( EOF != mssReadFldRecFRK(frkT) ){ 
0152:       mssSeekTopFRK(frkM); 
0153:       while( EOF != mssReadFldRecFRK(frkM) ){ 
0154:         writeTraFld(frkT->fldCnt,frkT->pnt); 
0155:         writeMstFld(OPTFLD->flds->cnt,frkM->pnt); 
0156:         mssGV.outCnt++; 
0157:       } 
0158:     } 
0159:   } 
0160: } 
0161:  
0162: /** 
0163:  * # FUNCTION # 
0164:  * writeNulMstのhash版。 
0165:  */ 
0166: void writeNulMstHash(struct mssHashFld *hash){ 
0167:   struct mssHashNodeFld *node; 
0168:   int i,j; 
0169:  
0170:   for(i=0; i<hash->hashVal; i++){ /*全hash値を見る*/ 
0171:     node=*(hash->node+i); 
0172:     while(node != NULL){       /*hash値がiのノードを全て見る*/ 
0173:       if(!node->endFlg){            /*そのノードが1回も検索されていなければ*/ 
0174:         for(j=0; j<node->recCnt; j++){ 
0175:           writeTraByMst(*(node->rec+j)); 
0176:           writeMstFld(OPTFLD->flds->cnt,*(node->rec+j)); 
0177:           mssGV.outCnt++; 
0178:         } 
0179:       } 
0180:       node=node->next; 
0181:     } 
0182:   } 
0183: } 
0184:  
0185: /** 
0186:  * # FUNCTION # 
0187:  * writeTMのhash版。 
0188:  */ 
0189: void writeTMhash(struct mssFldRecKey *frkT,struct mssHashNodeFld *node){ 
0190:   int i; 
0191:  
0192:   /*マスターがNULLの時*/ 
0193:   if(node==NULL){ 
0194:     mssSeekTopFRK(frkT); 
0195:     while( EOF != mssReadFldRecFRK(frkT) ){ 
0196:       writeTraFld(frkT->fldCnt,frkT->pnt); 
0197:       writeMstNul(OPTFLD->flds->cnt); 
0198:       mssGV.outCnt++; 
0199:     } 
0200:  
0201:   /*トラ、マスターの両方ある場合*/ 
0202:   }else{ 
0203:     mssSeekTopFRK(frkT); 
0204:     while( EOF != mssReadFldRecFRK(frkT) ){ 
0205:       for(i=0; i<node->recCnt; i++){ 
0206:         writeTraFld(frkT->fldCnt,frkT->pnt); 
0207:         writeMstFld(OPTFLD->flds->cnt,*(node->rec+i)); 
0208:         mssGV.outCnt++; 
0209:       } 
0210:     } 
0211:   } 
0212: } 
0213:  
0214: int main(int argc, char *argv[]){ 
0215: /*============================================================================*/ 
0216: /* オプション宣言&定義                                                       */ 
0217: /*============================================================================*/ 
0218: /*----------------------------------------------------------------------------*/ 
0219: /* 入力キー項目                                                               */ 
0220: /*----------------------------------------------------------------------------*/ 
0221:   MssOptKEY optTKY={ 
0222:     OKEY,   /* オプションタイプ                                             */ 
0223:     "k",    /* キーワード(複数文字は不可)                                   */ 
0224:     1,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0225:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0226:     "i",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0227:     0,      /* デフォルト(このオプションが指定されなかったときの動作を指定) */ 
0228:             /* 1:全ての行を異るキー値として扱う                             */ 
0229:             /* 2:全ての行を同じキー値として扱う)                            */ 
0230:             /* 0:その他(上記の意味解釈がない)                               */ 
0231:     TKYT,   /* このオプションのタイトル(Helpで表示)                         */ 
0232:     TKYC    /* このオプションのコメント(Helpで表示)                         */ 
0233:   }; 
0234:  
0235: /*----------------------------------------------------------------------------*/ 
0236: /* 参照キー項目                                                               */ 
0237: /*----------------------------------------------------------------------------*/ 
0238:   MssOptKEY optMKY={ 
0239:     OKEY,   /* オプションタイプ                                             */ 
0240:     "K",    /* キーワード(複数文字は不可)                                   */ 
0241:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0242:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0243:     "m",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0244:     0,      /* デフォルト(このオプションが指定されなかったときの動作を指定) */ 
0245:             /* 1:全ての行を異るキー値として扱う                             */ 
0246:             /* 2:全ての行を同じキー値として扱う)                            */ 
0247:             /* 0:その他(上記の意味解釈がない)                               */ 
0248:     MKYT,   /* このオプションのタイトル(Helpで表示)                         */ 
0249:     MKYC    /* このオプションのコメント(Helpで表示)                         */ 
0250:   }; 
0251:  
0252: /*----------------------------------------------------------------------------*/ 
0253: /* 参照ファイル                                                               */ 
0254: /*----------------------------------------------------------------------------*/ 
0255:   MssOptINF optMST={ 
0256:     OINF,   /* オプションタイプ                                             */ 
0257:     "m",    /* キーワード(複数文字は不可)                                   */ 
0258:     1,      /* 0:オプション, 1:必須                                         */ 
0259:     1,      /* 指定可能の最大ファイル数                                     */ 
0260:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0261:     MSTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0262:     MSTC    /* このオプションのコメント(Helpで表示)                         */ 
0263:   }; 
0264:  
0265: /*----------------------------------------------------------------------------*/ 
0266: /* 結合項目                                                                   */ 
0267: /*----------------------------------------------------------------------------*/ 
0268:   MssOptFLD optFLD={ 
0269:     OFLD,   /* オプションタイプ                                             */ 
0270:     "f",    /* キーワード(複数文字は不可)                                   */ 
0271:     1,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0272:     MssFieldMaxCnt, /* 指定可能な最大項目数                                 */ 
0273:     "m",    /* 対象とする入力データのキーワード(GUIで利用)                  */ 
0274:     1,      /* 正規表現を許可するかどうか(0:不可,1:可)                      */ 
0275:     1,      /* 新項目名を指定できるかどうか(0:不可,1:可)                    */ 
0276:     NULL,   /* 項目オプション(%以下)で指定可能な文字                        */ 
0277:             /* ex) 指定不可の場合はNULL, "nr": "-f 項目名%rn"の指定可能     */ 
0278:     FLDT,   /* このオプションのタイトル(Helpで表示)                         */ 
0279:     FLDC,   /* このオプションのコメント(Helpで表示)                         */ 
0280:     FLDF    /* フラグについての説明(Helpで表示)複数の場合はカンマで区切る   */ 
0281:   }; 
0282:  
0283: /*----------------------------------------------------------------------------*/ 
0284: /* マスターouterJoin                                                          */ 
0285: /*----------------------------------------------------------------------------*/ 
0286:   MssOptFLG optMNL={ 
0287:     OFLG,   /* オプションタイプ                                             */ 
0288:     "N",    /* キーワード(複数文字は不可)                                   */ 
0289:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0290:     MNLT,   /* このオプションのタイトル(Helpで表示)                         */ 
0291:     MNLC    /* このオプションのコメント(Helpで表示)                         */ 
0292:   }; 
0293:  
0294: /*----------------------------------------------------------------------------*/ 
0295: /* 入力outerJoin                                                              */ 
0296: /*----------------------------------------------------------------------------*/ 
0297:   MssOptFLG optTNL={ 
0298:     OFLG,   /* オプションタイプ                                             */ 
0299:     "n",    /* キーワード(複数文字は不可)                                   */ 
0300:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0301:     TNLT,   /* このオプションのタイトル(Helpで表示)                         */ 
0302:     TNLC    /* このオプションのコメント(Helpで表示)                         */ 
0303:   }; 
0304:  
0305: /*----------------------------------------------------------------------------*/ 
0306: /* 強制ハッシュJoin                                                           */ 
0307: /*----------------------------------------------------------------------------*/ 
0308:   MssOptINT optHAS={ 
0309:     OINT,   /* オプションタイプ                                             */ 
0310:     "H",    /* キーワード(複数文字は不可)                                   */ 
0311:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0312:     1001,   /* デフォルト(数値として指定)                                   */ 
0313:     11,     /* 最小値                                                       */ 
0314:     100001, /* 最大値                                                       */ 
0315:     HAST,   /* このオプションのタイトル(Helpで表示)                         */ 
0316:     HASC    /* このオプションのコメント(Helpで表示)                         */ 
0317:   }; 
0318:  
0319: /*----------------------------------------------------------------------------*/ 
0320: /* 入力ファイル                                                               */ 
0321: /*----------------------------------------------------------------------------*/ 
0322:   MssOptINF optINF={ 
0323:     OINF,   /* オプションタイプ                                             */ 
0324:     "i",    /* キーワード(複数文字は不可)                                   */ 
0325:     0,      /* 0:オプション, 1:必須                                         */ 
0326:     1,      /* 指定可能の最大ファイル数                                     */ 
0327:     0,      /*1:file not foundのエラーで終了しない 0:する                   */ 
0328:     INFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0329:     INFC    /* このオプションのコメント(Helpで表示)                         */ 
0330:   }; 
0331:  
0332: /*----------------------------------------------------------------------------*/ 
0333: /* 出力ファイル                                                               */ 
0334: /*----------------------------------------------------------------------------*/ 
0335:   MssOptOTF optOTF={ 
0336:     OOTF,   /* オプションタイプ                                             */ 
0337:     "o",    /* キーワード(複数文字は不可)                                   */ 
0338:     0,      /* 0:オプション, 1:必須                                         */ 
0339:     OTFT,   /* このオプションのタイトル(Helpで表示)                         */ 
0340:     OTFC    /* このオプションのコメント(Helpで表示)                         */ 
0341:   }; 
0342:  
0343: /*----------------------------------------------------------------------------*/ 
0344: /* 圧縮出力                                                                   */ 
0345: /*----------------------------------------------------------------------------*/ 
0346:   MssOptFLG optZIP={ 
0347:     OFLG,   /* オプションタイプ                                             */ 
0348:     "z",    /* キーワード(複数文字は不可)                                   */ 
0349:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0350:     ZIPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0351:     ZIPC    /* このオプションのコメント(Helpで表示)                         */ 
0352:   }; 
0353:  
0354: /*----------------------------------------------------------------------------*/ 
0355: /* plain text                                                                 */ 
0356: /*----------------------------------------------------------------------------*/ 
0357:   MssOptFLG optTXT={ 
0358:     OFLG,   /* オプションタイプ                                             */ 
0359:     "t",    /* キーワード(複数文字は不可)                                   */ 
0360:     0,      /* デフォルト(基本的には0) 常にonにしたいときは1にする          */ 
0361:     TXTT,   /* このオプションのタイトル(Helpで表示)                         */ 
0362:     TXTC    /* このオプションのコメント(Helpで表示)                         */ 
0363:   }; 
0364:  
0365: /*----------------------------------------------------------------------------*/ 
0366: /* ワークファイル用ディレクトリ名                                             */ 
0367: /*----------------------------------------------------------------------------*/ 
0368:   MssOptSTR optTMP={ 
0369:     OSTR,   /* オプションタイプ                                             */ 
0370:     "T",    /* キーワード(複数文字は不可)                                   */ 
0371:     0,      /* 0:オプション, 1:必須, 2:XMLtableでのみ必須(txtでは無視)      */ 
0372:     MssTempDir, /* デフォルト                                               */ 
0373:     1,      /* 文字列の最小長                                               */ 
0374:     MssFileNameMaxLen,  /* 文字列の最大長                                   */ 
0375:     TMPT,   /* このオプションのタイトル(Helpで表示)                         */ 
0376:     TMPC    /* このオプションのコメント(Helpで表示)                         */ 
0377:   }; 
0378:  
0379: /*----------------------------------------------------------------------------*/ 
0380: /* オプションをまとめる                                                       */ 
0381: /*----------------------------------------------------------------------------*/ 
0382:   void *opt[]={&optTKY,&optMKY,&optMST,&optFLD,&optMNL,&optTNL,&optHAS, 
0383:                &optINF,&optOTF,&optZIP,&optTXT,&optTMP,NULL}; 
0384:  
0385: /*============================================================================*/ 
0386: /* 変数宣言&定義                                                             */ 
0387: /*============================================================================*/ 
0388:   struct mssHeader    *hdT; /*入力ファイル用<head>タグ格納構造体*/ 
0389:   struct mssHeader    *hdM; /*参照ファイル用<head>タグ格納構造体*/ 
0390:   struct mssHeader    *hdo; /*出力ファイル用<head>タグ格納構造体*/ 
0391:   struct mssFPR       *fprT;/*入力ファイル構造体                */ 
0392:   struct mssFPR       *fprM;/*参照ファイル構造体                */ 
0393:   struct mssFPW       *fpw; /*出力ファイル構造体                */ 
0394:   struct mssFields    *sfT; /*ソート項目構造体                  */ 
0395:   struct mssFields    *sfM; /*ソート項目構造体                  */ 
0396:   int sortedT;              /*ソート済チェック用                */ 
0397:   int sortedM;              /*ソート済チェック用                */ 
0398:  
0399:   struct mssFldRecKey *frkT=NULL; 
0400:   struct mssFldRecKey *frkM=NULL; 
0401:   struct mssFldRecMax *frmM=NULL; 
0402:   struct mssFileInfo  *fi; /*マスターのファイル情報*/ 
0403:  
0404:   struct mssHashFld     *hash; 
0405:   struct mssHashNodeFld *hn; 
0406:  
0407:   int mstIsSmall; 
0408:   int procType; 
0409:   int kc; 
0410:   int i; 
0411:  
0412: /*----------------------------------------------------------------------------*/ 
0413: /* 前処理                                                                     */ 
0414: /*----------------------------------------------------------------------------*/ 
0415:   mssInit(argc,argv,&comHelp);       /* シグナル処理などの初期化              */ 
0416:   mssHelpDoc(opt,&comHelp,argc,argv);/* ヘルプ                                */ 
0417:   mssSetOption(opt,argc,argv);       /* コマンドオプションの設定              */ 
0418:  
0419:   /*-Kが指定されていなければ-kをコピーする*/ 
0420:   if(!optMKY.set){ 
0421:     mssCpyOptKey(&optMKY,&optTKY); 
0422:   } 
0423:  
0424:   fprT=mssOpenFPR(optINF.str,4);    /*ファイルオープン*/ 
0425:   fprM=mssOpenFPR(optMST.str,128);  /*マスターファイルオープン*/ 
0426:   hdT=mssReadHeader(fprT);          /*項目名情報の読み込み*/ 
0427:   hdM=mssReadHeader(fprM);          /*項目名情報の読み込み*/ 
0428:  
0429:   mssSetOptKey(&optTKY, hdT);       /* オプション項目をヘッダー項目に関連づけ*/ 
0430:   mssSetOptKey(&optMKY, hdM);       /* オプション項目をヘッダー項目に関連づけ*/ 
0431:   mssSetOptFld(&optFLD, hdM);       /* オプション項目をヘッダー項目に関連づけ*/ 
0432:  
0433:   /*traソート項目の作成*/ 
0434:   sfT=mssInitFields(); 
0435:   mssAddFieldsByFields(sfT,optTKY.flds);/* -k 項目をソート項目としてセット    */ 
0436:   mssSetFieldsSortPriority(sfT);        /* ソート優先順位番号を登録順にふる   */ 
0437:   sortedT=mssChkSorted(sfT,hdT);        /* ソート済かチェック                 */ 
0438:  
0439:   /*mstソート項目の作成*/ 
0440:   sfM=mssInitFields(); 
0441:   mssAddFieldsByFields(sfM,optMKY.flds);/* -k 項目をソート項目としてセット    */ 
0442:   mssSetFieldsSortPriority(sfM);        /* ソート優先順位番号を登録順にふる   */ 
0443:   sortedM=mssChkSorted(sfM,hdM);        /* ソート済かチェック                 */ 
0444:  
0445:   /*強制hashでなければ一万行を上限にマスターの情報を取得*/ 
0446:   if(!optHAS.set){ 
0447:     fi=mssGetFileInfo(optMST.str,10000); 
0448:  
0449:   /*強制hashならば全行マスターの情報を取得*/ 
0450:   }else{ 
0451:     fi=mssGetFileInfo(optMST.str,0); 
0452:   } 
0453:  
0454: /*----------------------------------------------------------------------------*/ 
0455: /*前処理                                                                      */ 
0456: /*----------------------------------------------------------------------------*/ 
0457: /* Traは大きいという前提で考える*/ 
0458: /* TraSrt MstSrt MstSmall */ 
0459: /* 無     無   小 hash                (1)*/ 
0460: /* 無     無   大 Tsrt+Msrt + keyBreak(2)*/ 
0461: /* 無     済   小 hash                (1)*/ 
0462: /* 無     済   大 Tsrt      + keyBreak(3)*/ 
0463: /* 済     無   小 Msrt      + keyBreak(4)*/ 
0464: /* 済     無   大 Msrt      + keyBreak(4)*/ 
0465: /* 済     済   小             keyBreak(5)*/ 
0466: /* 済     済   大             keyBreak(5)*/ 
0467:  
0468:   /*マスタが小さいかどうかのチェック*/ 
0469:   if(!fi->readEnd){  /*最後まで読み切っていない*/ 
0470:     mstIsSmall=0; 
0471:   }else{             /*その他は、smallであると判断*/ 
0472:     mstIsSmall=1; 
0473:   } 
0474:   mssFree(fi); 
0475:  
0476:   /*処理タイプの決定*/ 
0477:   if(sortedT){ 
0478:     if(sortedM){ 
0479:       if(mstIsSmall) procType=5; 
0480:       else           procType=5; 
0481:     }else{ 
0482:       if(mstIsSmall) procType=4; 
0483:       else           procType=4; 
0484:     } 
0485:   }else{ 
0486:     if(sortedM){ 
0487:       if(mstIsSmall) procType=1; 
0488:       else           procType=3; 
0489:     }else{ 
0490:       if(mstIsSmall) procType=1; 
0491:       else           procType=2; 
0492:     } 
0493:   } 
0494:  
0495:   /*強制hashの時は、強制的にtype1*/ 
0496:   if(optHAS.set) procType=1; 
0497:  
0498: /*----------------------------------------------------------------------------*/ 
0499: /*出力ヘッダーの作成と出力                                                    */ 
0500: /*----------------------------------------------------------------------------*/ 
0501:   /*出力ヘッダーの初期化(タイトル等のコピー)*/ 
0502:   hdo=mssInitCpyHeader(hdT); 
0503:      
0504:   /*入力ヘッダの全項目を追加*/ 
0505:   mssAddFieldsByFields(hdo->flds,hdT->flds); 
0506:  
0507:   /*新項目名を追加する*/ 
0508:   mssAddFieldsByStrList(hdo->flds,optFLD.newNam,optFLD.cnt); 
0509:  
0510:   if(procType==2 || procType==3){ 
0511:     mssSetFieldsSort(hdo->flds,sfT); 
0512:   } 
0513:  
0514:   /*標準出力オープン+ヘッダーの出力*/ 
0515:   fpw=mssOpenFPW(optOTF.str,optZIP.set,0); 
0516:   mssWriteHeader(hdo, fpw); 
0517:      
0518: /*----------------------------------------------------------------------------*/ 
0519: /*メインルーチン                                                              */ 
0520: /*----------------------------------------------------------------------------*/ 
0521:   /*グローバル変数セット*/ 
0522:   fcT=hdT->flds->cnt; 
0523:   fcM=hdM->flds->cnt; 
0524:   OPTTKY=&optTKY; 
0525:   OPTMKY=&optMKY; 
0526:   OPTFLD=&optFLD; 
0527:   op=fpw; 
0528:  
0529:   /*hash join*/ 
0530:   if(procType==1){ 
0531:  
0532:     /*ハッシュテーブルの作成*/ 
0533:     frmM =mssInitFRM(fcM); 
0534:     mssReadFRM(fprM,frmM); 
0535:  
0536:     /*全行読み込んでるはずなのでeofフラグがたっているはず*/ 
0537:     if(!frmM->eof) { 
0538:       mssShowErrMsg("internal error in xtnjoin by hash"); 
0539:       mssEnd(mssErrorNoDefault); 
0540:     } 
0541:  
0542:     hash=mssInitHashFld(optHAS.val, optMKY.flds); 
0543:     for(i=0; i<frmM->recCnt; i++){ 
0544:       mssHashInsertFld(hash, frmM->pnt+i*frmM->fldCnt); 
0545:     } 
0546: /*mssShowHashFld(hash, frmM->fldCnt);*/ 
0547:  
0548:     frkT=mssInitFRK(fcT,&optTKY,optTMP.str); 
0549:     while(1){ 
0550:       /*tra読み込み*/ 
0551:       statT=mssReadFRK(fprT,frkT); 
0552:  
0553:       /*Tra Endの時*/ 
0554:       if(statT==EOF){ 
0555:         if(optMNL.set) writeNulMstHash(hash); 
0556:         break; 
0557:       } 
0558:  
0559:       mssGV.inCnt += frkT->keyRecCnt; 
0560:  
0561:       /*Traのキー項目値がMstにあるかどうか*/ 
0562:       mssReadFldRecFRK(frkT); /*tra一行だけ読み込み*/ 
0563:       hn=mssHashMemberFld(hash, frkT->pnt, optTKY.flds); 
0564:       if(hn==NULL && !optTNL.set) continue; 
0565:  
0566:       /*書き出し*/ 
0567:       writeTMhash(frkT,hn); 
0568:     } 
0569:     mssFreeFRK(frkT); 
0570:     mssFreeFRM(frmM); 
0571:     mssFreeHashFld(hash); 
0572:  
0573:   /*key break join*/ 
0574:   }else{ 
0575:     frkT=mssInitFRK(fcT,&optTKY,optTMP.str); 
0576:     frkM=mssInitFRK(fcM,&optMKY,optTMP.str); 
0577:     if(!sortedT){ 
0578:       fprT=mssReopenFPRsort(fprT,4,sfT,hdT->flds->cnt,optTMP.str); 
0579:     } 
0580:     if(!sortedM){ 
0581:       fprM=mssReopenFPRsort(fprM,4,sfM,hdM->flds->cnt,optTMP.str); 
0582:     }  
0583:  
0584:     /*frk構造体から読み込むための変数。*/ 
0585:     /*このプログラムでは確保はするけど開放しない。*/ 
0586:     /*readRecFromFRKにてfr->pntは既にあるデータを指す。*/ 
0587:     /*すなわちアドレスが変わる。だから。*/ 
0588:     //frT=mssInitFRK(frkT->fldCnt); 
0589:     //frM=mssInitFRK(frkM->fldCnt); 
0590:  
0591:     statT=mssReadFRK(fprT,frkT); 
0592:     statM=mssReadFRK(fprM,frkM); 
0593:     mssGV.inCnt += frkT->keyRecCnt; 
0594:  
0595:     while(1){ 
0596:  
0597:       /*Tra,Mst両方Endの時*/ 
0598:       if(statT==EOF && statM==EOF) break; 
0599:  
0600:       /*TraだけEndの時*/ 
0601:       if(statT==EOF){ 
0602:         if(!optMNL.set) break; 
0603:       } 
0604:  
0605:       /*MstだけEndの時*/ 
0606:       if(statM==EOF){ 
0607:         if(!optTNL.set) break; 
0608:       } 
0609:  
0610:       /* Tra,Mstの最初の一行をキーの値の比較のために読み込む*/ 
0611:       mssReadFldRecFRK(frkT); 
0612:       mssReadFldRecFRK(frkM); 
0613:       kc=keyCmp(frkT,frkM); 
0614:       if(kc == 1){       /*T>M*/ 
0615:         if(optMNL.set) writeTM(NULL,frkM); 
0616:         statM=mssReadFRK(fprM,frkM); 
0617:       }else if(kc ==-1){ /*T<M*/ 
0618:         if(optTNL.set) writeTM(frkT,NULL); 
0619:         statT=mssReadFRK(fprT,frkT); 
0620:         mssGV.inCnt += frkT->keyRecCnt; 
0621:       }else{             /*T==M*/ 
0622:         writeTM(frkT,frkM); 
0623:         statT=mssReadFRK(fprT,frkT); 
0624:         mssGV.inCnt += frkT->keyRecCnt; 
0625:         statM=mssReadFRK(fprM,frkM); 
0626:       } 
0627:     } 
0628:     mssFreeFRK(frkT); 
0629:     mssFreeFRK(frkM); 
0630:   } 
0631:  
0632: /*----------------------------------------------------------------------------*/ 
0633: /*フッター出力&終了処理                                                       */ 
0634: /*----------------------------------------------------------------------------*/ 
0635:   mssWriteFooter(fpw);    /*フッターの出力              */ 
0636:   mssCloseFPR(fprT);      /*入力ファイルのクローズ      */ 
0637:   mssCloseFPR(fprM);      /*入力ファイルのクローズ      */ 
0638:   mssCloseFPW(fpw);       /*出力ファイルのクローズ      */ 
0639:   mssFreeFields(sfT);     /*ソート項目構造体の領域開放  */ 
0640:   mssFreeFields(sfM);     /*ソート項目構造体の領域開放  */ 
0641:   mssFreeHeader(hdT);     /*入力ヘッダ領域開放          */ 
0642:   mssFreeHeader(hdM);     /*入力ヘッダ領域開放          */ 
0643:   mssFreeHeader(hdo);     /*出力ヘッダ領域開放          */ 
0644:   mssFreeOption(opt);     /*オプション領域開放          */ 
0645:   mssShowEndMsg();        /* 完了メッセージ             */ 
0646:   mssEnd(mssExitSuccess); /* 終了                       */ 
0647:   return(0);              /* to avoid warning message   */ 
0648: }