summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rwxr-xr-xsrc/include/xbconfig.h.in6
-rwxr-xr-xsrc/include/xbcrix.cpp292
-rwxr-xr-xsrc/include/xbdate.h5
-rwxr-xr-xsrc/include/xbdbf.h22
-rwxr-xr-xsrc/include/xbexp.h1
-rwxr-xr-xsrc/include/xbexpnode.h2
-rwxr-xr-xsrc/include/xbfile.h139
-rwxr-xr-xsrc/include/xbindex.h184
-rwxr-xr-xsrc/include/xbindex.h.nope605
-rwxr-xr-xsrc/include/xblog.h15
-rwxr-xr-xsrc/include/xbretcod.h3
-rwxr-xr-xsrc/include/xbssv.h19
-rwxr-xr-xsrc/include/xbstring.h6
-rwxr-xr-xsrc/include/xbxbase.h13
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 );