#define UDEBUG 0 #define PKMAX 10 /* max number of keys [GROUP BY fields] */ #define LOADMEMMAX 100000 /* max number of records in batch */ typedef short int DdSInt; typedef long DdLong; typedef unsigned long DdULong; typedef float DdFloat; typedef double DdDouble; typedef struct DATAITEMINFO{ char pkName[64]; int pkDataType; int pkDataLen; int pkDataPosition; }DATAITEMINFO; typedef struct DATAITEMHEADER{ char *dihPtr; int dihOrder; /* original 1-rel position in DataArray[] */ long dihRecno; /* record # or 0 if not found */ int dihFlags; int dihReducedIndexBack; /* 1-rel back index from Reduced */ }DATAITEMHEADER; typedef struct FINDCBCONTEXT{ DATAITEMHEADER *dih; int pkCount; DATAITEMINFO *pkInfo; }FINDCBCONTEXT; enum{ DihFlDuplicate = 0x01 }; static void ExtractUpdateParams( CONTROL *ctl, char *OptnStr, char *ArgStr, char *dgName, /* char dgName[64] */ char *rdName, /* char rdName[64] */ DATAITEMINFO *pkInfo, int *pkCount, int *rdLengthRef, char *ErrorString); /* char ErrorString[256] */ static int STDCALL FindCb( /* value 1 - continue FIND iteration; 0 - stop FIND iteration */ WtCastPtr UserWord, long *FindRecArray, /* array of record numbers */ int FindRecCount, /* number of records found */ int DataArrayIndex); static int UpdateSortComp(WtCastPtr UserWord,char *bi,char *bj); static void UpdateSortSwap(WtCastPtr UserWord,char *bi,char *bj); /* Format of ArgStr:1) Create shadow vector of DATAITEMHEADER{} structs; copy pointers to shadow vector; 2) Sort shadow vector; 3) Eliminate duplicates from shadow vector; 4) Create new char* vector of sorted, reduced items; 5) Call ddlFindCb(); 6) Do Updates 7) Do Inserts 8) Build Structures */ void DoUpdate( CONTROL *ctl, char *OptnStr, char *ArgStr, char *DataArray[], int DataArrayCount, /* number of DataArray[] items */ int DataArrayItemSize, /* size of each DataArray[] item */ char *ErrorString) /* char ErrorString[256] */ { DATAITEMHEADER *dih = 0; DATAITEMINFO pkInfo[PKMAX]; FINDCBCONTEXT FindCbContext; int rdLength = 0,pkCount = 0; int i,j,iLatest,memneed = 0,iDataReducedCount = 0; int iInsertRecCount = 0,iUpdateRecCount = 0; int offset = 0,irc = 0,ircBatch = 0,ircCount = 0; char **DataArrayReduced = 0,*DataLoadMemBlock = 0; char command[2048]; char dgName[64] = "Sessions"; char rdName[64] = "Sessions_RD"; #if UDEBUG ddlCalc(ctl,"/","SET %TimePrep = \' \'"); ddlCalc(ctl,"/","SET %TimeFind = \' \'"); ddlCalc(ctl,"/","SET %TimeUpdate = \' \'"); ddlCalc(ctl,"/","SET %TimeLoad = \' \'"); ddlCalc(ctl,"/","SET %TimeSession = \' \'"); ddlCalc(ctl,"/","SET %TimeStartTime = \' \'"); ddlCalc(ctl,"/","SET %TimeClientAddr = \' \'"); ddlCalc(ctl,"/","SET %TimeServerAddr = \' \'"); // CheckTime(ctl,"Elapsed","%TimeStart"); #endif *ErrorString = 0; setmem((char*)pkInfo,sizeof(pkInfo),0); ExtractUpdateParams(ctl,OptnStr,ArgStr,dgName,rdName,pkInfo,&pkCount,&rdLength,ErrorString); if(ErrorString[0] != 0){ return; } if(DataArrayCount == 0) return; /* 1A) Create shadow vector of DATAITEMHEADER{} structs */ memneed = DataArrayCount * sizeof(DATAITEMHEADER); dih = (DATAITEMHEADER*)malloc(memneed); if(dih == 0){ sprintf(ErrorString,"Unable to allocate memory-1: %d bytes",memneed); return; } setmem((char*)dih,memneed,0); /* 1B) copy pointers to shadow vector */ for(i=0;i dihPtr = DataArray[i]; (dih+i)->dihOrder = i+1; } FindCbContext.dih = dih; FindCbContext.pkInfo = pkInfo; FindCbContext.pkCount = pkCount; /* 2) sort shadow vector */ ddlShellSort(ctl, (char*)dih, DataArrayCount, sizeof(DATAITEMHEADER), UpdateSortComp, UpdateSortSwap, (long)&FindCbContext); if(ctl->Status != 0){ sprintf(ErrorString,"Error in ShellSort: %d",ctl->Status); return; } /* 3) eliminate duplicates from shadow vector */ for(i=1,iLatest=0;i dihPtr,(dih+i)->dihPtr,pkLength) == 0){ if(UpdateSortComp((long)&FindCbContext,(char*)(dih+i-1),(char*)(dih+i)) == 0){ (dih+i-1)->dihFlags |= DihFlDuplicate; (dih+i)->dihFlags |= DihFlDuplicate; if(iLatest == 0) iLatest = i; /* = (i-1) + 1 */ /* remember the latest in the original order */ if((dih+i)->dihOrder > (dih+iLatest-1)->dihOrder){ iLatest = i+1; } if(i == (DataArrayCount - 1)){ (dih+iLatest-1)->dihFlags &= ~DihFlDuplicate; ++iDataReducedCount; iLatest = 0; break; } }else{ if(iLatest != 0){ (dih+iLatest-1)->dihFlags &= ~DihFlDuplicate; }else{ } if(i == (DataArrayCount - 1)){ ++iDataReducedCount; } ++iDataReducedCount; iLatest = 0; } } if(DataArrayCount == 1) iDataReducedCount = 1; /* 4) create new char* vector of sorted, reduced items */ memneed = iDataReducedCount * sizeof(char*); DataArrayReduced = (char**)malloc(memneed); if(DataArrayReduced == 0){ sprintf(ErrorString,"Unable to allocate memory-2: %d bytes",memneed); if(dih) free((void*)dih); return; } for(i=j=0;i dihFlags & DihFlDuplicate) == 0){ (dih+j)->dihReducedIndexBack = i+1; DataArrayReduced[j++] = (dih+i)->dihPtr; } } #if UDEBUG // CheckTime(ctl,"Elapsed","%TimePrep"); #endif /* 5) call ddlFindCb() */ _snprintf(command,sizeof(command)-1,"%s %s %s",dgName,rdName,pkInfo[0].pkName); for(i=1;i Status != 0){ sprintf(ErrorString,"Error in FindCb: %d",ctl->Status); goto Finish; } if(DataArrayReduced) free((void*)DataArrayReduced); DataArrayReduced = 0; #if UDEBUG // CheckTime(ctl,"Elapsed","%TimeFind"); #endif // for(i=0;i dihOrder,(dih+i)->dihReducedIndexBack,(dih+i)->dihRecno,(dih+i)->dihPtr); // } /* 6) do Updates */ for(i=0;i dihFlags & DihFlDuplicate) == 0 && (dih+i)->dihRecno != 0){ _snprintf(command,sizeof(command)-1,"%s %s %d",dgName,rdName,(dih+i)->dihRecno); ddlRewriteB(ctl,"/",command,(dih+i)->dihPtr); if(ctl->Status != 0){ sprintf(ErrorString,"Error in RewriteB: %d",ctl->Status); goto Finish; } ++iUpdateRecCount; } if(((dih+i)->dihFlags & DihFlDuplicate) == 0 && (dih+i)->dihRecno == 0){ ++iInsertRecCount; } } #if UDEBUG // CheckTime(ctl,"Elapsed","%TimeUpdate"); #endif /* 7) do Inserts */ if(iInsertRecCount > 0){ irc = iInsertRecCount; memneed = LOADMEMMAX * rdLength; if(irc < LOADMEMMAX) memneed = iInsertRecCount * rdLength; DataLoadMemBlock = (char*)malloc(memneed+64); if(DataLoadMemBlock == 0){ sprintf(ErrorString,"Unable to allocate memory-3: %d bytes",memneed); if(dih) free((void*)dih); return; } setmem(DataLoadMemBlock,memneed,0); i = 0; while(irc > 0){ ircBatch = irc; if(ircBatch > LOADMEMMAX) ircBatch = LOADMEMMAX; irc -= ircBatch; ircCount = 0; for(offset=0;i dihFlags & DihFlDuplicate) == 0 && (dih+i)->dihRecno == 0){ // k = stccpy(DataLoadMemBlock+offset,(dih+i)->dihPtr,rdLength+1) - 1; movmem((dih+i)->dihPtr,DataLoadMemBlock+offset,rdLength); offset += rdLength; if(++ircCount >= ircBatch) break; } } _snprintf(command,sizeof(command)-1,"^S %s %s",dgName,rdName); ddlLoadMem(ctl,"/B",command,DataLoadMemBlock,rdLength,ircCount); if(ctl->Status != 0){ sprintf(ErrorString,"Error in LoadMem: %d",ctl->Status); goto Finish; } } #if UDEBUG // CheckTime(ctl,"Elapsed","%TimeLoad"); #endif #if !UDEBUG ddlStructure(ctl,"/",""); #else ddlStructure(ctl,"/","SESSION"); // CheckTime(ctl,"Elapsed","%TimeSession"); ddlStructure(ctl,"/","STARTTIME"); // CheckTime(ctl,"Elapsed","%TimeStartTime"); ddlStructure(ctl,"/","CLIENT_ADDR"); // CheckTime(ctl,"Elapsed","%TimeClientAddr"); ddlStructure(ctl,"/","SERVER_ADDR"); // CheckTime(ctl,"Elapsed","%TimeServerAddr"); #endif if(ctl->Status != 0){ sprintf(ErrorString,"Error in Structure: %d",ctl->Status); goto Finish; } } Finish: if(iInsertRecCount > 0 || iUpdateRecCount > 0){ printf("\n\n%d records updated; %d records inserted\n",iUpdateRecCount,iInsertRecCount); } if(DataLoadMemBlock) free((void*)DataLoadMemBlock); DataLoadMemBlock = 0; if(DataArrayReduced) free((void*)DataArrayReduced); DataArrayReduced = 0; if(dih) free((void*)dih); dih = 0; } static void ExtractUpdateParams( CONTROL *ctl, char *OptnStr, char *ArgStr, char *dgName, /* char dgName[64] */ char *rdName, /* char rdName[64] */ DATAITEMINFO *pkInfo, int *pkCountRef, int *rdLengthRef, char *ErrorString) /* char ErrorString[256] */ { int pkCount = 0; long pkHandle; char tempName[64],command[512]; *dgName = 0; *rdName = 0; *pkCountRef = 0; /* extract TABLE name */ MakeName(ArgStr,tempName,sizeof(tempName)); _snprintf(command,sizeof(command)-1,"DGNAME %s",tempName); ddlVerify(ctl,"/",command); if(strcmp(ctl->Ans1str,"NO") == 0){ sprintf(ErrorString,"Error: Table \"%s\" not found",tempName); return; }else{ strcpy(dgName,tempName); } ArgStr = nextarg(ArgStr); /* extract RD name */ MakeName(ArgStr,tempName,sizeof(tempName)); _snprintf(command,sizeof(command)-1,"%s",tempName); ddlGetRDHandle(ctl,"/",command); if(ctl->Status != 0){ sprintf(ErrorString,"Error: RD \"%s\" not found",tempName); return; }else{ strcpy(rdName,tempName); pkHandle = ctl->Ans1; *rdLengthRef = (int)ctl->Ans3; } for(;;){ ArgStr = nextarg(ArgStr); if(*ArgStr == 0) break; /* extract PK name */ MakeName(ArgStr,tempName,sizeof(tempName)); _snprintf(command,sizeof(command)-1,"SIGNATURE %s %s",dgName,tempName); ddlVerify(ctl,"/",command); if(strcmp(ctl->Ans1str,"NO") == 0){ sprintf(ErrorString,"Error: PK \"%s\" not found",tempName); return; }else{ strcpy(pkInfo->pkName,tempName); } /* get PK RD info */ _snprintf(command,sizeof(command)-1,"%s %s",rdName,tempName); ddlGetRDType(ctl,"/",command); if(ctl->Status != 0){ sprintf(ErrorString,"Error: PK \"%s\" not found in RD",tempName); return; }else{ pkInfo->pkDataType = (int)ctl->Ans1; pkInfo->pkDataPosition = (int)ctl->Ans2 + 1; /* make it 1-relative */ pkInfo->pkDataLen = (int)(ctl->Ans3 % 65536); } ++pkCount; ++pkInfo; } *pkCountRef = pkCount; } static int STDCALL FindCb( /* value 1 - continue FIND iteration; 0 - stop FIND iteration */ WtCastPtr UserWord, long *FindRecArray, /* array of record numbers */ int FindRecCount, /* number of records found */ int DataArrayIndex) { FINDCBCONTEXT *FindCbContext = (FINDCBCONTEXT*)UserWord; DATAITEMHEADER *dih = FindCbContext->dih; int dihIndex = 0; int result = 1; dihIndex = (dih+DataArrayIndex-1)->dihReducedIndexBack; if(dihIndex > 0){ (dih+dihIndex-1)->dihRecno = *FindRecArray; } return result; } static char **ReadFlatFile( CONTROL *ctl, char *rdName, char *filename, int *reccount, int delta, /* flag for generating test data */ char *ErrorString) /* char ErrorString[256] */ { int i = 0,l = 8,deltaT = delta,fn = _open(filename,0x8000); int pkHandle = 0,rdLength = 0,nItem = 0; int memneed = 0,memneedData = 0,memneedPtr = 0; DdLong64 flen; char **data = 0,*d = 0,*d1; char deltaStr[12] = "\0"; char command[256],tempName[256]; if(delta){ setmem(deltaStr,sizeof(deltaStr),0); setmem(deltaStr,l,'0'); for(i=l;;){ if(deltaT <= 0 || i <= 0) break; deltaStr[--i] = ((deltaT - 1) % 26) + 'A'; deltaT /= 26; } } if(fn == -1){ sprintf(ErrorString,"Error opening file \"%s\"",filename); return 0; } flen = _lseek(fn,0,2); _lseek(fn,0,0); memneedData = (int)flen + 64; /* extract RD name */ MakeName(rdName,tempName,sizeof(tempName)); _snprintf(command,sizeof(command)-1,"%.256s",tempName); ddlGetRDHandle(ctl,"/",command); if(ctl->Status != 0){ sprintf(ErrorString,"Error: RD \"%s\" not found",tempName); return 0; }else{ pkHandle = ctl->Ans1; rdLength = (int)ctl->Ans3; } nItem = (int)flen / rdLength; memneedPtr = sizeof(char*) * nItem + 64; memneed = memneedData + memneedPtr; data = (char**)malloc(memneed); setmem((char*)data,memneed,0); d = (char*)data + memneedPtr; _read(fn,d,(long)flen); _close(fn); // { // if(delta){ // for(i=0;i<(int)flen;++i){ // *(d+i) ^= (0x84 + i); // } // } // } #if 1 for(i=0,d1=d;;){ data[i++] = d1; if(delta){ movmem(deltaStr,d1+45,l); *((long*)(d1+55)) += delta * 3000; /* starttime */ *((long*)(d1+59)) += delta * 3000; /* endtime */ *((long*)(d1+124)) += (delta % 6) * 65536; /* endtime */ } d1 += rdLength; if(i >= nItem) break; } #else for(d1=d2=d;;++d1){ if((chr = *d1) == 0) break; if(chr == '\r'){ *d1 = 0; data[i++] = d2; while(*(d1+1) == '\r' || *(d1+1) == '\n') ++d1; d2 = d1+1; } } if(d1 > (d2+20)) data[i++] = d2; #endif if(i > 0 && strncmp(data[i-1],"/./././.",8) == 0) --i; *reccount = i; return data; } static int UpdateSortComp(WtCastPtr UserWord,char *bi,char *bj) { FINDCBCONTEXT *fcc = (FINDCBCONTEXT*)UserWord; DATAITEMINFO *pkInfo = fcc->pkInfo; int i = 0,k,pl,pkCount = fcc->pkCount; char *pi = 0,*pj = 0; for(i=0;i dihPtr + pkInfo->pkDataPosition - 1; pj = ((DATAITEMHEADER*)bj)->dihPtr + pkInfo->pkDataPosition - 1; pl = pkInfo->pkDataLen; switch(pkInfo->pkDataType){ case DdTypeAlpha: if((k = strnicmp(pi,pj,pl)) < 0) return -1; if(k > 0) return 1; break; case DdTypeShortInt: if(*((DdSInt*)pi) < *((DdSInt*)pj)) return -1; if(*((DdSInt*)pi) > *((DdSInt*)pj)) return 1; break; case DdTypeLongInt: if(*((DdLong*)pi) < *((DdLong*)pj)) return -1; if(*((DdLong*)pi) > *((DdLong*)pj)) return 1; break; case DdTypeLongInt64: if(*((DdLong64*)pi) < *((DdLong64*)pj)) return -1; if(*((DdLong64*)pi) > *((DdLong64*)pj)) return 1; break; case DdTypeFloat: if(*((DdFloat*)pi) < *((DdFloat*)pj)) return -1; if(*((DdFloat*)pi) > *((DdFloat*)pj)) return 1; break; case DdTypeDouble: if(*((DdDouble*)pi) < *((DdDouble*)pj)) return -1; if(*((DdDouble*)pi) > *((DdDouble*)pj)) return 1; break; case DdTypeULongInt: if(*((DdULong*)pi) < *((DdULong*)pj)) return -1; if(*((DdULong*)pi) > *((DdULong*)pj)) return 1; break; case DdTypeNumeric: case DdTypeLogical: case DdTypeVarChar: default: break; } } return 0; } static void UpdateSortSwap(WtCastPtr UserWord,char *bi,char *bj) { DATAITEMHEADER dihTemp; movmem((char*)bi,(char*)&dihTemp,sizeof(DATAITEMHEADER)); movmem((char*)bj,(char*)bi,sizeof(DATAITEMHEADER)); movmem((char*)&dihTemp,(char*)bj,sizeof(DATAITEMHEADER)); }
Copyright © 2019 , WhamTech, Inc. All rights reserved. This
document is provided for information purposes only and the contents hereof are
subject to change without notice. Names may be
trademarks of their respective owners.