diff options
Diffstat (limited to 'src/include')
-rwxr-xr-x | src/include/xbconfig.h.in | 6 | ||||
-rwxr-xr-x | src/include/xbcrix.cpp | 292 | ||||
-rwxr-xr-x | src/include/xbdate.h | 5 | ||||
-rwxr-xr-x | src/include/xbdbf.h | 22 | ||||
-rwxr-xr-x | src/include/xbexp.h | 1 | ||||
-rwxr-xr-x | src/include/xbexpnode.h | 2 | ||||
-rwxr-xr-x | src/include/xbfile.h | 139 | ||||
-rwxr-xr-x | src/include/xbindex.h | 184 | ||||
-rwxr-xr-x | src/include/xbindex.h.nope | 605 | ||||
-rwxr-xr-x | src/include/xblog.h | 15 | ||||
-rwxr-xr-x | src/include/xbretcod.h | 3 | ||||
-rwxr-xr-x | src/include/xbssv.h | 19 | ||||
-rwxr-xr-x | src/include/xbstring.h | 6 | ||||
-rwxr-xr-x | src/include/xbxbase.h | 13 |
14 files changed, 1127 insertions, 185 deletions
diff --git a/src/include/xbconfig.h.in b/src/include/xbconfig.h.in index f0d475a..f084038 100755 --- a/src/include/xbconfig.h.in +++ b/src/include/xbconfig.h.in @@ -11,6 +11,7 @@ #define PROJECT_RUNTIME_DIR "@PROJECT_RUNTIME_DIR@" #define PROJECT_DATA_DIR "@PROJECT_DATA_DIR@" #define PROJECT_LOG_DIR "@PROJECT_LOG_DIR@" +#define PROJECT_TEMP_DIR "@PROJECT_TEMP_DIR@" #define PROJECT_DFLT_LOGFILE "@CMAKE_SYSTEM_NAME@_@XB_PLATFORM@.xbLog.txt" #define EXTRA_LIBS "@EXTRA_LIBS@" #define CMAKE_RUNTIME_OUTPUT_DIRECTORY "@CMAKE_RUNTIME_OUTPUT_DIRECTORY@" @@ -69,11 +70,12 @@ #cmakedefine HAVE__FILENO_F #cmakedefine HAVE_FOPEN_S_F #cmakedefine HAVE__FSOPEN_F - #cmakedefine HAVE_FORK_F #cmakedefine HAVE__FSEEKI64_F #cmakedefine HAVE_FSEEKO_F #cmakedefine HAVE_FTRUNCATE_F + +#cmakedefine HAVE_GETENV_S_F #cmakedefine HAVE__LOCALTIME64_S_F #cmakedefine HAVE_LOCKFILE_F #cmakedefine HAVE_LOCKING_F @@ -84,6 +86,7 @@ #cmakedefine HAVE__VSNPRINTF_S_F #cmakedefine HAVE_VSPRINTF_S_F + #cmakedefine XB_PLATFORM_32 #cmakedefine XB_PLATFORM_64 #cmakedefine XB_DEBUG_SUPPORT @@ -98,6 +101,7 @@ #cmakedefine XB_INDEX_SUPPORT #cmakedefine XB_NDX_SUPPORT #cmakedefine XB_MDX_SUPPORT +#cmakedefine XB_TDX_SUPPORT #cmakedefine XB_SQL_SUPPORT #cmakedefine XB_INF_SUPPORT #cmakedefine XB_FILTER_SUPPORT diff --git a/src/include/xbcrix.cpp b/src/include/xbcrix.cpp new file mode 100755 index 0000000..b89baaa --- /dev/null +++ b/src/include/xbcrix.cpp @@ -0,0 +1,292 @@ +/* xbcrix.cpp + +XBase64 Software Library + +Copyright (c) 1997,2003,2014,2022 Gary A Kunkel + +The xb64 software library is covered under the terms of the GPL Version 3, 2007 license. + +Email Contact: + + XDB-devel@lists.sourceforge.net + XDB-users@lists.sourceforge.net + +*/ + +#include "xbase.h" + +#ifdef XB_SQL_SUPPORT + +namespace xb{ + + +/***********************************************************************/ +#ifdef XB_INDEX_SUPPORT +xbInt16 xbSql::SqlCreateIndex( const xbString &sCmdLine ){ + + // std::cout << "CREATE INDEX " << sCmdLine << std::endl; + + // expected format to create an Dbase 3, NDX index: + // CREATE INDEX ixname.ndx ON tablename.dbf ( EXPRESSION ) [ASSOCIATE] + + // expected format to create an Dbase 4, tag on an MDX index: + // CREATE [UNIQUE] INDEX tagname ON tablename.dbf ( EXPRESSION ) [DESC] [FILTER .NOT. DELETED()] + + // The ASSOCIATE parameter is specific to Xbase64 library, it is used to associate + // a non production (NDX) index file to a dbf file so it will be automatically + // opened with the dbf file whenever the dbf file is opened by the xbase64 routines. + + // The [ASSOCIATE] parameter is not used with MDX production indices + + // This method first looks for ".NDX" in the file name to determine if an NDX + // index should be created. + // if .NDX is not in the filename, it looks in the uda for "IXTYPE" for either + // NDX or MDX to detmermine the index type to create + // if IXTYPE not found, create an MDX tag + + // The optional DESC parameter defines an entire index key as descending. This is + // different than other SQL implementations where specific fields can be descending. + + // The optional FILTER parameter is specific to the XBASE64 library, is it used to + // assign a filter to a tag in an MDX style index. Everything to the right of + // the keyword FILTER is considered part of the filter. + + // The original DBASE indices used to '+' to create an index on more than one field + // ie: FIELD1+FIELD2+FIELD3 + // SQL uses commas: ie: FIELD1, FIELD2, FIELD3 + // The Xbase library supports either '+' or ',' when creating mutli field indices. + + xbInt16 iRc = 0; + xbInt16 iErrorStop = 0; + xbString sTableName; + xbString sIxName; + xbString sIxType; + xbUInt32 ulPos; + xbString sCmd = sCmdLine; + xbString sNode; + xbBool bUnique = xbFalse; + xbDbf * dbf = NULL; + xbBool bTableLocked = xbFalse; + + try{ + + // drop off the first node + ulPos = sCmd.Pos( ' ' ); + sCmd.Ltrunc( ulPos ); + sCmd.Ltrim(); + + sNode.ExtractElement( sCmd, ' ', 1, 0 ); + sNode.ToUpperCase(); + + if( sNode == "UNIQUE" ){ + //std::cout << "unique ix\n"; + bUnique = xbTrue; + ulPos = sCmd.Pos( ' ' ); + sCmd.Ltrunc( ulPos ); + sCmd.Ltrim(); + } + + // go past the index keyword + ulPos = sCmd.Pos( ' ' ); + sCmd.Ltrunc( ulPos ); + sCmd.Ltrim(); + + // pull the index name off the cmd line + sIxName.ExtractElement( sCmd, ' ', 1, 0 ); + + #ifdef XB_NDX_SUPPORT + xbString sTemp = sIxName; + sTemp.ToUpperCase(); + ulPos = sTemp.Pos( ".NDX" ); + if(ulPos == (sTemp.Len() - 3) ) + sIxType = "NDX"; + #endif // XB_NDX_SUPPORT + + if( sIxType == "" ){ + if(( iRc = uda.GetTokenForKey( "IXTYPE", sIxType )) != XB_NO_ERROR ){ + iErrorStop = 100; + throw iRc; + } + } + + #ifdef XB_NDX_SUPPORT + if( sIxType == "NDX" ){ + xbFile f( xbase ); + f.SetFileName( sIxName ); + if( f.FileExists()){ + + iErrorStop = 110; + iRc = XB_FILE_EXISTS; + throw iRc; + } + } + #endif // XB_NDX_SUPPORT + + // skip past index name + ulPos = sCmd.Pos( ' ' ); + sCmd.Ltrunc( ulPos ); + sCmd.Ltrim(); + + // skip past "ON" + ulPos = sCmd.Pos( ' ' ); + sCmd.Ltrunc( ulPos ); + sCmd.Ltrim(); + + // get the table name + ulPos = sCmd.Pos( '(' ); + sTableName.ExtractElement( sCmd, '(', 1, 0 ); + sTableName.Trim(); + + xbFile fDbf( xbase ); + fDbf.SetFileName( sTableName ); + + // if not open, attempt to open it + dbf = xbase->GetDbfPtr( fDbf.GetFqFileName()); + + if( !dbf ){ + if(( iRc = xbase->OpenHighestVersion( sTableName, "", &dbf )) != XB_NO_ERROR ){ + iErrorStop = 120; + throw iRc; + } + } + + if( dbf == NULL ){ + iErrorStop = 130; + iRc = XB_FILE_NOT_FOUND; + throw iRc; + } + sCmd.Ltrunc( ulPos ); + + //ulPos = sCmd.GetLastPos( ')' ); + xbString sKeyExpression; + xbBool bDone = xbFalse; + xbUInt32 lPos = 1; + xbInt16 iParenCtr = 0; + + while( !bDone && lPos < sCmd.Len()){ + if( sCmd[lPos] == '(' ){ + iParenCtr++; + sKeyExpression.Append( sCmd[lPos] ); + } else if( sCmd[lPos] == ')' ){ + if( iParenCtr > 0 ){ + iParenCtr--; + sKeyExpression.Append( sCmd[lPos] ); + } else { + bDone = xbTrue; + } + } else if( sCmd[lPos] == ',' && iParenCtr == 0 ){ + sKeyExpression.Append( '+' ); + } else if( sCmd[lPos] != ' ' ){ + sKeyExpression.Append( sCmd[lPos] ); + } + lPos++; + } + + // std::cout << "Key Expression =[" << sKeyExpression << "]\n"; + sCmd.Ltrunc( lPos ); + sCmd.Trim(); + + xbBool bDesc = xbFalse; + // std::cout << "sCmd - looking for DESC [" << sCmd << "]\n"; + if( sCmd.Len() > 4 ){ + sNode = sCmd; + sNode.ToUpperCase(); + ulPos = sNode.Pos( "DESC" ); + if( ulPos > 0 ){ + bDesc = xbTrue; + sCmd.Ltrunc( 4 ); + sCmd.Trim(); + std::cout << "Descending\n"; + } + } + + // std::cout << "sCmd - looking for FILTER stuff [" << sCmd << "]\n"; + xbString sFilter; + if( sCmd.Len() > 6 ){ + sNode = sCmd; + sNode.ToUpperCase(); + ulPos = sNode.Pos( "FILTER" ); + if( ulPos > 0 ){ + sFilter = sCmd; + sFilter.Ltrunc( ulPos + 6 ); + sFilter.Trim(); + } + } + // std::cout << "sCmd - FILTER = [" << sFilter << "]\n"; + + #ifdef XB_LOCKING_SUPPORT + if(( iRc = dbf->LockTable( XB_LOCK )) != XB_NO_ERROR ){ + iErrorStop = 140; + throw iRc; + } else { + bTableLocked = xbTrue; + } + #endif // XB_LOCKING_SUPPORT + + xbIx *pIx; + void *vpTag; + + if(( iRc = dbf->CreateTag( sIxType, sIxName, sKeyExpression, sFilter, bDesc, bUnique, xbFalse, &pIx, &vpTag )) != XB_NO_ERROR ){ + iErrorStop = 150; + throw iRc; + } + + #ifdef XB_NDX_SUPPORT + if( sIxType == "NDX"){ + sCmd.Ltrunc( ulPos ); + sCmd.Trim(); + if( sCmd.Len() > 0 ){ + sCmd.ToUpperCase(); + if( sCmd.Pos( "ASSOCIATE" )){ + if(( iRc = dbf->AssociateIndex( "NDX", sIxName, 0 )) != XB_NO_ERROR ){ + iErrorStop = 160; + throw iRc; + } + } + } + } + #endif // XB_NDX_SUPPORT + + if(( iRc = pIx->Reindex( &vpTag )) != XB_NO_ERROR ){ + +// if(( iRc = dbf->Reindex( 2, &vpTag )) != XB_NO_ERROR ){ + iErrorStop = 170; + throw iRc; + } + + + //std::cout << "Tag count = " << pIx->GetTagCount() << "\n"; + // s = pIx->GetTagName( &vpTag ); + // std::cout << "tagname = [" << s.Str() << "]\n"; + + + #ifdef XB_LOCKING_SUPPORT + if( bTableLocked ){ + if(( iRc = dbf->LockTable( XB_UNLOCK )) != XB_NO_ERROR ){ + iErrorStop = 180; + throw iRc; + } else { + bTableLocked = xbFalse; + } + } + #endif // XB_LOCKING_SUPPORT + + } + catch (xbInt16 iRc ){ + xbString sMsg; + sMsg.Sprintf( "xbSql::SqlCreateIndex() Exception Caught. Error Stop = [%d] rc = [%d] table = [%s]", iErrorStop, iRc, sTableName.Str() ); + xbase->WriteLogMessage( sMsg.Str() ); + xbase->WriteLogMessage( GetErrorMessage( iRc )); + } + #ifdef XB_LOCKING_SUPPORT + if( bTableLocked && dbf ) + dbf->LockTable( XB_UNLOCK ); + #endif // XB_LOCKING_SUPPORT + + return iRc; +} +#endif // XB_INDEX_SUPPORT +/***********************************************************************/ +} /* namespace */ +#endif /* XB_SQL_SUPPORT */ + diff --git a/src/include/xbdate.h b/src/include/xbdate.h index 8dff463..e914d65 100755 --- a/src/include/xbdate.h +++ b/src/include/xbdate.h @@ -66,6 +66,7 @@ class XBDLLEXPORT xbDate : public xbSsv { xbDate( const char * Date8 ); xbDate( const xbString &Date8 ); xbDate( xbInt32 lJulDate ); + xbDate( xbUInt16 iInit ); // Constructor used to set the static variables, also defaults to sysdate ~xbDate(); void operator=( const xbDate &d ); @@ -96,6 +97,7 @@ class XBDLLEXPORT xbDate : public xbSsv { const char *Str() const; xbBool IsLeapYear( xbInt16 iYear ) const; xbBool IsLeapYear() const; + xbBool IsNull() const; xbInt32 JulianDays() const; xbInt16 JulToDate8( xbInt32 lJulDate ); xbInt16 LastDayOfMonth(); @@ -111,7 +113,8 @@ class XBDLLEXPORT xbDate : public xbSsv { private: void SetDateTables(); - xbString sDate8; /* CCYYMMDD date format ie; 20140718 */ + xbString sDate8; // CCYYMMDD date format ie; 20140718 + // Null date is identified by sDate.Len() < 8 static int iAggregatedDaysInMonths[2][13]; static int iDaysInMonths[2][13]; diff --git a/src/include/xbdbf.h b/src/include/xbdbf.h index 16799f2..fe24e72 100755 --- a/src/include/xbdbf.h +++ b/src/include/xbdbf.h @@ -164,7 +164,7 @@ class XBDLLEXPORT xbDbf : public xbFile { virtual xbInt16 DeleteAll ( xbInt16 iOption ); virtual xbInt16 DeleteAllRecords (); virtual xbInt16 DeleteRecord (); - virtual xbInt16 DumpHeader ( xbInt16 iOption ) const; + virtual xbInt16 DumpHeader ( xbInt16 iOption ); virtual xbInt16 DumpRecord ( xbUInt32 ulRecNo, xbInt16 iOutputDest = 0, xbInt16 iOutputFmt = 0 ); virtual xbInt16 GetAutoCommit () const; virtual xbInt16 GetAutoCommit ( xbInt16 iOption ) const; @@ -186,7 +186,7 @@ class XBDLLEXPORT xbDbf : public xbFile { virtual xbInt16 GetPrevRecord ( xbInt16 iOption ); virtual xbInt16 GetRecord ( xbUInt32 ulRecNo ); - virtual xbUInt32 GetRecordCount (); + // virtual xbUInt32 GetRecordCount (); virtual xbInt16 GetRecordCnt ( xbUInt32 & ulRecCnt ); virtual char * GetRecordBuf ( xbInt16 iOpt = 0 ) const; @@ -207,7 +207,7 @@ class XBDLLEXPORT xbDbf : public xbFile { virtual xbInt16 PutRecord (); // Put record to current location virtual xbInt16 PutRecord ( xbUInt32 ulRecNo ); - virtual xbInt16 ReadHeader ( xbInt16 iFilePositionOption, xbInt16 iReadOption ); +// virtual xbInt16 ReadHeader ( xbInt16 iFilePositionOption, xbInt16 iReadOption ); virtual xbInt16 RecordDeleted ( xbInt16 iOpt = 0 ) const; virtual xbInt16 Rename ( const xbString sNewName ) = 0; @@ -251,7 +251,7 @@ class XBDLLEXPORT xbDbf : public xbFile { virtual xbInt16 GetLongField( xbInt16 iFieldNo, xbInt32 &lFieldValue ) const; virtual xbInt16 GetLongField( const xbString &sFieldName, xbInt32 &lFieldValue ) const; virtual xbInt16 PutLongField( xbInt16 iFieldNo, xbInt32 lFieldValue ); - virtual xbInt16 PutLongField( const xbString &sFieldNo, xbInt32 lFieldValue ); + virtual xbInt16 PutLongField( const xbString &sFieldName, xbInt32 lFieldValue ); virtual xbInt16 GetULongField( xbInt16 iFieldNo, xbUInt32 &lFieldValue ) const; virtual xbInt16 GetULongField( const xbString &sFieldName, xbUInt32 &lFieldValue ) const; @@ -274,6 +274,10 @@ class XBDLLEXPORT xbDbf : public xbFile { virtual xbInt16 PutDateField( xbInt16 iFieldNo, const xbDate &dt ); virtual xbInt16 PutDateField( const xbString &sFieldName, const xbDate &dt ); + virtual xbInt16 GetNullSts( xbInt16 iFieldNo, xbBool &bIsNull ) const; + virtual xbInt16 GetNullSts( const xbString &sFieldName, xbBool &bIsNull ) const; + virtual xbInt16 GetNullSts( xbInt16 iFieldNo, xbBool &bIsNull, xbInt16 iRecBufSw ) const; + #ifdef XB_MEMO_SUPPORT @@ -282,7 +286,7 @@ class XBDLLEXPORT xbDbf : public xbFile { virtual xbUInt32 GetCreateMemoBlockSize() const; virtual xbInt16 GetMemoField ( xbInt16 iFldNo, xbString &sMemoData ); virtual xbInt16 GetMemoField ( const xbString & sFldName, xbString &sMemoData ); - virtual xbInt16 GetMemoFieldLen ( xbInt16 iFldNo, xbUInt32 &ullMemoFieldLen ); + virtual xbInt16 GetMemoFieldLen ( xbInt16 iFldNo, xbUInt32 &ulMemoFieldLen ); virtual xbInt16 GetMemoFieldLen ( const xbString & sFldName, xbUInt32 &ulMemoFieldLen ); virtual xbBool MemoFieldExists ( xbInt16 iFieldNo ) const; virtual xbBool MemoFieldExists ( const xbString &sFieldName ) const; @@ -347,7 +351,7 @@ class XBDLLEXPORT xbDbf : public xbFile { xbLinkListNode<xbTag *> *GetTagList () const; virtual xbInt16 OpenIndex( const xbString &sIxType, const xbString &sIndexName ); - virtual xbInt16 Reindex( xbInt16 iTagOpt ); + virtual xbInt16 Reindex( xbInt16 iTagOpt = 0, xbInt16 iErrorOpt = 1, xbIx **pIx = NULL, void **vpTag = NULL ); virtual xbInt16 SetCurTag( const xbString &sTagName ); virtual void SetCurTag( const xbString &sIxType, xbIx *pIx, void *vpTag ); @@ -373,14 +377,20 @@ class XBDLLEXPORT xbDbf : public xbFile { #ifdef XB_INDEX_SUPPORT friend class xbIx; friend class xbIxMdx; + friend class xbIxTdx; xbInt16 AddIndex( xbIx *ix, const xbString &sFmt ); void ClearTagList(); xbInt16 RemoveIndex( xbIx * ix ); void UpdateSchemaIxFlag( xbInt16 iFldNo, unsigned char cVal ); + + virtual xbInt16 UpdateTagList (); #endif // XB_INDEX_SUPPORT + virtual xbInt16 ReadHeader ( xbInt16 iFilePositionOption, xbInt16 iReadOption ); + + #ifdef XB_INF_SUPPORT virtual xbInt16 GetInfFileName( xbString &sNdxIdxFileName ); #endif // XB_INF_SUPPORT diff --git a/src/include/xbexp.h b/src/include/xbexp.h index 96413ac..4792b0e 100755 --- a/src/include/xbexp.h +++ b/src/include/xbexp.h @@ -22,6 +22,7 @@ Email Contact: // #pragma interface // #endif +#define XB_NULL_DATE 21474835648 #ifdef XB_FUNCTION_SUPPORT diff --git a/src/include/xbexpnode.h b/src/include/xbexpnode.h index f50d9eb..51efa9b 100755 --- a/src/include/xbexpnode.h +++ b/src/include/xbexpnode.h @@ -103,7 +103,7 @@ class XBDLLEXPORT xbExpNode { xbUInt32 ulResultLen; // for string results, accumulated length of character operations // includes the sum of all nodes under this + this // date = 8, numeric = 4, logical = 1 - xbInt16 iWeight; // used for buildign the tree of nodes, assigned to operators + xbInt16 iWeight; // used for building the tree of nodes, assigned to operators // the higher the number, the lower it goes on the tree }; diff --git a/src/include/xbfile.h b/src/include/xbfile.h index af04e98..e346a75 100755 --- a/src/include/xbfile.h +++ b/src/include/xbfile.h @@ -56,108 +56,109 @@ This class could be used if you want to write a platform independent program tha class XBDLLEXPORT xbFile : public xbSsv { public: - // xbFile(); xbFile( xbXBase * x ); - ~xbFile(); - xbInt16 SetHomeFolders(); - - xbInt16 CreateUniqueFileName( const xbString &sDirIn, const xbString &sExtIn, xbString &sFqnOut ); - xbInt16 CreateUniqueFileName( const xbString &sDirIn, const xbString &sExtIn, xbString &sFqnOut, xbInt16 iOption ); - const xbString& GetDirectory() const; const xbString& GetFileName() const; const xbString& GetFqFileName() const; - void SetDirectory ( const xbString &sDirectory); - void SetFileName ( const xbString &sFileName ); - void SetFqFileName( const xbString &sFqName ); - xbUInt32 GetBlockSize () const; - xbInt16 SetBlockSize ( xbUInt32 ulBlockSize ); + xbInt16 CreateUniqueFileName( const xbString &sDirIn, const xbString &sExtIn, xbString &sFqnOut, xbInt16 iOption = 0 ); + + xbInt16 DetermineXbaseTableVersion( unsigned char cFileTypeByte ) const; + xbInt16 DetermineXbaseMemoVersion( unsigned char cFileTypeByte ) const; + + xbDouble eGetDouble ( const char *p ) const; + xbInt32 eGetInt32 ( const char *p ) const; + xbUInt32 eGetUInt32 ( const char *p ) const; + xbInt16 eGetInt16 ( const char *p ) const; + xbUInt16 eGetUInt16 ( const char *p ) const; + void ePutDouble ( char *p, xbDouble d ); + void ePutInt32 ( char *p, xbInt32 l ); + void ePutUInt32 ( char *p, xbUInt32 ul ); + void ePutInt16 ( char *p, xbInt16 s ); + void ePutUInt16 ( char *p, xbUInt16 s ); + + xbBool FileExists () const; + xbBool FileExists ( xbInt16 iOption ) const; + xbBool FileExists ( const xbString &sFileName ) const; + xbBool FileExists ( const xbString &sFileName, xbInt16 iOption ) const; + xbBool FileIsOpen () const; - xbInt16 GetOpenMode () const; - xbInt16 GetShareMode () const; + xbUInt32 GetBlockSize () const; xbInt16 GetFileDirPart ( xbString &sFileDirPartOut ) const; xbInt16 GetFileDirPart ( const xbString &sCompleteFileNameIn, xbString &sFileDirPartOut ) const; xbInt16 GetFileExtPart ( xbString &sFileExtPartOut ) const; xbInt16 GetFileExtPart ( const xbString &sCompleteFileNameIn, xbString &sFileExtPartOut ) const; + xbInt16 GetFileMtime ( time_t &mtime ); xbInt16 GetFileNamePart( xbString &sFileNamePartOut ) const; xbInt16 GetFileNamePart( const xbString &sCompleteFileNameIn, xbString &sFileNamePartOut ) const; + xbInt16 GetFileSize ( xbUInt64 &ullFileSize ); xbInt16 GetFileType ( xbString &sFileType ) const; + + xbInt16 GetOpenMode () const; + xbInt16 GetShareMode () const; + + xbInt16 GetXbaseFileTypeByte( const xbString &sFileName, xbInt16 &iVersion ); xbInt16 GetXbaseFileTypeByte( const xbString &sFileName, unsigned char &cFileTypeByte ); xbInt16 GetXbaseFileTypeByte( const xbString &sFileName, unsigned char &cFileTypeByte, xbInt16 &iVersion ); - xbInt16 DetermineXbaseTableVersion( unsigned char cFileTypeByte ) const; - xbInt16 DetermineXbaseMemoVersion( unsigned char cFileTypeByte ) const; - xbBool FileExists () const; - xbBool FileExists ( xbInt16 iOption ) const; - xbBool FileExists ( const xbString &sFileName ) const; - xbBool FileExists ( const xbString &sFileName, xbInt16 iOption ) const; + xbInt16 NameSuffixMissing( const xbString &sFileName, xbInt16 iOption ) const; - xbBool FileIsOpen () const; + xbInt16 ReadBlock ( xbUInt32 ulBlockNo, size_t readSize, void *buf ); + xbInt16 ReadBlock ( xbUInt32 ulBlockNo, xbUInt32 ulBlockSize, size_t readSize, void *buf ); - xbInt16 ReadBlock ( xbUInt32 ulBlockNo, size_t readSize, void *buf ); - xbInt16 ReadBlock ( xbUInt32 ulBlockNo, xbUInt32 ulBlockSize, size_t readSize, void *buf ); - xbInt16 WriteBlock( xbUInt32 ulBlockNo, size_t writeSize, void *buf ); - - xbInt16 GetFileSize( xbUInt64 &ullFileSize ); - xbInt16 GetFileMtime( time_t &mtime ); - - xbDouble eGetDouble( const char *p ) const; - xbInt32 eGetInt32 ( const char *p ) const; - xbUInt32 eGetUInt32( const char *p ) const; - xbInt16 eGetInt16 ( const char *p ) const; - xbUInt16 eGetUInt16( const char *p ) const; - void ePutDouble( char *p, xbDouble d ); - void ePutInt32 ( char *p, xbInt32 l ); - void ePutUInt32( char *p, xbUInt32 ul ); - void ePutInt16 ( char *p, xbInt16 s ); - void ePutUInt16( char *p, xbUInt16 s ); - - xbInt16 xbFclose (); - xbInt16 xbFeof (); - xbInt16 xbFflush (); - xbInt16 xbFgetc ( xbInt32 &c ); - xbInt16 xbFgetc ( char &c ); + xbInt16 SetBlockSize ( xbUInt32 ulBlockSize ); + void SetDirectory ( const xbString &sDirectory); + void SetFileName ( const xbString &sFileName ); + void SetFqFileName ( const xbString &sFqName ); + xbInt16 SetHomeFolders(); - #ifdef XB_LOCKING_SUPPORT - xbInt16 xbLock ( xbInt16 iFunction, xbInt64 llOffset, size_t stLen ); - xbInt16 GetLockRetryCount() const; - void SetLockRetryCount( xbInt16 iLockRetries ); - #endif + xbInt16 WriteBlock ( xbUInt32 ulBlockNo, size_t writeSize, void *buf ); - xbInt16 xbFopen ( xbInt16 iOpenMode ); - xbInt16 xbFopen ( const xbString &sOpenMode, xbInt16 iShareMode ); - xbInt16 xbFopen ( xbInt16 iOpenMode, xbInt16 iShareMode ); - xbInt16 xbFopen ( const xbString &sMode, const xbString &sFileName, xbInt16 iShareMode ); + xbInt16 xbFclose (); + xbInt16 xbFeof (); + xbInt16 xbFflush (); + xbInt16 xbFgetc ( xbInt32 &c ); + xbInt16 xbFgetc ( char &c ); + xbInt16 xbFgets ( size_t lSize, xbString &sLine ); - xbInt16 xbFputc ( xbInt32 c ); - xbInt16 xbFputc ( xbInt32 c, xbInt32 iNoTimes ); - xbInt16 xbFputs ( const xbString &s ); - xbInt16 xbFread ( void *ptr, size_t size, size_t nmemb ); - xbInt16 xbFgets ( size_t lSize, xbString &sLine ); - size_t xbFtell (); - xbInt16 xbFseek ( xbInt64 llOffset, xbInt32 whence ); + xbInt16 xbFopen ( xbInt16 iOpenMode ); + xbInt16 xbFopen ( const xbString &sOpenMode, xbInt16 iShareMode ); + xbInt16 xbFopen ( xbInt16 iOpenMode, xbInt16 iShareMode ); + xbInt16 xbFopen ( const xbString &sMode, const xbString &sFileName, xbInt16 iShareMode ); + xbInt16 xbFputc ( xbInt32 c ); + xbInt16 xbFputc ( xbInt32 c, xbInt32 iNoTimes ); + xbInt16 xbFputs ( const xbString &s ); + xbInt16 xbFread ( void *ptr, size_t size, size_t nmemb ); + xbInt16 xbFseek ( xbInt64 llOffset, xbInt32 whence ); + size_t xbFtell (); void xbFTurnOffFileBuffering(); - xbInt16 xbFwrite ( const void *ptr, size_t lSize, size_t lNmemb ); + + xbInt16 xbReadUntil ( const char cDelim, xbString &sOut ); + xbInt16 xbRemove ( const xbString &sFileName, xbInt16 iOption ); + xbInt16 xbRemove ( const xbString &sFileName ); + xbInt16 xbRemove (); - xbInt16 xbReadUntil ( const char cDelim, xbString &sOut ); - xbInt16 xbRemove ( const xbString &sFileName, xbInt16 iOption ); - xbInt16 xbRemove ( const xbString &sFileName ); - xbInt16 xbRemove (); + xbInt16 xbRename ( const xbString &sOldName, const xbString &sNewName ); + void xbRewind (); - xbInt16 xbRename ( const xbString &sOldName, const xbString &sNewName ); - void xbRewind (); + xbInt16 xbFwrite ( const void *ptr, size_t lSize, size_t lNmemb ); - xbInt16 xbTruncate ( xbInt64 llSize ); - xbInt16 NameSuffixMissing( const xbString &sFileName, xbInt16 iOption ) const; + xbInt16 xbTruncate ( xbInt64 llSize ); + + + #ifdef XB_LOCKING_SUPPORT + xbInt16 xbLock ( xbInt16 iFunction, xbInt64 llOffset, size_t stLen ); + xbInt16 GetLockRetryCount() const; + void SetLockRetryCount( xbInt16 iLockRetries ); + #endif #ifdef XB_DEBUG_SUPPORT xbInt16 DumpBlockToDisk( xbUInt32 ulBlockNo, size_t lBlockSize ); diff --git a/src/include/xbindex.h b/src/include/xbindex.h index b42f76e..959562c 100755 --- a/src/include/xbindex.h +++ b/src/include/xbindex.h @@ -167,7 +167,6 @@ class XBDLLEXPORT xbIx : public xbFile { virtual xbBool GetSortOrder( void *vpTag ) const = 0; virtual xbInt16 Open( const xbString &sFileName ); - virtual xbInt16 Reindex( void **vpTag ) = 0; virtual xbInt16 SetCurTag( xbInt16 iTagNo ) = 0; virtual xbInt16 SetCurTag( xbString &sTagName ) = 0; virtual void SetCurTag( void * vpCurTag ); @@ -176,6 +175,10 @@ class XBDLLEXPORT xbIx : public xbFile { virtual void TestStub( char *s, void *vpTag ) {}; + + virtual xbInt16 Reindex( void **vpTag ) = 0; + + #ifdef XB_DEBUG_SUPPORT virtual xbInt16 DumpFreeBlocks( xbInt16 iOpt = 0 ) { return XB_NO_ERROR; } virtual xbInt16 DumpHeader( xbInt16 iDestOpt = 0, xbInt16 iFmtOpt = 0 ) = 0; @@ -199,17 +202,13 @@ class XBDLLEXPORT xbIx : public xbFile { virtual xbInt16 CreateKeys( xbInt16 iOpt ); virtual xbInt16 CreateKey( void * vpTag, xbInt16 iOpt ) = 0; virtual xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo ) = 0; -// virtual xbInt16 DeleteKeys( xbUInt32 ulRecNo ); virtual xbInt16 DeleteKeys(); virtual xbInt16 DeleteKey( void *vpTag ) = 0; - virtual xbInt16 DeleteTag( void *vpTag ) = 0; - virtual xbInt16 FindKeyForCurRec( void *vpTag ) = 0; virtual xbIxNode *FreeNodeChain( xbIxNode *np ); virtual xbInt16 GetBlock( void *vpTag, xbUInt32 ulBlockNo, xbInt16 iOpt, xbUInt32 ulAddlBuf = 0 ); -// virtual xbBool GetIndexUpdated() const = 0; virtual xbInt32 GetKeyCount( xbIxNode *npNode ) const; virtual char *GetKeyData( xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iKeyItemLen ) const; virtual xbInt16 GetKeySts( void *vpTag ) const = 0; @@ -217,9 +216,9 @@ class XBDLLEXPORT xbIx : public xbFile { virtual xbInt16 InsertNodeL( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 uiPtr ) = 0; virtual xbInt16 InsertNodeI( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, xbUInt32 uiPtr ) = 0; virtual xbInt16 KeyExists( void * ) = 0; -// virtual xbInt16 KeyUpdated( void *vpTag ) const = 0; virtual void NodeFree( xbIxNode * ixNode ); virtual xbInt16 ReadHeadBlock( xbInt16 iOpt = 0 ) = 0; + // virtual xbInt16 Reindex( void **vpTag ) = 0; virtual void SetDbf( xbDbf *dbf ); virtual xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ) = 0; virtual xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr ) = 0; @@ -267,7 +266,6 @@ struct XBDLLEXPORT xbNdxTag { char *cpKeyBuf; // key buffer, for searches and adds char *cpKeyBuf2; // key buffer, for deletes xbString sTagName; // tag name - is the file name without the extension -// xbInt16 iKeyUpdated; // key updated? set in method KeyUpdated, checked in AddKey and DeleteKey routines xbBool bFoundSts; // key found? used to determine if new key should be added in XB_EMULATE_DBASE mode in AddKey @@ -307,7 +305,6 @@ class XBDLLEXPORT xbIxNdx : public xbIx { ~xbIxNdx(); xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt ); xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ); -// xbInt16 DeleteTag( void *vpTag ); xbInt16 FindKey( void *vpTag, const void *vpKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ); xbInt16 GetFirstKey( void *vpTag, xbInt16 iRetrieveSw ); @@ -326,12 +323,9 @@ class XBDLLEXPORT xbIxNdx : public xbIx { xbInt16 GetTagCount() const; xbBool GetUnique( void *vpTag = NULL ) const; xbBool GetSortOrder( void *vpTag ) const; - xbInt16 Reindex( void **vpTag ); xbInt16 SetCurTag( xbInt16 iTagNo ); xbInt16 SetCurTag( xbString &sTagName ); - - #ifdef XB_DEBUG_SUPPORT xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL ); xbInt16 DumpHeader( xbInt16 iOpt = 0, xbInt16 iFmt = 0 ); @@ -340,6 +334,9 @@ class XBDLLEXPORT xbIxNdx : public xbIx { xbInt16 DumpNode( void * vpTag, xbIxNode * pNode, xbInt16 iOption ) const; #endif + xbInt16 Reindex( void **vpTag ); + + protected: friend class xbDbf; xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo ); @@ -349,20 +346,16 @@ class XBDLLEXPORT xbIxNdx : public xbIx { xbInt16 CreateKey( void * vpTag, xbInt16 iOpt ); xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo ); xbInt16 DeleteKey( void *vpTag ); - xbInt16 DeleteTag( void *vpTag ); - xbInt16 FindKeyForCurRec( void *vpTag ); -// xbBool GetIndexUpdated() const; xbInt16 GetKeyTypeN( const void *vpTag ) const; xbInt16 GetKeySts( void *vpTag ) const; xbInt16 GetLastKey( xbUInt32 ulNodeNo, void *vpTag, xbInt16 iRetrieveSw = 1 ); xbInt16 InsertNodeI( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, xbUInt32 uiPtr ); xbInt16 InsertNodeL( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 uiPtr ); xbInt16 KeyExists( void *vpTag = NULL ); -// xbBool KeyFiltered( void *vpTag ) const; -// xbInt16 KeyUpdated( void *vpTag ) const; xbInt16 ReadHeadBlock(xbInt16 iOpt); // read the header node of the disk NDX file +// xbInt16 Reindex( void **vpTag ); xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr ); xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ); xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 ); @@ -377,7 +370,6 @@ class XBDLLEXPORT xbIxNdx : public xbIx { xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const; xbInt16 KeySetPosAdd( xbNdxTag *npTag, xbUInt32 ulAddKeyRecNo ); xbInt16 KeySetPosDel( xbNdxTag *npTag ); - // void SetCurNode( void *vpTag, xbIxNode *np ); xbNdxTag *ndxTag; }; @@ -409,7 +401,6 @@ struct XBDLLEXPORT xbMdxTag { // one unused byte fits here char cTag11; // dbase sets to 0x1B - xbInt16 iKeyLen; xbInt16 iKeysPerBlock; xbInt16 iSecKeyType; @@ -418,10 +409,8 @@ struct XBDLLEXPORT xbMdxTag { char cSerialNo; // Increments +1 for each tag update char cUnique; xbString *sKeyExp; // Key expression - char cHasFilter; // 0x00 or 0x01 char cHasKeys; // 0x00 or 0x01 - xbUInt32 ulLeftChild; // dbase 7 sets this to the root page on tag creation xbUInt32 ulRightChild; // dbase 7 sets this to the root page on tag creation @@ -441,12 +430,6 @@ struct XBDLLEXPORT xbMdxTag { char *cpKeyBuf; // key buffer char *cpKeyBuf2; // key buffer -// xbBool iKeyUpdated; // key updated? set in method CreateKey, checked in AddKey and DeleteKey routines - // 0 - no update - // 1 - Add - // 2 - Update - // 3 - Delete -// xbBool bKeyFiltered; // key filtered? True if included key, False if excluded key. Set in method CreateKey, checked in AddKey and DeleteKey routines xbString *sTagName; // string tag name @@ -469,59 +452,67 @@ class XBDLLEXPORT xbIxMdx : public xbIx { public: xbIxMdx( xbDbf * d ); ~xbIxMdx(); - xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt ); - xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ); -// xbInt16 DeleteTag( void *vpTag ); - xbInt16 FindKey( void *vpTag, const void *vKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ); - xbInt16 FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw ); - xbInt16 GetFirstKey( void *vpTag, xbInt16 lRetrieveSw ); - xbString &GetKeyExpression( const void *vpTag ) const; - xbString &GetKeyFilter( const void *vpTag ) const; - char GetKeyType( const void *vpTag ) const; - xbInt16 GetLastKey( void *vpTag, xbInt16 lRetrieveSw ); - xbInt16 GetNextKey( void *vpTag, xbInt16 lRetrieveSw ); - xbInt16 GetPrevKey( void *vpTag, xbInt16 lRetrieveSw ); - xbBool GetReuseEmptyNodesSw() const; - xbBool GetSortOrder( void *vpTag ) const; - void *GetTag( xbInt16 iTagNo ) const; - void *GetTag( xbString &sTagName ) const; - xbInt16 GetTagCount() const; + virtual xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt ); + virtual xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ); + virtual xbInt16 FindKey( void *vpTag, const void *vKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ); + virtual xbInt16 FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw ); + virtual xbInt16 GetFirstKey( void *vpTag, xbInt16 lRetrieveSw ); + virtual xbString &GetKeyExpression( const void *vpTag ) const; + virtual xbString &GetKeyFilter( const void *vpTag ) const; + virtual char GetKeyType( const void *vpTag ) const; + virtual xbInt16 GetLastKey( void *vpTag, xbInt16 lRetrieveSw ); + virtual xbInt16 GetNextKey( void *vpTag, xbInt16 lRetrieveSw ); + virtual xbInt16 GetPrevKey( void *vpTag, xbInt16 lRetrieveSw ); + virtual xbBool GetReuseEmptyNodesSw() const; + virtual xbBool GetSortOrder( void *vpTag ) const; + virtual void *GetTag( xbInt16 iTagNo ) const; + virtual void *GetTag( xbString &sTagName ) const; + virtual xbInt16 GetTagCount() const; - xbString &GetTagName( void *vpTag ) const; - const char * GetTagName( void *vpTag, xbInt16 iOpt ) const; - void GetTagName( void *vpTag, xbString &sTagName ); + virtual xbString &GetTagName( void *vpTag ) const; + virtual const char * GetTagName( void *vpTag, xbInt16 iOpt ) const; + virtual void GetTagName( void *vpTag, xbString &sTagName ); + + virtual xbInt16 GetUnique( void *vpTag ) const; + virtual xbInt16 SetCurTag( xbInt16 iTagNo ); + virtual xbInt16 SetCurTag( xbString &sTagName ); + void SetReuseEmptyNodesSw( xbBool bReuse ); + + void TestStub( char *s, void *vpTag ); - xbInt16 GetUnique( void *vpTag ) const; - xbInt16 Reindex( void **vpTag ); - xbInt16 SetCurTag( xbInt16 iTagNo ); - xbInt16 SetCurTag( xbString &sTagName ); - void SetReuseEmptyNodesSw( xbBool bReuse ); - void TestStub( char *s, void *vpTag ); + virtual xbInt16 Reindex( void **vpTag ); + protected: friend class xbDbf; xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo ); xbIxNode *AllocateIxNode( xbMdxTag * mpTag, xbUInt32 ulBufSize, xbUInt32 ulBlock2 ); + void CalcBtreePointers(); + char CalcTagKeyFmt( xbExp &exp ); + xbInt16 CheckForDupKey( void *vpTag ); - xbInt16 Close(); + virtual xbInt16 Close(); xbInt16 CreateKey( void * vpTag, xbInt16 iOpt ); xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo ); xbInt16 DeleteKey( void *vpTag ); - xbInt16 DeleteTag( void *vpTag ); + virtual xbInt16 DeleteTag( void *vpTag ); xbInt16 FindKeyForCurRec( void *vpTag ); xbInt16 GetKeySts( void *vpTag ) const; xbInt16 GetLastKey( xbUInt32 ulBlockNo, void *vpTag, xbInt16 lRetrieveSw ); void *GetTagTblPtr() const; + + xbInt16 HarvestTagNodes( xbMdxTag *mpTag, xbBool bRecycleRoot = xbFalse ); void Init( xbInt16 iOpt = 0 ); xbInt16 InsertNodeI( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, xbUInt32 uiPtr ); xbInt16 InsertNodeL( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ); xbInt16 KeyExists( void * ); xbInt16 LoadTagTable(); xbInt16 ReadHeadBlock(xbInt16 iOpt); // read the header node of the disk file + //virtual xbInt16 Reindex( void **vpTag ); xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr ); xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ); xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 ); @@ -535,34 +526,10 @@ class XBDLLEXPORT xbIxMdx : public xbIx { void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const; #endif - private: - xbInt16 AddKeyNewRoot( xbMdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight ); - void AppendNodeChain( void *vpTag, xbIxNode *npNode ); - xbUInt32 BlockToPage( xbUInt32 ulBlockNo ); - void CalcBtreePointers(); - char CalcTagKeyFmt( xbExp &exp ); - char CalcTagFwdThread1(); - char CalcTagFwdThread2(); - xbMdxTag *ClearTagTable(); - xbInt16 DumpBlock( xbInt16 iOpt, xbUInt32 ulBlockNo, xbMdxTag * mpTag ); - xbInt16 GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulDbfPtr ) const; - xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const; - xbInt16 GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpKeyBuf ); - xbInt16 HarvestEmptyNode( xbMdxTag *mpTag, xbIxNode *npNode, xbInt16 iOpt, xbBool bHarvestRoot = xbFalse ); - xbInt16 HarvestTagNodes( xbMdxTag *mpTag, xbBool bRecycleRoot = xbFalse ); - xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const; - xbInt16 KeySetPosAdd( xbMdxTag *mpTag, xbUInt32 ulAddKeyRecNo ); - xbInt16 KeySetPosDel( xbMdxTag *mpTag ); - xbInt16 LoadTagDetail( xbInt16 iOption, xbMdxTag *tte ); - xbUInt32 PageToBlock( xbUInt32 ulPageNo ); - xbInt16 TagSerialNo( xbInt16 iOption, xbMdxTag *mpTag ); - xbInt16 UpdateTagSize( xbMdxTag *mpTag, xbUInt32 ulTagSz ); - #ifdef XB_DEBUG_SUPPORT - xbInt16 PrintKey( void *vpTag, xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iDepth, char cType, xbInt16 iOutputOpt ); - #endif + xbMdxTag *mdxTagTbl; - // MDX File Header Fields +// MDX File Header Fields char cVersion; char cCreateYY; char cCreateMM; @@ -588,18 +555,59 @@ class XBDLLEXPORT xbIxMdx : public xbIx { // end of MDX Header fields - - xbMdxTag *mdxTagTbl; - xbBool bReuseEmptyNodes; // Reuese empty MDX nodes when all keys deleted? // DBase 7.x and MS ODBC drivers do not reuse empty nodes, leaves them stranded in the file // Codebase 6.x reuses empty nodes. // Setting this to True will reuse empty nodes in the same manner Codebase 6.x reuses them. + + private: + xbInt16 AddKeyNewRoot( xbMdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight ); + void AppendNodeChain( void *vpTag, xbIxNode *npNode ); + xbUInt32 BlockToPage( xbUInt32 ulBlockNo ); + xbMdxTag *ClearTagTable(); + xbInt16 DumpBlock( xbInt16 iOpt, xbUInt32 ulBlockNo, xbMdxTag * mpTag ); + xbInt16 GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulDbfPtr ) const; + xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const; + xbInt16 GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpKeyBuf ); + xbInt16 HarvestEmptyNode( xbMdxTag *mpTag, xbIxNode *npNode, xbInt16 iOpt, xbBool bHarvestRoot = xbFalse ); + xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const; + xbInt16 KeySetPosAdd( xbMdxTag *mpTag, xbUInt32 ulAddKeyRecNo ); + xbInt16 KeySetPosDel( xbMdxTag *mpTag ); + xbInt16 LoadTagDetail( xbInt16 iOption, xbMdxTag *tte ); + xbUInt32 PageToBlock( xbUInt32 ulPageNo ); + xbInt16 TagSerialNo( xbInt16 iOption, xbMdxTag *mpTag ); + xbInt16 UpdateTagSize( xbMdxTag *mpTag, xbUInt32 ulTagSz ); + + #ifdef XB_DEBUG_SUPPORT + xbInt16 PrintKey( void *vpTag, xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iDepth, char cType, xbInt16 iOutputOpt ); + #endif + + + }; + #endif /* XB_MDX_SUPPORT */ + + +#ifdef XB_TDX_SUPPORT + +class XBDLLEXPORT xbIxTdx : public xbIxMdx { + public: + xbIxTdx( xbDbf * d ); + ~xbIxTdx(); + + xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ); + + protected: + friend class xbDbf; + xbInt16 Close(); + xbInt16 DeleteTag( void *vpTag ); + + private: }; -#endif /* XB_MDX_SUPPORT */ - -} /* namespace xb */ -#endif /* XB_INDEX_SUPPORT */ -#endif /* __XB_INDEX_H__ */ +#endif /* XB_TDX_SUPPORT */ + + + } /* namespace xb */ + #endif /* XB_INDEX_SUPPORT */ +#endif /* __XB_INDEX_H__ */ diff --git a/src/include/xbindex.h.nope b/src/include/xbindex.h.nope new file mode 100755 index 0000000..b42f76e --- /dev/null +++ b/src/include/xbindex.h.nope @@ -0,0 +1,605 @@ +/* xbindex.h + +XBase64 Software Library + +Copyright (c) 1997,2003,2014, 2018, 2022 Gary A Kunkel + +The xb64 software library is covered under the terms of the GPL Version 3, 2007 license. + +Email Contact: + + XDB-devel@lists.sourceforge.net + XDB-users@lists.sourceforge.net + +*/ + + +#ifndef __XB_INDEX_H__ +#define __XB_INDEX_H__ + +#ifdef XB_INDEX_SUPPORT + + +#define XB_ADD_KEY 1 +#define XB_UPD_KEY 2 +#define XB_DEL_KEY 3 + +namespace xb{ + + + +///@cond DOXYOFF +// structure for index nodes, each node contains information regarding one block +struct XBDLLEXPORT xbIxNode { + xbIxNode *npPrev; // pointer to previous node in chain + xbIxNode *npNext; // pointer to next node in chain + xbUInt32 iCurKeyNo; // current key number in the node, 0 offset + xbUInt32 ulBlockNo; // this block number + xbUInt32 ulBufSize; // size of cpBlockData + char *cpBlockData; // pointer to memory version of block data stored in file +}; +///@endcond DOXYOFF + + +//! @brief Base class for handling dbf indices. +/*! + +The xbIx class is used as a base class for accessing index files. +Each index file can have one or more tags. + +Calls to the index routines to perform index updates are handled automatically by the dbf class. +The application program does not need to be concerned with index updates. + +If there is a production MDX index, it is opened automatically when the dbf file is opened. +If there is an ndx file, that has been associated with the dbf file with the metadata routines, +it will be opened automatically when the dbf file is opened. +If there are non prod ndx indices that are not associated with the dbf file, the application +program will need to open as appropriate. +The meta data association logic is specific to the Xbase64 library and is not applicable to +other available tools that handle ndx indices. +All index files are automatically closed when the dbf file is closed. + + +<br> +The class is designed to support the addition of additional indices with a minimal amount of effort +needed to integrate into the library. +If you are looking at adding an new index type to the library, create a derived class using xbIx as a +base class and modify methods needed to support the new index file version. +The xbDbf class (and derived classes) perform the needed calls to the index routines for updates.<br> +See the following for examples on how to start on this:<br> +xbIxNdx is a derived class and supports a single tag.<br> +xbIxMdx is a derived class and supports multiple tags.<br> + + + +<br> +How data fields are stored in index files: +<table> +<tr><th>Field Type<th>Stored in DBF as<th>Stored in NDX as<th>Stored in MDX as</tr> +<tr><td>C<td>char<td>char<td>char +<tr><td>F<td>text numbers<td>xbDouble<td>xbBcd +<tr><td>N<td>text numbers<td>xbDouble<td>xbBcd +<tr><td>D<td>text CCYYMMDD<td>xbDouble - julian<td>xbDouble - julian +</table> + + +<br> +Pages Vs Blocks +<br> +For purposes of the Xbase index classes, a page is considered to be 512 bytes of data +and a block is made up of one or more 512 byte pages. +<br>Default block sixe of NDX indices is one 512 byte page. +<br>Default block size of MDX indices is two 512 byte pages or 1024 bytes. + +<br>The WriteBlock and GetBlock functions calculate the physical position in the +file based on a combination of Block Number and Block Size. Block size is set at +time of index file creation, default is 1024 or two pages. + +<br>Page numbers are stored in the physical file, but block reads and writes +are performed. + +<br> +Duplicate Keys +<br> +With the original DBase unique indexing option, if a table has multiple records with the +same key value, DBase would allow multiple records in the table, but only the first +record would be found in the index. +<br> +XBase64 can be configured to support the original DBase duplicate key implementation, +or can be configured to halt with a DUPLICATE_KEY error on the insertion of a record +with a duplicate key. +<br> +<table> +<tr><th>Option<th>Description</tr> +<tr><td>XB_HALT_ON_DUPKEY</td><td>Return error XB_KEY_NOT_UNIQUE when attempting to append record with duplicate key</td></tr> +<tr><td>XB_EMULATE_DBASE</td><td>Emulate DBase, allow duplicate records with the same key, only the first record is indexed</td></tr> +</table> +*/ + + +class XBDLLEXPORT xbIx : public xbFile { + public: + xbIx( xbDbf * d ); + virtual ~xbIx(); + + virtual xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt ) = 0; + virtual xbInt16 Close(); + virtual xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ) = 0; + virtual xbInt16 FindKey( void *vpTag, const xbString &sKey, xbInt16 iRetrieveSw ); + virtual xbInt16 FindKey( void *vpTag, const char * cKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ); + virtual xbInt16 FindKey( void *vpTag, const xbBcd &bcd, xbInt16 iRetrieveSw ); + virtual xbInt16 FindKey( void *vpTag, const xbDate &dtKey, xbInt16 iRetrieveSw ); + virtual xbInt16 FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw ); + virtual xbInt16 FindKey( void *vpTag, const void *vKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ) = 0; + virtual void *GetCurTag() const; + virtual xbDbf *GetDbf() const; + + virtual xbString &GetKeyExpression( const void *vpTag ) const = 0; + virtual xbString &GetKeyFilter( const void *vpTag ) const = 0; + virtual char GetKeyType( const void *vpTag ) const = 0; + virtual xbBool GetLocked() const; + + virtual xbInt16 GetFirstKey( void *vpTag, xbInt16 iRetrieveSw ) = 0; + virtual xbInt16 GetFirstKey( void *vpTag ); + virtual xbInt16 GetFirstKey(); + + virtual xbInt16 GetLastKey( void *vpTag, xbInt16 lRetrieveSw ) = 0; + virtual xbInt16 GetLastKey( void *vpTag ); + virtual xbInt16 GetLastKey(); + + virtual xbInt16 GetNextKey( void *vpTag, xbInt16 iRetrieveSw ) = 0; + virtual xbInt16 GetNextKey( void *vpTag ); + virtual xbInt16 GetNextKey(); + + virtual xbInt16 GetPrevKey( void *vpTag, xbInt16 iRetrieveSw ) = 0; + virtual xbInt16 GetPrevKey( void *vpTag ); + virtual xbInt16 GetPrevKey(); + + virtual void *GetTag( xbInt16 iTagNo ) const = 0; + virtual void *GetTag( xbString &sTagName ) const = 0; + virtual xbInt16 GetTagCount() const = 0; + + virtual xbString &GetTagName( void *vpTag ) const = 0; + virtual const char * GetTagName( void *vpTag, xbInt16 iOpt ) const = 0; + virtual void GetTagName( void *vpTag, xbString &sTagName ) {}; + + virtual xbBool GetUnique( void *vpTag ) const = 0; + virtual xbBool GetSortOrder( void *vpTag ) const = 0; + + virtual xbInt16 Open( const xbString &sFileName ); + virtual xbInt16 Reindex( void **vpTag ) = 0; + virtual xbInt16 SetCurTag( xbInt16 iTagNo ) = 0; + virtual xbInt16 SetCurTag( xbString &sTagName ) = 0; + virtual void SetCurTag( void * vpCurTag ); + virtual void SetLocked( xbBool bLocked ); + + virtual void TestStub( char *s, void *vpTag ) {}; + + + #ifdef XB_DEBUG_SUPPORT + virtual xbInt16 DumpFreeBlocks( xbInt16 iOpt = 0 ) { return XB_NO_ERROR; } + virtual xbInt16 DumpHeader( xbInt16 iDestOpt = 0, xbInt16 iFmtOpt = 0 ) = 0; + virtual xbInt16 DumpIxForTag( void *vpTag, xbInt16 iOutputOpt ) = 0; + virtual void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const = 0; + virtual xbInt16 DumpNode( void * vpTag, xbIxNode * pNode, xbInt16 iOption ) const; + virtual xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL ) = 0; + + #endif + + protected: + friend class xbDbf; + + virtual xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo ) = 0; + virtual xbInt16 AddKeys( xbUInt32 ulRecNo ); + virtual xbIxNode *AllocateIxNode( xbUInt32 ulBufSize = 0, xbInt16 iOption = 0 ); + virtual xbInt16 BSearchBlock( char cKeyType, xbIxNode *npNode, xbInt32 lKeyLen, const void *vpKey, xbInt32 lSearchKeyLen, xbInt16 &iCompRc, xbBool bDescending = xbFalse ) const; + virtual xbInt16 CheckForDupKeys(); + virtual xbInt16 CheckForDupKey( void *vpTag ) = 0; + virtual xbInt16 CompareKey( char cKeyType, const void *v1, const void *v2, size_t lKeyLen ) const; + virtual xbInt16 CreateKeys( xbInt16 iOpt ); + virtual xbInt16 CreateKey( void * vpTag, xbInt16 iOpt ) = 0; + virtual xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo ) = 0; +// virtual xbInt16 DeleteKeys( xbUInt32 ulRecNo ); + virtual xbInt16 DeleteKeys(); + virtual xbInt16 DeleteKey( void *vpTag ) = 0; + + virtual xbInt16 DeleteTag( void *vpTag ) = 0; + + + virtual xbInt16 FindKeyForCurRec( void *vpTag ) = 0; + virtual xbIxNode *FreeNodeChain( xbIxNode *np ); + virtual xbInt16 GetBlock( void *vpTag, xbUInt32 ulBlockNo, xbInt16 iOpt, xbUInt32 ulAddlBuf = 0 ); +// virtual xbBool GetIndexUpdated() const = 0; + virtual xbInt32 GetKeyCount( xbIxNode *npNode ) const; + virtual char *GetKeyData( xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iKeyItemLen ) const; + virtual xbInt16 GetKeySts( void *vpTag ) const = 0; + virtual xbInt16 GetLastKey( xbUInt32 ulNodeNo, void *vpTag, xbInt16 lRetrieveSw ) = 0; + virtual xbInt16 InsertNodeL( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 uiPtr ) = 0; + virtual xbInt16 InsertNodeI( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, xbUInt32 uiPtr ) = 0; + virtual xbInt16 KeyExists( void * ) = 0; +// virtual xbInt16 KeyUpdated( void *vpTag ) const = 0; + virtual void NodeFree( xbIxNode * ixNode ); + virtual xbInt16 ReadHeadBlock( xbInt16 iOpt = 0 ) = 0; + virtual void SetDbf( xbDbf *dbf ); + virtual xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ) = 0; + virtual xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr ) = 0; + virtual xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 ) = 0; + virtual xbInt16 WriteHeadBlock( xbInt16 iOption ) = 0; + + xbDbf *dbf; + char *cNodeBuf; // pointer to memory for processing in a block of index data + void *vpCurTag; // pointer to active tag. Single index files have only one tag + + private: + virtual void AppendNodeChain( void *vpTag, xbIxNode *npNode ) = 0; + virtual xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const = 0; + virtual xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const = 0; + // virtual void SetCurNode( void *vpTag, xbIxNode *npNode ) = 0; + + xbBool bLocked; // index file locked? +}; + +#ifdef XB_NDX_SUPPORT + +#define XB_NDX_BLOCK_SIZE 512 + + +///@cond DOXYOFF +struct XBDLLEXPORT xbNdxTag { + + // NDX File Header Fields + xbUInt32 ulRootBlock; // header node is 0 + xbUInt32 ulTotalBlocks; // includes header node + char cKeyType; // C = Char, F = Numeric, D = Date + xbInt16 iKeyLen; // length of key data + xbInt16 iKeysPerBlock; // max number keys per block <=100 + xbInt16 iKeyType; // 00 = Char, 01 = Numeric + xbInt16 iKeyItemLen; // KeyLen + 8 bytes + char cSerNo; // rolling incrementing serial number +1 on each index update + xbInt16 iUnique; // True if unique + xbString sKeyExpression; // index expression + // end of NDX Header field + + xbExp *exp; // pointer to expression for expression keys + time_t tNodeChainTs; // node chain time stamp + xbIxNode *npNodeChain; + xbIxNode *npCurNode; + char *cpKeyBuf; // key buffer, for searches and adds + char *cpKeyBuf2; // key buffer, for deletes + xbString sTagName; // tag name - is the file name without the extension +// xbInt16 iKeyUpdated; // key updated? set in method KeyUpdated, checked in AddKey and DeleteKey routines + xbBool bFoundSts; // key found? used to determine if new key should be added in XB_EMULATE_DBASE mode in AddKey + + + xbInt16 iKeySts; // key updated? set in method CreateKey, checked in AddKey and DeleteKey routines + // old key filtered new key filtered iKeySts + // Y Y XB_UPD_KEY 2 - update key if changed (delete and add) + // Y N XB_DEL_KEY 3 - delete key + // N Y XB_ADD_KEY 1 - add key + // N N 0 - no update + +}; +///@endcond DOXYOFF + +//! @brief Class for handling NDX single tag indices. +/*! + +The xbIxNdx class is derived from the xbIx base class and is specific to handling NDX single tag index files. +Each NDX index file can have only one tag, but the methods are set up to take an argument for a specific tag. +This was done in order to provide a consistant interface across index types. + +Calls to the ndx index routines to perform index updates are handled automatically be the dbf class after +the ndx file has been opened. + +Xbase64 provides a mechanism to automatically open ndx files when a dbf file is opened. +If the ndx file has been associated with the dbf file with the metadata routines, +it will be opened automatically when the dbf file is opened. +If there are non prod ndx indices that are not associated with the dbf file, the application +program will need to open as appropriate. +The meta data association logic is specific to the Xbase64 library and is not applicable to +other available tools that handle ndx indices. + +*/ + +class XBDLLEXPORT xbIxNdx : public xbIx { + public: + xbIxNdx( xbDbf * d ); + ~xbIxNdx(); + xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt ); + xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ); +// xbInt16 DeleteTag( void *vpTag ); + xbInt16 FindKey( void *vpTag, const void *vpKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ); + xbInt16 GetFirstKey( void *vpTag, xbInt16 iRetrieveSw ); + + xbInt16 GetLastKey( void *vpTag, xbInt16 iRetrieveSw = 1 ); + xbInt16 GetNextKey( void *vpTag, xbInt16 iRetrieveSw = 1 ); + xbInt16 GetPrevKey( void *vpTag, xbInt16 iRetrieveSw = 1 ); + xbInt32 GetKeyLen ( const void *vpTag ) const; + char GetKeyType ( const void *vpTag ) const; + xbString &GetKeyExpression( const void *vpTag ) const; + xbString &GetKeyFilter( const void *vpTag ) const; + void *GetTag( xbInt16 iTagNo ) const; + void *GetTag( xbString &sTagName ) const; + xbString &GetTagName( void *vpTag ) const; + const char * GetTagName( void *vpTag, xbInt16 iOpt ) const; + + xbInt16 GetTagCount() const; + xbBool GetUnique( void *vpTag = NULL ) const; + xbBool GetSortOrder( void *vpTag ) const; + xbInt16 Reindex( void **vpTag ); + xbInt16 SetCurTag( xbInt16 iTagNo ); + xbInt16 SetCurTag( xbString &sTagName ); + + + + #ifdef XB_DEBUG_SUPPORT + xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL ); + xbInt16 DumpHeader( xbInt16 iOpt = 0, xbInt16 iFmt = 0 ); + xbInt16 DumpIxForTag( void *vpTag, xbInt16 iOutputOpt ); + void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const; + xbInt16 DumpNode( void * vpTag, xbIxNode * pNode, xbInt16 iOption ) const; + #endif + + protected: + friend class xbDbf; + xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo ); + xbIxNode *AllocateIxNode( xbUInt32 ulBufSize = 0, xbInt16 iOption = 0 ); + xbInt16 CheckForDupKey( void *vpTag ); + xbIxNode *CreateIxNode( xbUInt32 ulBufSize ); + xbInt16 CreateKey( void * vpTag, xbInt16 iOpt ); + xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo ); + xbInt16 DeleteKey( void *vpTag ); + + xbInt16 DeleteTag( void *vpTag ); + + xbInt16 FindKeyForCurRec( void *vpTag ); +// xbBool GetIndexUpdated() const; + xbInt16 GetKeyTypeN( const void *vpTag ) const; + xbInt16 GetKeySts( void *vpTag ) const; + xbInt16 GetLastKey( xbUInt32 ulNodeNo, void *vpTag, xbInt16 iRetrieveSw = 1 ); + xbInt16 InsertNodeI( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, xbUInt32 uiPtr ); + xbInt16 InsertNodeL( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo, char * cpKeyBuf, xbUInt32 uiPtr ); + xbInt16 KeyExists( void *vpTag = NULL ); +// xbBool KeyFiltered( void *vpTag ) const; +// xbInt16 KeyUpdated( void *vpTag ) const; + xbInt16 ReadHeadBlock(xbInt16 iOpt); // read the header node of the disk NDX file + xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr ); + xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ); + xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 ); + xbInt16 WriteHeadBlock( xbInt16 iOption ); + + private: + xbInt16 AddKeyNewRoot( xbNdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight ); + void AppendNodeChain( void *vpTag, xbIxNode *npNode ); + xbInt16 GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulDbfPtr ) const; + xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const; + xbInt16 GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpKeyBuf ); + xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const; + xbInt16 KeySetPosAdd( xbNdxTag *npTag, xbUInt32 ulAddKeyRecNo ); + xbInt16 KeySetPosDel( xbNdxTag *npTag ); + // void SetCurNode( void *vpTag, xbIxNode *np ); + xbNdxTag *ndxTag; +}; + +#endif /* XB_NDX_SUPPORT */ + + +#ifdef XB_MDX_SUPPORT +//#define XB_MDX_BLOCK_SIZE 1024 + +struct XBDLLEXPORT xbMdxTag { + + // next 7 fields comprise the tag table entry + xbUInt32 ulTagHdrPageNo; // 512 byte page number, NOT block number + char cTagName[11]; + char cKeyFmt; // always 0x10 w/ DBase V7 + char cLeftChild; // cFwdTagThread + char cRightChild; // cFwdTagThread2 + char cParent; // cBwdTagThread + char c2; + char cKeyType; // C,D,N + + xbUInt32 ulRootPage; // 512 byte page number, NOT block number + xbUInt32 ulTagSize; // Number of 512 byte pages allocated to the tag. Tag size of two is a single 1024 block + + char cKeyFmt2; // 0x10 - base + // 0x08 - descending + // 0x40 - unique + char cKeyType2; + // one unused byte fits here + + char cTag11; // dbase sets to 0x1B + + xbInt16 iKeyLen; + xbInt16 iKeysPerBlock; + xbInt16 iSecKeyType; + xbInt16 iKeyItemLen; // iKeyLen + 4 + + char cSerialNo; // Increments +1 for each tag update + char cUnique; + xbString *sKeyExp; // Key expression + + char cHasFilter; // 0x00 or 0x01 + char cHasKeys; // 0x00 or 0x01 + + xbUInt32 ulLeftChild; // dbase 7 sets this to the root page on tag creation + xbUInt32 ulRightChild; // dbase 7 sets this to the root page on tag creation + + char cTagYY; + char cTagMM; + char cTagDD; + + char cKeyFmt3; // dbase 7 sets this 0x01 if discreet field or 0x00 if calculated or combination field key expression on tag creation + + xbString *sFiltExp; // Filter expression + + time_t tNodeChainTs; + xbIxNode *npNodeChain; + xbIxNode *npCurNode; + xbExp *exp; // pointer to expression for expression based tags + xbExp *filter; // pointer to expression for index filter + + char *cpKeyBuf; // key buffer + char *cpKeyBuf2; // key buffer +// xbBool iKeyUpdated; // key updated? set in method CreateKey, checked in AddKey and DeleteKey routines + // 0 - no update + // 1 - Add + // 2 - Update + // 3 - Delete +// xbBool bKeyFiltered; // key filtered? True if included key, False if excluded key. Set in method CreateKey, checked in AddKey and DeleteKey routines + xbString *sTagName; // string tag name + + + xbMdxTag *next; + xbBool bFoundSts; // key found? used to determine if new key should be added in XB_EMULATE_DBASE mode in AddKey + + + xbInt16 iKeySts; // key updated? set in method CreateKey, checked in AddKey and DeleteKey routines + // old key filtered new key filtered iKeySts + // Y Y XB_UPD_KEY 2 - update key if changed (delete and add) + // Y N XB_DEL_KEY 3 - delete key + // N Y XB_ADD_KEY 1 - add key + // N N 0 - no update + + +}; + + +class XBDLLEXPORT xbIxMdx : public xbIx { + public: + xbIxMdx( xbDbf * d ); + ~xbIxMdx(); + xbInt16 CheckTagIntegrity( void *vpTag, xbInt16 iOpt ); + xbInt16 CreateTag( const xbString &sName, const xbString &sKey, const xbString &sFilter, xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverlay, void **vpTag ); +// xbInt16 DeleteTag( void *vpTag ); + xbInt16 FindKey( void *vpTag, const void *vKey, xbInt32 lKeyLen, xbInt16 iRetrieveSw ); + xbInt16 FindKey( void *vpTag, xbDouble dKey, xbInt16 iRetrieveSw ); + xbInt16 GetFirstKey( void *vpTag, xbInt16 lRetrieveSw ); + xbString &GetKeyExpression( const void *vpTag ) const; + xbString &GetKeyFilter( const void *vpTag ) const; + char GetKeyType( const void *vpTag ) const; + xbInt16 GetLastKey( void *vpTag, xbInt16 lRetrieveSw ); + xbInt16 GetNextKey( void *vpTag, xbInt16 lRetrieveSw ); + xbInt16 GetPrevKey( void *vpTag, xbInt16 lRetrieveSw ); + xbBool GetReuseEmptyNodesSw() const; + xbBool GetSortOrder( void *vpTag ) const; + void *GetTag( xbInt16 iTagNo ) const; + void *GetTag( xbString &sTagName ) const; + xbInt16 GetTagCount() const; + + xbString &GetTagName( void *vpTag ) const; + const char * GetTagName( void *vpTag, xbInt16 iOpt ) const; + void GetTagName( void *vpTag, xbString &sTagName ); + + xbInt16 GetUnique( void *vpTag ) const; + xbInt16 Reindex( void **vpTag ); + xbInt16 SetCurTag( xbInt16 iTagNo ); + xbInt16 SetCurTag( xbString &sTagName ); + void SetReuseEmptyNodesSw( xbBool bReuse ); + + void TestStub( char *s, void *vpTag ); + + protected: + friend class xbDbf; + + xbInt16 AddKey( void *vpTag, xbUInt32 ulRecNo ); + xbIxNode *AllocateIxNode( xbMdxTag * mpTag, xbUInt32 ulBufSize, xbUInt32 ulBlock2 ); + xbInt16 CheckForDupKey( void *vpTag ); + xbInt16 Close(); + xbInt16 CreateKey( void * vpTag, xbInt16 iOpt ); + xbInt16 DeleteFromNode( void *vpTag, xbIxNode * npNode, xbInt16 iSlotNo ); + xbInt16 DeleteKey( void *vpTag ); + + xbInt16 DeleteTag( void *vpTag ); + + xbInt16 FindKeyForCurRec( void *vpTag ); + xbInt16 GetKeySts( void *vpTag ) const; + xbInt16 GetLastKey( xbUInt32 ulBlockNo, void *vpTag, xbInt16 lRetrieveSw ); + void *GetTagTblPtr() const; + void Init( xbInt16 iOpt = 0 ); + xbInt16 InsertNodeI( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, xbUInt32 uiPtr ); + xbInt16 InsertNodeL( void *vpTag, xbIxNode *npNode, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ); + xbInt16 KeyExists( void * ); + xbInt16 LoadTagTable(); + xbInt16 ReadHeadBlock(xbInt16 iOpt); // read the header node of the disk file + xbInt16 SplitNodeI( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, xbUInt32 uiPtr ); + xbInt16 SplitNodeL( void *vpTag, xbIxNode * npLeft, xbIxNode *npRight, xbInt16 iSlotNo, char *cpKeyBuf, xbUInt32 uiPtr ); + xbInt16 UpdateTagKey( char cAction, void *vpTag, xbUInt32 ulRecNo = 0 ); + xbInt16 WriteHeadBlock( xbInt16 iOption ); + + #ifdef XB_DEBUG_SUPPORT + xbInt16 DumpTagBlocks( xbInt16 iOpt = 1, void *vpTag = NULL ); + xbInt16 DumpFreeBlocks( xbInt16 iOpt = 0 ); + xbInt16 DumpHeader( xbInt16 iOpt = 0, xbInt16 iFmtOpt = 0 ); + xbInt16 DumpIxForTag( void *vpTag, xbInt16 iOutputOpt ); + void DumpIxNodeChain( void *vpTag, xbInt16 iOutputOpt ) const; + #endif + + private: + xbInt16 AddKeyNewRoot( xbMdxTag *npTag, xbIxNode *npLeft, xbIxNode *npRight ); + void AppendNodeChain( void *vpTag, xbIxNode *npNode ); + xbUInt32 BlockToPage( xbUInt32 ulBlockNo ); + void CalcBtreePointers(); + char CalcTagKeyFmt( xbExp &exp ); + char CalcTagFwdThread1(); + char CalcTagFwdThread2(); + xbMdxTag *ClearTagTable(); + xbInt16 DumpBlock( xbInt16 iOpt, xbUInt32 ulBlockNo, xbMdxTag * mpTag ); + xbInt16 GetDbfPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulDbfPtr ) const; + xbInt16 GetKeyPtr( void *vpTag, xbInt16 iKeyNo, xbIxNode *npNode, xbUInt32 &ulKeyPtr ) const; + xbInt16 GetLastKeyForBlockNo( void *vpTag, xbUInt32 ulBlockNo, char *cpKeyBuf ); + xbInt16 HarvestEmptyNode( xbMdxTag *mpTag, xbIxNode *npNode, xbInt16 iOpt, xbBool bHarvestRoot = xbFalse ); + xbInt16 HarvestTagNodes( xbMdxTag *mpTag, xbBool bRecycleRoot = xbFalse ); + xbBool IsLeaf( void *vpTag, xbIxNode *npNode ) const; + xbInt16 KeySetPosAdd( xbMdxTag *mpTag, xbUInt32 ulAddKeyRecNo ); + xbInt16 KeySetPosDel( xbMdxTag *mpTag ); + xbInt16 LoadTagDetail( xbInt16 iOption, xbMdxTag *tte ); + xbUInt32 PageToBlock( xbUInt32 ulPageNo ); + xbInt16 TagSerialNo( xbInt16 iOption, xbMdxTag *mpTag ); + xbInt16 UpdateTagSize( xbMdxTag *mpTag, xbUInt32 ulTagSz ); + + #ifdef XB_DEBUG_SUPPORT + xbInt16 PrintKey( void *vpTag, xbIxNode *npNode, xbInt16 iKeyNo, xbInt16 iDepth, char cType, xbInt16 iOutputOpt ); + #endif + + // MDX File Header Fields + char cVersion; + char cCreateYY; + char cCreateMM; + char cCreateDD; + xbString sFileName; + xbInt16 iBlockFactor; // 1-32 #of 512 byte segments in a block + + // use file version + // xbInt16 iBlockSize; // Stored at the xbFile level + + char cProdIxFlag; + char cTagEntryCnt; + xbInt16 iTagLen; + xbInt16 iTagUseCnt; + char cNextTag; // byte 28 +1 + char c1B; // always 0x1B + xbUInt32 ulPageCnt; // number of 512 byte pages in the mdx file + xbUInt32 ulFirstFreePage; // page number corresponding to the next free block + xbUInt32 ulNoOfBlockAvail; // might be improperly named?? not sure how it is used + char cUpdateYY; + char cUpdateMM; + char cUpdateDD; + // end of MDX Header fields + + + + xbMdxTag *mdxTagTbl; + + xbBool bReuseEmptyNodes; // Reuese empty MDX nodes when all keys deleted? + // DBase 7.x and MS ODBC drivers do not reuse empty nodes, leaves them stranded in the file + // Codebase 6.x reuses empty nodes. + // Setting this to True will reuse empty nodes in the same manner Codebase 6.x reuses them. + +}; +#endif /* XB_MDX_SUPPORT */ + + +} /* namespace xb */ +#endif /* XB_INDEX_SUPPORT */ +#endif /* __XB_INDEX_H__ */ diff --git a/src/include/xblog.h b/src/include/xblog.h index e78f476..5c7d721 100755 --- a/src/include/xblog.h +++ b/src/include/xblog.h @@ -44,13 +44,14 @@ class XBDLLEXPORT xbLog : public xbFile { xbLog( const xbString &sLogFileName ); ~xbLog(); - xbInt16 LogClose (); - xbInt16 LogGetStatus (); - xbInt16 LogOpen (); - void LogSetStatus ( xbBool bLogStatus ); - void LogSetLogSize( size_t lSize ); // { LogSize = size; } - xbInt16 LogWrite ( const xbString &LogEntry, xbInt16 iOutputOption = 0 ); - xbInt16 LogWriteBytes( xbUInt32 lByteCnt, const char *p ); + xbInt16 LogClose (); + xbInt16 LogGetStatus (); + xbInt16 LogOpen (); + void LogSetStatus ( xbBool bLogStatus ); + void LogSetLogSize( size_t lSize ); // { LogSize = size; } + xbInt16 LogWrite ( const xbString &LogEntry, xbInt16 iOutputOption = 0 ); + xbInt16 LogWriteBytes( xbUInt32 lByteCnt, const char *p ); + size_t LogGetLogSize() const { return lLogSize; } private: xbBool bLoggingStatus; // false = logging off diff --git a/src/include/xbretcod.h b/src/include/xbretcod.h index ec1f91b..f2885b1 100755 --- a/src/include/xbretcod.h +++ b/src/include/xbretcod.h @@ -24,9 +24,10 @@ namespace xb{ #define XB_NO_ERROR 0 // general #define XB_NO_MEMORY -100 // general #define XB_INVALID_OPTION -101 // general + #define XB_INVALID_PARAMETER -102 // general #define XB_DUP_TABLE_OR_ALIAS -110 // table manager #define XB_INVALID_NODELINK -120 // linklist - #define XB_KEY_NOT_UNIQUE -121 // linklist + #define XB_KEY_NOT_UNIQUE -121 // linklist, index #define XB_MEMCPY_ERROR -122 // memcpy failure #define XB_FILE_EXISTS -200 // file diff --git a/src/include/xbssv.h b/src/include/xbssv.h index d050bcb..3b87a13 100755 --- a/src/include/xbssv.h +++ b/src/include/xbssv.h @@ -64,11 +64,19 @@ class XBDLLEXPORT xbSsv{ void DisplayError ( xbInt16 ErrorCode ) const; xbString& GetDefaultDateFormat () const; xbString& GetDataDirectory () const; - xbInt16 GetEndianType () const; + xbString& GetTempDirectory () const; + + void GetHomeDir ( xbString &sHomeDirOut ); + + xbInt16 GetEndianType () const; const char *GetErrorMessage ( xbInt16 ErrorCode ) const; + char GetPathSeparator () const; + void SetDataDirectory ( const xbString &sDataDirectory ); void SetDefaultDateFormat ( const xbString &sDefaultDateFormat ); + void SetTempDirectory ( const xbString &sTempDirectory ); + xbBool BitSet ( unsigned char c, xbInt16 iBitNo ) const; void BitDump ( unsigned char c ) const; @@ -77,11 +85,11 @@ class XBDLLEXPORT xbSsv{ xbBool GetDefaultAutoCommit () const; void SetDefaultAutoCommit ( xbBool bDefaultAutoCommit ); - void GetHomeDir ( xbString &sHomeDirOut ); - xbString& GetLogDirectory () const; xbString& GetLogFileName () const; void SetLogDirectory ( const xbString &sLogDirectory ); + void SetLogFileName ( const xbString &sLogFileName ); + xbBool GetMultiUser () const; void SetMultiUser ( xbBool bMultiUser ); @@ -127,10 +135,11 @@ class XBDLLEXPORT xbSsv{ static xbString sDefaultDateFormat; static xbString sDataDirectory; //Data file directory + static xbString sTempDirectory; //Temp file directory #ifdef XB_LOGGING_SUPPORT - static xbString sLogDirectory; //Default location to store log files - static xbString sLogFileName; //Default LogFileName + static xbString sLogDirectory; //Default location to store log files + static xbString sLogFileName; //Default LogFileName #endif static xbInt16 iDefaultFileVersion; // 3 = DBase 3 diff --git a/src/include/xbstring.h b/src/include/xbstring.h index 3e70acc..7fe1692 100755 --- a/src/include/xbstring.h +++ b/src/include/xbstring.h @@ -95,8 +95,8 @@ class XBDLLEXPORT xbString { xbString &Append(char c); xbString &Assign(const char *srcStr, xbUInt32 lStartPos, xbUInt32 lCopyLen ); xbString &Assign(const char *srcStr, xbUInt32 lStartPos ); - xbString &Assign(const xbString &s, xbUInt32 pos, xbUInt32 lCopyLen ); - xbString &Assign(const xbString &s, xbUInt32 lCopyLen ); + xbString &Assign(const xbString &s, xbUInt32 ulStartPos, xbUInt32 lCopyLen ); + xbString &Assign(const xbString &s, xbUInt32 ulStartPos ); xbString Copy() const; xbUInt32 CountChar( char c ) const; @@ -112,7 +112,9 @@ class XBDLLEXPORT xbString { void DumpHex( const char *title ) const; #endif + xbString &ExtractElement(xbString &s, char delim, xbUInt32 iCnt, xbInt16 iOpt = 0 ); xbString &ExtractElement(const char *src, char delim, xbUInt32 iCnt, xbInt16 iOpt = 0 ); + char GetCharacter( xbUInt32 lPos ) const; xbUInt32 GetLastPos(char c) const; xbUInt32 GetLastPos(const char *s) const; diff --git a/src/include/xbxbase.h b/src/include/xbxbase.h index fe1f323..702da23 100755 --- a/src/include/xbxbase.h +++ b/src/include/xbxbase.h @@ -126,12 +126,13 @@ class XBDLLEXPORT xbXBase : public xbTblMgr{ ~xbXBase(); xbInt16 CloseAllTables(); + xbInt16 CreateFqn( const xbString &sDirIn, const xbString &sNameIn, const xbString &sExtIn, xbString &sFqfnOut ); void DisableMsgLogging(); void EnableMsgLogging (); xbInt16 FlushLog(); - const xbString &GetLogDirectory () const; - const xbString &GetLogFileName () const; + //const xbString &GetLogDirectory () const; + //const xbString &GetLogFileName () const; const xbString &GetLogFqFileName() const; xbBool GetLogStatus () const; @@ -140,9 +141,13 @@ class XBDLLEXPORT xbXBase : public xbTblMgr{ xbDbf * Open( const xbString &sTableName, xbInt16 &iRc ); xbDbf * Open( const xbString &sTableName, const xbString &sAlias, xbInt16 iOpenMode, xbInt16 iShareMode, xbInt16 iVersion, xbInt16 &iRc ); - void SetLogDirectory( const xbString &sLogFileDirectory ); - void SetLogFileName ( const xbString &sLogFileName ); + + // next three methods moved to xbssv for consistency + // void SetLogDirectory( const xbString &sLogFileDirectory ); + // void SetLogFileName ( const xbString &sLogFileName ); void SetLogSize ( size_t lSize ); + size_t GetLogSize () const; + xbInt16 WriteLogMessage( const xbString &sLogMessage, xbInt16 iOutputOpt = 0 ); xbInt16 WriteLogBytes ( xbUInt32 lCnt, const char *p ); |