diff options
Diffstat (limited to 'src/core/xbdbf.cpp')
-rwxr-xr-x | src/core/xbdbf.cpp | 267 |
1 files changed, 231 insertions, 36 deletions
diff --git a/src/core/xbdbf.cpp b/src/core/xbdbf.cpp index 4033ef9..8904a6d 100755 --- a/src/core/xbdbf.cpp +++ b/src/core/xbdbf.cpp @@ -159,12 +159,14 @@ xbInt16 xbDbf::Abort(){ //! @brief Add an index to the internal list of indices for this table. /*! The index list is used during any table update process to update any open - index file. Index files can contain one or more tags. + index file. Index files can contain one or more tags. Temporary tags + are not included here because they are created after a table is open + and will be deleted when the table is closed. \param ixIn Pointer to index object for a given index file. - \param sFmt NDX or MDX. + \param sFmt NDX, MDX or TDX. \returns <a href="xbretcod_8h.html">Return Codes</a> - + */ xbInt16 xbDbf::AddIndex( xbIx * ixIn, const xbString &sFmt ){ @@ -295,6 +297,7 @@ xbInt16 xbDbf::AppendRecord(){ // calculate the latest header information xbDate d; + d.Sysdate(); cUpdateYY = (char) d.YearOf() - 1900; cUpdateMM = (char) d.MonthOf(); cUpdateDD = (char) d.DayOf( XB_FMT_MONTH ); @@ -411,7 +414,7 @@ xbInt16 xbDbf::AppendRecord(){ \param sIxType Currently only NDX. Future versions will support additional non prod index types. \param sIxName The index name. \param iOpt 0 - Add index to .INF if not already there<br> - 1 - Remove index from .INF if there + 1 - Remove index from .INF if exists \returns <a href="xbretcod_8h.html">Return Codes</a> @@ -534,7 +537,7 @@ xbInt16 xbDbf::BlankRecord() This method is used to check an index tag's intgerity. \param iTagOpt 0 - Check current tag<br> - 1 - Check all tag<br> + 1 - Check all tags<br> \param iOutputOpt Output message destination<br> 0 = stdout<br> @@ -585,21 +588,41 @@ xbInt16 xbDbf::CheckTagIntegrity( xbInt16 iTagOpt, xbInt16 iOutputOpt ){ \param iTagOpt 0 - Reindex current tag<br> 1 - Reindex all tags<br> + 2 - Reindex for tag identified by vpTag + \param iErrorOpt 0 - Don't delete tag on reindex failure<br> + 1 - Delete tag on reindex failure + \param vpTag if option 2 used, pointer to tag to reindex \returns <a href="xbretcod_8h.html">Return Codes</a> */ -xbInt16 xbDbf::Reindex( xbInt16 iTagOpt ){ +xbInt16 xbDbf::Reindex( xbInt16 iTagOpt, xbInt16 iErrorOpt, xbIx **ppIx, void **vppTag ){ xbInt16 iRc = XB_NO_ERROR; xbInt16 iErrorStop = 0; void *vp; + xbString sType; + xbString sTagName; + + if( iTagOpt < 0 || iTagOpt > 2 || (iTagOpt == 2 && (!ppIx || !vppTag ))) + return XB_INVALID_OPTION; + + + #ifdef XB_BLOCKREAD_SUPPORT + xbBool bOriginalBlockReadSts = GetBlockReadStatus(); + #endif + try{ + + #ifdef XB_BLOCKREAD_SUPPORT + if( !bOriginalBlockReadSts ) + EnableBlockReadProcessing(); + #endif + if( iTagOpt == 0 ){ if( pCurIx ){ - iRc = pCurIx->Reindex( &vpCurIxTag ); - if( iRc != XB_NO_ERROR ){ + if(( iRc = pCurIx->Reindex( &vpCurIxTag )) != XB_NO_ERROR ){ iErrorStop = 100; throw iRc; } @@ -608,7 +631,7 @@ xbInt16 xbDbf::Reindex( xbInt16 iTagOpt ){ return XB_INVALID_TAG; } - } else { + } else if( iTagOpt == 1 ) { xbLinkListNode<xbTag *> *llN = GetTagList(); xbTag *pTag; @@ -622,6 +645,19 @@ xbInt16 xbDbf::Reindex( xbInt16 iTagOpt ){ } llN = llN->GetNextNode(); } + } else if( iTagOpt == 2 ){ + + // xbIx *pIx; + // pIx = *ppIx; + xbIx *pIx = *ppIx; + // void *vpTag; + // vpTag = *vppTag; + void *vpTag = *vppTag; + + if(( iRc = pIx->Reindex( &vpTag )) != XB_NO_ERROR ){ + iErrorStop = 120; + throw iRc; + } } } catch (xbInt16 iRc ){ @@ -630,6 +666,12 @@ xbInt16 xbDbf::Reindex( xbInt16 iTagOpt ){ xbase->WriteLogMessage( sMsg.Str() ); xbase->WriteLogMessage( GetErrorMessage( iRc )); } + + #ifdef XB_BLOCKREAD_SUPPORT + if( !bOriginalBlockReadSts ) + DisableBlockReadProcessing(); + #endif + return iRc; } @@ -939,10 +981,10 @@ xbInt16 xbDbf::CopyDbfStructure( xbDbf * dNewTable, const xbString &sNewTableNam #ifdef XB_INDEX_SUPPORT //! @brief Create a new tag (index) for this dbf file (table). /*! - This routine creates a new tag (index) on a dbf file. The library currently supports NDX and MDX + This routine creates a new tag (index) on a dbf file. The library currently supports NDX, MDX ans TDX. indices. If you don't have a specific need for an NDX file, use MDX. - \param sIxType "MDX" or "NDX". + \param sIxType "MDX", "NDX" or "NTX". \param sName Index or tag name. \param sKey Index key expression, \param sFilter Filter expression. Not applicable for NDX indices. @@ -1002,6 +1044,8 @@ xbInt16 xbDbf::CreateTag( const xbString &sIxType, const xbString &sName, const } *pIxOut = ixNdx; + + // Set the current tag if one not already set if( sCurIxType == "" ){ sCurIxType = "NDX"; @@ -1031,6 +1075,7 @@ xbInt16 xbDbf::CreateTag( const xbString &sIxType, const xbString &sName, const ixMdx = (xbIxMdx *) ixList->ix; bMdxFound = xbTrue; } + ixList = ixList->next; } if( !bMdxFound ) @@ -1061,7 +1106,53 @@ xbInt16 xbDbf::CreateTag( const xbString &sIxType, const xbString &sName, const pCurIx = ixMdx; vpCurIxTag = ixMdx->GetTag(0); } + #endif + + #ifdef XB_TDX_SUPPORT + } else if( sIxType == "TDX" ){ + + if( GetVersion() == 3 ){ // TDX indexes were version 4 and higher + iErrorStop = 140; + iRc = XB_INVALID_INDEX; + throw iRc; + } + xbIxTdx *ixTdx; + xbString s; + // look through the index list and see if there is an mdx pointer we can grab + xbBool bTdxFound = xbFalse; + xbIxList *ixList = GetIxList(); + while( ixList && !bTdxFound ){ + s = ixList->sFmt->Str(); + if( s == "TDX" ){ + ixTdx = (xbIxTdx *) ixList->ix; + bTdxFound = xbTrue; + } + ixList = ixList->next; + } + if( !bTdxFound ) + ixTdx = new xbIxTdx( this ); + + if(( iRc = ixTdx->CreateTag( sName, sKey, sFilter, iDescending, iUnique, iOverLay, vpTagOut )) != XB_NO_ERROR ){ + iErrorStop = 150; + throw iRc; + } + if( !bTdxFound ){ + if(( iRc = AddIndex( ixTdx, "TDX" )) != XB_NO_ERROR ){ + iErrorStop = 160; + throw iRc; + } + } + *pIxOut = ixTdx; + + // set the current tag if one not already set + if( sCurIxType == "" ){ + + sCurIxType = "TDX"; + pCurIx = ixTdx; + vpCurIxTag = ixTdx->GetTag(0); + } + #endif } else { @@ -1192,17 +1283,23 @@ xbInt16 xbDbf::DeleteAllIndexFiles(){ // close any open index files, delete it, remove from the ix list while( ixList ){ + + // next two lines for debugging + ixList->ix->GetFileNamePart( sIxName ); ixList->ix->Close(); - ixList->ix->xbRemove(); + if(( iRc = ixList->ix->xbRemove()) != XB_NO_ERROR ){ + iErrorStop = 110; + throw iRc; + } #ifdef XB_INF_SUPPORT // if XB_INF_SUPPORT is enabled, all open non prod indices should be in here - if( *ixList->sFmt != "MDX" ){ // production indices not stored in .INF dataset + if( *ixList->sFmt != "MDX" && *ixList->sFmt != "TDX" ){ // production and temp indices not stored in .INF dataset if(( iRc = ixList->ix->GetFileNamePart( sIxName )) != XB_NO_ERROR ){ - iErrorStop = 110; + iErrorStop = 120; throw iRc; } if(( iRc = AssociateIndex( *ixList->sFmt, sIxName, 1 )) != XB_NO_ERROR ){ - iErrorStop = 120; + iErrorStop = 130; throw iRc; } } @@ -1391,7 +1488,7 @@ xbInt16 xbDbf::DeleteTable(){ /*! This routine deletes an index tag - \param sIxType Either "NDX" or "MDX".<br> + \param sIxType Either "NDX", "MDX" or "TDX".<br> \param sName Tag name to delete.<br> \returns <a href="xbretcod_8h.html">Return Codes</a> */ @@ -1452,7 +1549,7 @@ xbInt16 xbDbf::DeleteTag( const xbString &sIxType, const xbString &sName ){ throw iRc; } - if( ixl->ix == pCurIx ) + if( !ixList || ixl->ix == pCurIx ) SetCurTag( "", NULL, NULL ); } @@ -1500,7 +1597,64 @@ xbInt16 xbDbf::DeleteTag( const xbString &sIxType, const xbString &sName ){ iErrorStop = 170; throw iRc; } - if( ixl->ix == pCurIx ) + if( !ixList || ixl->ix == pCurIx ) + SetCurTag( "", NULL, NULL ); + } + } + ixlPrev = ixl; + ixl = ixlNext; + } + + if( !bDone ) + return XB_INVALID_TAG; + #endif + + #ifdef XB_TDX_SUPPORT + } else if( sIxType == "TDX" ){ + xbIxList *ixl = ixList; + xbIxList *ixlNext; + xbIxList *ixlPrev = NULL; + xbBool bDone = xbFalse; + xbIxTdx *pTdx; + xbMdxTag *pMdxTag; + xbInt16 iTagCnt = 0; + + while( ixl && !bDone ){ + ixlNext = ixl->next; + pTdx = (xbIxTdx *) ixl->ix; + iTagCnt = pTdx->GetTagCount(); + for( xbInt16 i = 0; i < iTagCnt && !bDone; i++ ){ + pMdxTag = (xbMdxTag *) pTdx->GetTag( i ); + if( pTdx->GetTagName( pMdxTag ) == sName ){ + bDone = xbTrue; + iRc = pTdx->DeleteTag( pMdxTag ); + if( iRc > 0 ){ + // Successful delete of only tag in production mdx file - need to remove it from the list, update the dbf header + cIndexFlag = 0x00; + if(( iRc = WriteHeader( 1, 0 )) != XB_NO_ERROR ){ + iErrorStop = 150; + throw iRc; + } + if(( iRc = RemoveIndex( ixl->ix )) != XB_NO_ERROR ){ + iErrorStop = 160; + throw iRc; + } + if( ixlPrev == NULL ){ + // std::cout << "setting ixList to null or should be\n"; + ixList = ixlNext; + } else { + ixlPrev = ixlNext; + } + } else if( iRc < 0 ){ + iErrorStop = 170; + throw iRc; + } + if( ixList ) + std::cout << "ixlist not null\n"; + else + std::cout << "ixlist null\n"; + + if( !ixList || ixl->ix == pCurIx ) SetCurTag( "", NULL, NULL ); } } @@ -1513,6 +1667,8 @@ xbInt16 xbDbf::DeleteTag( const xbString &sIxType, const xbString &sName ){ #endif + + } else { iErrorStop = 180; iRc = XB_INVALID_OPTION; @@ -1562,15 +1718,19 @@ xbInt16 xbDbf::DeleteTag( const xbString &sIxType, const xbString &sName ){ \returns <a href="xbretcod_8h.html">Return Codes</a> */ -xbInt16 xbDbf::DumpHeader( xbInt16 iOption ) const { +xbInt16 xbDbf::DumpHeader( xbInt16 iOption ){ int i; int iMemoCtr = 0; if( iOption < 1 || iOption > 4 ) return XB_INVALID_OPTION; - if( iDbfStatus == XB_CLOSED ) - return XB_NOT_OPEN; + xbInt16 iRc = ReadHeader( xbTrue, 0 ); + if( iRc != XB_NO_ERROR ) + return iRc; + +// if( iDbfStatus == XB_CLOSED ) +// return XB_NOT_OPEN; std::cout << "\nDatabase file " << GetFqFileName() << std::endl << std::endl; @@ -1859,7 +2019,7 @@ xbUInt32 xbDbf::GetAppendLocked() const { This routine returns the table setting if set, otherwise returns the system level setting. - + \returns Not 0 - Auto commit on for this table.<br> 0 - Auto commit off for this table. */ @@ -1920,8 +2080,10 @@ xbIx *xbDbf::GetCurIx() const { /************************************************************************/ //! @brief Get pointer to current tag for the current index. /*! - An index file can have one or more tags. An NDX index has one tag. - An MDX file can have up to 47 tags. + An index file can have one or more tags + NDX index files have one tag per file. + MDX index files can can have up to 47 tags per file. + TDX index files can can have up to 47 tags per file. \returns Pointer to current tag. */ @@ -1932,7 +2094,8 @@ void *xbDbf::GetCurTag() const { //! @brief Get the current index type. /*! \returns NDX for single tag index.<br> - MDX for production multi tag index. + MDX for production multi tag index.<br> + TDX for temporary tag index. */ const xbString &xbDbf::GetCurIxType() const { return sCurIxType; @@ -2097,12 +2260,16 @@ xbBool xbDbf::GetBof() { /************************************************************************/ //! @brief Return true if dbf file empty or positioned to the last record /*! - \returns Returns true if dbf file is empty or positioned on the last record. + \returns Returns true if error, dbf file is empty or positioned on the last record. */ xbBool xbDbf::GetEof() { - xbUInt32 ulRecCnt = GetRecordCount(); + + // xbUInt32 ulRecCnt = GetRecordCount(); - if( ulRecCnt == 0 || GetCurRecNo() == ulRecCnt ) + xbUInt32 ulRecCnt; + xbInt16 iRc = GetRecordCnt( ulRecCnt ); + + if( iRc != XB_NO_ERROR || ulRecCnt == 0 || GetCurRecNo() == ulRecCnt ) return xbTrue; else return xbFalse; @@ -2542,6 +2709,7 @@ char * xbDbf::GetRecordBuf( xbInt16 iOpt ) const { /*! \returns Record count or <a href="xbretcod_8h.html">Return Codes</a> */ +/* xbUInt32 xbDbf::GetRecordCount(){ xbUInt32 ulCnt; @@ -2551,7 +2719,7 @@ xbUInt32 xbDbf::GetRecordCount(){ else return ulCnt; } - +*/ /************************************************************************/ //! @brief Get the current number of records in the dbf data file. /*! @@ -2626,8 +2794,8 @@ xbBool xbDbf::GetTableLocked() const { This routine returns a list of tags for the file.<br> The library is structured to support one or more files of the same or differing - index types (NDX/MDX), with each file supporting one or more index tags.<br> - + index types (NDX/MDX/TDX), with each file supporting one or more index tags.<br> + \returns Tag list for the file/table. */ xbLinkListNode<xbTag *> *xbDbf::GetTagList() const { @@ -2944,6 +3112,19 @@ xbInt16 xbDbf::LockIndices( xbInt16 iLockFunction ) } #endif + #ifdef XB_TDX_SUPPORT + if( *ixLI->sFmt == "TDX" ){ + if( !ixLI->ix->GetLocked()){ + if(( iRc = ixLI->ix->xbLock( XB_LOCK, LK4026531838, 1 )) != XB_NO_ERROR ){ + ixLI->ix->xbLock( XB_UNLOCK, LK4026531838, 1 ); + iErrorStop = 100; + throw iRc; + } + ixLI->ix->SetLocked( xbTrue ); + } + } + #endif + } else if( iLockFunction == XB_UNLOCK ){ #ifdef XB_NDX_SUPPORT @@ -2970,6 +3151,18 @@ xbInt16 xbDbf::LockIndices( xbInt16 iLockFunction ) } #endif + #ifdef XB_TDX_SUPPORT + if( *ixLI->sFmt == "MDX" ){ + if( ixLI->ix->GetLocked()){ + if(( iRc = ixLI->ix->xbLock( XB_UNLOCK, LK4026531838, 1 )) != XB_NO_ERROR ){ + iErrorStop = 100; + throw iRc; + } + ixLI->ix->SetLocked( xbFalse ); + } + } + #endif + } ixLI = ixLI->next; } @@ -3377,7 +3570,7 @@ xbInt16 xbDbf::OpenIndex( const xbString &sIxType, const xbString &sFileName ){ xbInt16 xbDbf::Pack() { xbUInt32 ulDeletedRecCnt; - return Pack( ulDeletedRecCnt ); + return Pack( ulDeletedRecCnt ); } @@ -3484,6 +3677,7 @@ xbInt16 xbDbf::Pack( xbUInt32 &ulDeletedRecCnt ) // update header record count xbDate d; + d.Sysdate(); cUpdateYY = (char) d.YearOf() - 1900; cUpdateMM = (char) d.MonthOf(); cUpdateDD = (char) d.DayOf( XB_FMT_MONTH ); @@ -3520,7 +3714,6 @@ xbInt16 xbDbf::Pack( xbUInt32 &ulDeletedRecCnt ) } } #endif // XB_MEMO_SUPPORT - } catch (xbInt16 iRc ){ if( iRc != XB_LOCK_FAILED ){ @@ -3665,6 +3858,7 @@ xbInt16 xbDbf::PutRecord(xbUInt32 ulRecNo) // update latest header date if changed xbDate d; + d.Sysdate(); if( (cUpdateYY != (char)(d.YearOf() - 1900)) || (cUpdateMM != (char) d.MonthOf()) || (cUpdateDD != (char)d.DayOf( XB_FMT_MONTH))){ cUpdateYY = (char) d.YearOf() - 1900; cUpdateMM = (char) d.MonthOf(); @@ -3716,9 +3910,9 @@ xbInt16 xbDbf::PutRecord(xbUInt32 ulRecNo) LockHeader( XB_UNLOCK ); LockAppend( XB_UNLOCK ); LockRecord( XB_UNLOCK, ulRecNo ); - #ifdef XB_INDEX_SUPPORT + #ifdef XB_INDEX_SUPPORT LockIndices( XB_UNLOCK ); - #endif // XB_INDEX_SUPPORT + #endif // XB_INDEX_SUPPORT } #endif // XB_LOCKING_SUPPORT @@ -3972,7 +4166,7 @@ xbInt16 xbDbf::SetCurTag( const xbString &sTagName ){ //! @brief Set the current tag for the dbf file. /*! - \param sIxType - One of "NDX" or MDX", + \param sIxType - One of "NDX", MDX or TDX", \param pIx - Pointer to index object. \param vpTag - Pointer to tag object. \returns <a href="xbretcod_8h.html">Return Codes</a> @@ -4206,6 +4400,7 @@ xbInt16 xbDbf::Zap(){ #endif xbDate d; + d.Sysdate(); cUpdateYY = (char) d.YearOf() - 1900; cUpdateMM = (char) d.MonthOf(); cUpdateDD = (char) d.DayOf( XB_FMT_MONTH ); |