summaryrefslogtreecommitdiff
path: root/src/utils/xb_dbfutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/xb_dbfutil.cpp')
-rwxr-xr-xsrc/utils/xb_dbfutil.cpp3719
1 files changed, 3719 insertions, 0 deletions
diff --git a/src/utils/xb_dbfutil.cpp b/src/utils/xb_dbfutil.cpp
new file mode 100755
index 0000000..e008155
--- /dev/null
+++ b/src/utils/xb_dbfutil.cpp
@@ -0,0 +1,3719 @@
+/* xb_dbfutil.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2021 Gary A Kunkel
+
+The xb64 software library is covered under
+the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ xb64-devel@lists.sourceforge.net
+ xb64-users@lists.sourceforge.net
+
+*/
+
+#include "xbase.h"
+
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+using namespace xb;
+
+///@cond DOXYOFF
+class xbUtil{
+ public:
+ xbUtil();
+ ~xbUtil();
+ xbDbf *GetTablePtr( const char * cTitle );
+ void DisplayActiveTable() const;
+
+ // menus
+ xbInt16 GetOption();
+ xbInt32 GetLong();
+ void ProcessOption( const xbString & sOption );
+ void MainMenu();
+ void SystemMenu();
+ void FileMenu();
+ void RecordMenu();
+ void FieldMenu();
+ void IndexMenu();
+ void LockingMenu();
+ void ExpressionMenu();
+ void DebugMenu();
+ void FilterMenu();
+
+ #ifdef XB_SQL_SUPPORT
+ void SqlMenu();
+ #endif // XB_SQL_MENU
+
+ #ifdef XB_NDXINF_SUPPORT
+ void InfFileMenu();
+ #endif // XB_NDXINF_SUPPORT
+
+ // 2 - SystemMenu options
+ void ListSystemSettings();
+ void UpdateDataDirectory();
+ void ToggleDefaultAutoCommit();
+ #ifdef XB_MEMO_SUPPORT
+ void UpdateDefaultMemoBlockSize();
+ #endif
+ void UpdateLogDirectory();
+ void UpdateLogFileName();
+ void ToggleLoggingStatus();
+ void WriteLogMessage();
+ #ifdef XB_LOCKING_SUPPORT
+ void UpdateDefaultLockRetries();
+ void ToggleDefaultAutoLock();
+ void UpdateDefaultLockFlavor();
+ void UpdateDefaultLockWait();
+ void ToggleMultiUserMode();
+ #endif
+
+ // 3 - FileMenu options
+ void ListFilesInDataDirectory();
+ void Open();
+ void Close();
+ void CloseAllTables();
+ void DisplayTableStats();
+ void Pack();
+ void ZapTable();
+ void CopyDbfStructure();
+ void UpdateTableAutoCommit();
+ void DisplayTableInfo();
+
+ // 4 - RecordMenu options
+ void GetRecord();
+ void BlankRecord();
+ void AppendRecord();
+ void PutRecord();
+ void DeleteRecord();
+ void UndeleteRecord();
+ void SelectActiveTable();
+ void GetFirstRecord();
+ void GetNextRecord();
+ void GetPrevRecord();
+ void GetLastRecord();
+ void DumpRecord();
+ void AbortRecord();
+ void CommitRecord();
+
+ #ifdef XB_FILTER_SUPPORT
+ void SetFilter();
+ void GetFirstFilterRec();
+ void GetNextFilterRec();
+ void GetPrevFilterRec();
+ void GetLastFilterRec();
+ #endif // XB_FILTER_SUPPORT
+
+ // 5 - FieldMenu options
+ void ListFieldInfo();
+ void UpdateFieldData();
+ #ifdef XB_MEMO_SUPPORT
+ void ShowMemoFieldData();
+ void UpdateMemoFieldData();
+ void DeleteMemoField();
+ #endif
+
+ // 6 - LockMenu options
+ #ifdef XB_LOCKING_SUPPORT
+ void DisplayFileLockSettings();
+ void UpdateFileLockRetryCount();
+ void UpdateFileLockFlavor();
+ void UpdateFileAutoLock();
+ void LockDbf();
+ void UnlockDbf();
+ void LockRecord();
+ void UnlockRecord();
+ void LockAppend();
+ void UnlockAppend();
+ #ifdef XB_INDEX_SUPPORT
+ void LockIndices();
+ void UnlockIndices();
+ #endif // XB_INDEX_SUPPORT
+
+ #ifdef XB_MEMO_SUPPORT
+ void LockMemo();
+ void UnlockMemo();
+ #endif
+
+ void LockHeader();
+ void UnlockHeader();
+ void xbFileLock();
+ void xbFileUnlock();
+ #endif
+
+ // 7 - Expression Menu options
+ #ifdef XB_EXPRESSION_SUPPORT
+ void ParseExpression( xbInt16 iOption );
+ void ProcessParsedExpression( xbInt16 iOption );
+ void ParseAndProcessExpression();
+ void JulToDate8();
+ void Date8ToJul();
+ void IsLeapYear();
+ #ifdef XB_DEBUG_SUPPORT
+ void DumpExpressionTree();
+ #endif
+ #endif
+
+ // 8 - Index Menu Options
+ #ifdef XB_INDEX_SUPPORT
+ void DisplayOpenIndexFiles();
+ void DisplaySupportedIndexTypes();
+ void SelectTag();
+ void OpenIndex();
+ void CloseIndexFile();
+ void CreateIndexTag();
+
+ void GetFirstKey();
+ void GetNextKey();
+ void GetPrevKey();
+ void GetLastKey();
+ void FindKey();
+
+ void CheckIntegrity();
+ void Reindex();
+ void DeleteTag();
+ void AssociateNonProdIx();
+
+ void DumpIxHeader();
+ void DumpIxNode();
+ void DumpIxNodeChain();
+ void DumpRecsByIx( xbInt16 iOpt );
+ void DumpFreeBlocks();
+
+ #endif // XB_INDEX_SUPPORT
+
+
+ // 9 - SQL Menu Options
+ #ifdef XB_SQL_SUPPORT
+ void ExecSqlNonQuery();
+ void ExecSqlQuery();
+ #endif // XB_SQL_SUPPORT
+
+
+ // 10 - DebugMenu options
+ #ifdef XB_MEMO_SUPPORT
+ void DumpDbtHeader();
+ void DumpMemoFreeChain();
+ #endif
+
+ // 11 - InfFileMenu options
+ #ifdef XB_NDXINF_SUPPORT
+ void ListInfFileData();
+ void AddInfFileData();
+ void DeleteInfFileData();
+ void InfFileHelp();
+ #endif
+
+
+ private:
+ xbXBase x;
+ xbDbf * dActiveTable;
+
+ #ifdef XB_EXPRESSION_SUPPORT
+ xbExp *exp;
+ #endif // XB_EXPRESSION_SUPPORT
+
+ #ifdef XB_SQL_SUPPORT
+ xbSql *sql;
+ #endif // XB_SQL_SUPPORT
+
+ #ifdef XB_FILTER_SUPPORT
+ xbFilter *filt;
+ #endif // XB_FILTER_SUPPORT
+
+};
+
+/*************************************************************************************/
+xbUtil::xbUtil()
+{
+ dActiveTable = NULL;
+ x.EnableMsgLogging();
+ x.SetLogSize( 10000000L );
+
+ #ifdef XB_EXPRESSION_SUPPORT
+ exp = NULL;
+ #endif
+
+ #ifdef XB_SQL_SUPPORT
+ sql = new xbSql( &x );
+ #endif // XB_SQL_SUPPORT
+
+ #ifdef XB_FILTER_SUPPORT
+ filt = NULL;
+ #endif // XB_FILTER_SUPPORT
+}
+
+
+/*************************************************************************************/
+xbUtil::~xbUtil(){
+
+ x.CloseAllTables();
+
+ if( dActiveTable )
+ delete dActiveTable;
+
+ #ifdef XB_SQL_SUPPORT
+ if( sql )
+ delete sql;
+ #endif // XB_SQL_SUPPORT
+
+ #ifdef XB_FILTER_SUPPORT
+ if( filt )
+ delete filt;
+ #endif // XB_FILTER_SUPPORT
+}
+
+/*************************************************************************************/
+#ifdef XB_NDXINF_SUPPORT
+
+void xbUtil::ListInfFileData()
+{
+ xbLinkListNode<xbString> *llN = dActiveTable->GetNdxInfList();
+
+ xbString s;
+ while( llN ){
+ s = llN->GetKey();
+ std::cout << s.Str() << std::endl;
+ llN = llN->GetNextNode();
+ }
+
+}
+
+void xbUtil::AddInfFileData()
+{
+ char cBuf[128];
+ std::cout << "Enter NDX index file name (FILENAME.NDX)" << std::endl;
+ std::cin.getline( cBuf, 128 );
+ xbInt16 iRc = dActiveTable->AssociateIndex( "NDX", cBuf, 0 );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::DeleteInfFileData()
+{
+ char cBuf[128];
+ std::cout << "Enter NDX index file name (FILENAME.NDX)" << std::endl;
+ std::cin.getline( cBuf, 128 );
+ xbInt16 iRc = dActiveTable->AssociateIndex( "NDX", cBuf, 1 );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::InfFileHelp()
+{
+ std::cout << std::endl;
+ std::cout << "Xbase64 uses an .INF file to link non production (NDX) index files to their associated DBF data file" << std::endl;
+}
+#endif // XB_NDXINF_SUPPORT
+
+
+/*************************************************************************************/
+#ifdef XB_INDEX_SUPPORT
+#ifdef XB_LOCKING_SUPPORT
+
+void xbUtil::LockIndices(){
+
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc = dActiveTable->LockIndices( XB_LOCK );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::UnlockIndices(){
+
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc = dActiveTable->LockIndices( XB_UNLOCK );
+ x.DisplayError( iRc );
+}
+
+#endif // XB_LOCKING_SUPPORT
+
+
+/*************************************************************************************/
+void xbUtil::ParseExpression( xbInt16 iOption ){
+
+ if( iOption == 0 )
+ std::cout << "ParseExpression()\n";
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ char sExpression[256];
+ memset( sExpression, 0x00, 256 );
+
+ std::cout << "Enter expresion:\n";
+ std::cin.getline( sExpression, 255 );
+
+ if( strlen( sExpression ) == 0 ){
+ std::cout << "Invalid expression" << std::endl;
+ return;
+ }
+
+ if( exp ){
+ delete exp;
+ exp = NULL;
+ }
+
+ exp = new xbExp( &x, dActiveTable );
+ iRc = exp->ParseExpression( sExpression );
+
+ if( iOption == 0 )
+ x.DisplayError( iRc );
+}
+
+/*************************************************************************************/
+void xbUtil::ProcessParsedExpression( xbInt16 iOption ){
+
+ if( iOption == 0 )
+ std::cout << "ProcessParsedExpression()\n";
+ if( !exp )
+ ParseExpression( iOption );
+ if( !exp )
+ return;
+
+ std::cout << "Dump from w/i dbfutil before processing expression\n";
+ exp->DumpTree( xbTrue );
+ std::cout << "-- end of dumptree in dbfutil before processExpression\n";
+
+ xbInt16 iRc = exp->ProcessExpression();
+ if( iRc != XB_NO_ERROR ){
+ x.DisplayError( iRc );
+ return;
+ }
+
+ std::cout << "Dump from w/i dbfutil after processing expression\n";
+ exp->DumpTree( xbTrue );
+ std::cout << "-- end of dumptree in dbfutil\n";
+
+ xbString sResult;
+ xbDouble dResult;
+ xbDate dtResult;
+ xbBool bResult;
+
+ switch ( exp->GetReturnType()){
+ case XB_EXP_CHAR:
+ exp->GetStringResult( sResult );
+ std::cout << sResult.Str() << "\n";
+ break;
+ case XB_EXP_DATE:
+ exp->GetDateResult( dtResult );
+ std::cout << dtResult.Str() << "\n";
+ break;
+ case XB_EXP_LOGICAL:
+ exp->GetBoolResult( bResult );
+ std::cout << bResult << "\n";
+ break;
+ case XB_EXP_NUMERIC:
+ exp->GetNumericResult( dResult );
+ std::cout << dResult << "\n";
+ break;
+ default:
+ std::cout << "Unknown result type [" << exp->GetReturnType() << std::endl;
+ break;
+ }
+ return;
+}
+
+/*************************************************************************************/
+void xbUtil::ParseAndProcessExpression(){
+ ParseExpression( 1 );
+ if( exp )
+ ProcessParsedExpression( 1 );
+}
+/*************************************************************************************/
+#ifdef XB_DEBUG_SUPPORT
+void xbUtil::DumpExpressionTree(){
+
+ if( exp )
+ exp->DumpTree( xbTrue );
+ else
+ std::cout << "No expression defined\n";
+}
+#endif // XB_DEBUG_SUPPORT
+
+
+void xbUtil::JulToDate8(){
+ std::cout << "Convert Julian Date to Date8 (CCYYMMDD) format" << std::endl;
+ std::cout << "Enter Julian Value" << std::endl;
+ xbInt32 l = GetLong();
+ xbDate d( l );
+ std::cout << "Date8 value = [" << d.Str() << "]" << std::endl;
+}
+
+void xbUtil::Date8ToJul(){
+ char cLine[12];
+ std::cout << "Convert Date8 (CCYYMMDD) format to Julian Date value" << std::endl;
+ std::cout << "Enter Date8 value:" << std::endl;
+ memset( cLine, 0x00, 12 );
+ std::cin.getline( cLine, 9 );
+
+ if( strlen( cLine ) == 8 ){
+ xbDate d( cLine );
+ std::cout << "Julian Value = [" << d.JulianDays() << "]" << std::endl;
+ } else {
+ std::cout << "Invalid length, expecting 8 characters" << std::endl;
+ }
+}
+
+void xbUtil::IsLeapYear(){
+ std::cout << "Check leap year status for a given year" << std::endl;
+ std::cout << "Enter a four digit year" << std::endl;
+ xbInt32 l = GetLong();
+ xbDate d( l );
+ if( d.IsLeapYear( (xbInt16) l ))
+ std::cout << l << " is a leap year" << std::endl;
+ else
+ std::cout << l << " is not a leap year" << std::endl;
+}
+#endif // XB_EXPRESSION_SUPPORT
+/*************************************************************************************/
+#ifdef XB_SQL_SUPPORT
+void xbUtil::ExecSqlNonQuery(){
+
+ xbSql sql( &x );
+ std::cout << "ExecSqlNonQuery\n";
+
+ char sSql[2048];
+ std::cout << "Enter an SQL command (2K max byte max)" << std::endl;
+ std::cin.getline( sSql, 2048 );
+
+ xbInt16 iRc = sql.ExecuteNonQuery( sSql );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::ExecSqlQuery(){
+ std::cout << "ExecSqlQuery\n";
+}
+#endif // XB_SQL_SUPPORT
+
+/*************************************************************************************/
+#ifdef XB_LOCKING_SUPPORT
+void xbUtil::DisplayFileLockSettings(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ std::cout << "File Lock Retry Count = [" << dActiveTable->GetLockRetryCount() << "]" << std::endl;
+ std::cout << "File Lock Flavor = [";
+ switch (dActiveTable->GetLockFlavor()){
+ case 1:
+ std::cout << "Dbase]" << std::endl;
+ break;
+ case 2:
+ std::cout << "Clipper]" << std::endl;
+ break;
+ case 3:
+ std::cout << "Fox]" << std::endl;
+ break;
+ case 9:
+ std::cout << "Xbase64]" << std::endl;
+ break;
+ default:
+ std::cout << "Unknown]" << std::endl;
+ break;
+ }
+ std::cout << "File Auto Lock = [";
+
+ if( dActiveTable->GetAutoLock())
+ std::cout << "ON]" << std::endl;
+ else
+ std::cout << "OFF]" << std::endl;
+ if( dActiveTable->GetHeaderLocked())
+ std::cout << "Header Locked = [TRUE]\n";
+ else
+ std::cout << "Header Locked = [FALSE]\n";
+
+ if( dActiveTable->GetTableLocked())
+ std::cout << "Table Locked = [TRUE]\n";
+ else
+ std::cout << "Table Locked = [FALSE]\n";
+
+ if( dActiveTable->GetAppendLocked() > 0 )
+ std::cout << "Append Locked = [" << dActiveTable->GetAppendLocked() << "]\n";
+ else
+ std::cout << "Append Locked = [FALSE]\n";
+
+ #ifdef XB_MEMO_SUPPORT
+ if( dActiveTable->GetMemoLocked())
+ std::cout << "Memo Locked = [TRUE]\n";
+ else
+ std::cout << "Memo Locked = [FALSE]\n";
+ #endif
+
+ xbLinkListNode<xbUInt32> * llN = dActiveTable->GetFirstRecLock();
+ if( llN ){
+ while( llN ){
+ std::cout << "Record Locked = [" << llN->GetKey() << "]\n";
+ llN = llN->GetNextNode();
+ }
+ } else {
+ std::cout << "Record Locked = [None]\n";
+ }
+}
+
+void xbUtil::UpdateFileLockRetryCount(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ char cBuf[15];
+ std::cout << std::endl << "Enter new File Lock Retry Count: " << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "File Lock Retry Count not updated" << std::endl;
+ return;
+ } else {
+ dActiveTable->SetLockRetryCount( atoi( cBuf ));
+ std::cout << "File Lock Retry Count updated to ["
+ << dActiveTable->GetLockRetryCount() << "]" << std::endl;
+ }
+}
+
+void xbUtil::UpdateFileLockFlavor(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ std::cout << std::endl;
+ std::cout << "Enter new File Lock Flavor: " << std::endl;
+ std::cout << "1 = DBase" << std::endl;
+ std::cout << "2 = Clipper (not implemented yet)" << std::endl;
+ std::cout << "3 = Fox (not implemented yet)" << std::endl;
+ std::cout << "9 = XBase64 (not implemented yet)" << std::endl;
+
+ char cBuf[15];
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "File Lock Flavor not updated" << std::endl;
+ return;
+ } else {
+ dActiveTable->SetLockFlavor( atoi( cBuf ));
+ std::cout << "File Lock Flavor updated to ["
+ << dActiveTable->GetLockFlavor() << "]" << std::endl;
+ }
+}
+
+void xbUtil::UpdateFileAutoLock(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ std::cout << "Enter new File Auto Lock: " << std::endl;
+ std::cout << "-1 = Use System Default" << std::endl;
+ std::cout << " 0 = Disable Auto Lock for this DBF file" << std::endl;
+ std::cout << " 1 = Enable Auto Lock for this DBF file" << std::endl;
+
+ char cBuf[15];
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "File Auto Lock Flavor not updated" << std::endl;
+ return;
+ }
+ xbInt16 iOption = atoi( cBuf );
+ if( iOption < -1 || iOption > 1 ){
+ std::cout << "Must be one of:" << std::endl;
+ std::cout << " -1 = Use Default Auto Lock" << std::endl;
+ std::cout << " 0 = File Auto Lock Off" << std::endl;
+ std::cout << " 1 = File Auto Lock On" << std::endl;
+ std::cout << "File Auto Lock Flavor not updated" << std::endl;
+ return;
+ } else {
+ dActiveTable->SetAutoLock( iOption );
+ std::cout << "File Auto Lock updated to ["
+ << dActiveTable->GetAutoLock() << "]" << std::endl;
+ }
+}
+
+void xbUtil::LockDbf(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ std::cout << std::endl << "Lock Table" << std::endl;
+ iRc = dActiveTable->LockTable( XB_LOCK );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::LockAppend(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ std::cout << std::endl << "Lock Append" << std::endl;
+ iRc = dActiveTable->LockAppend( XB_LOCK );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::UnlockAppend(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ std::cout << std::endl << "Unlock Append" << std::endl;
+ iRc = dActiveTable->LockAppend( XB_UNLOCK );
+ x.DisplayError( iRc );
+}
+#ifdef XB_MEMO_SUPPORT
+void xbUtil::LockMemo(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ std::cout << std::endl << "Lock Memo" << std::endl;
+ iRc = dActiveTable->LockMemo( XB_LOCK );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::UnlockMemo(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ std::cout << std::endl << "Unlock Memo" << std::endl;
+ iRc = dActiveTable->LockMemo( XB_UNLOCK );
+ x.DisplayError( iRc );
+}
+#endif
+
+void xbUtil::LockRecord(){
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ xbInt16 iRc;
+ std::cout << std::endl << "Lock Record" << std::endl;
+ std::cout << "Enter record number to lock specific record" << std::endl;
+
+ char cBuf[15];
+ std::cin.getline( cBuf, 15 );
+ iRc = dActiveTable->LockRecord( XB_LOCK, atol( cBuf ));
+ x.DisplayError( iRc );
+}
+
+void xbUtil::UnlockRecord(){
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ xbInt16 iRc;
+ std::cout << std::endl << "Unlock Record" << std::endl;
+ std::cout << "Enter record number to unlock specific record" << std::endl;
+
+ char cBuf[15];
+ std::cin.getline( cBuf, 15 );
+ iRc = dActiveTable->LockRecord( XB_UNLOCK, atol( cBuf ));
+ x.DisplayError( iRc );
+}
+
+void xbUtil::UnlockDbf(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ xbInt16 iRc;
+ std::cout << std::endl << "Unlock Table" << std::endl;
+ iRc = dActiveTable->LockTable( XB_UNLOCK );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::UnlockHeader(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ xbInt16 iRc;
+ std::cout << std::endl << "Unlock Table Header" << std::endl;
+ iRc = dActiveTable->LockHeader( XB_UNLOCK );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::LockHeader(){
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ xbInt16 iRc;
+ std::cout << std::endl << "Lock Table Header" << std::endl;
+ iRc = dActiveTable->LockHeader( XB_LOCK );
+ x.DisplayError( iRc );
+}
+
+#ifdef XB_DEBUG_SUPPORT
+
+void xbUtil::xbFileLock(){
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ char cBufOffset[30];
+ char cBufLen[30];
+
+ std::cout << std::endl << "Enter new File Lock Offset (in bytes from BOF): " << std::endl;
+ std::cin.getline( cBufOffset, 30 );
+ std::cout << std::endl << "Enter new File Lock Len (in Bytes): " << std::endl;
+ std::cin.getline( cBufLen, 30 );
+
+ if( strlen( cBufOffset ) == 0 || strlen( cBufLen ) == 0 ){
+ std::cout << "Offset and length required." << std::endl;
+ return;
+ }
+
+ xbInt64 llSpos;
+ xbInt64 llLen;
+ xbString s1 = cBufOffset;
+ s1.CvtLongLong( llSpos );
+ s1 = cBufLen;
+ s1.CvtLongLong( llLen );
+ xbInt16 iRc = dActiveTable->xbLock( XB_LOCK, llSpos, (size_t) llLen );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::xbFileUnlock(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ char cBufOffset[30];
+ char cBufLen[30];
+ std::cout << std::endl << "Enter new File Lock Offset (in bytes from BOF): " << std::endl;
+ std::cin.getline( cBufOffset, 30 );
+ std::cout << std::endl << "Enter new File Lock Len (in Bytes): " << std::endl;
+ std::cin.getline( cBufLen, 30 );
+ if( strlen( cBufOffset ) == 0 || strlen( cBufLen ) == 0 ){
+ std::cout << "Offset and length required." << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ iRc = dActiveTable->xbLock( XB_UNLOCK, atol( cBufOffset ), (size_t) atol( cBufLen ));
+ x.DisplayError( iRc );
+}
+
+#endif
+#endif
+/*************************************************************************************/
+#ifdef XB_DEBUG_SUPPORT
+#ifdef XB_MEMO_SUPPORT
+
+void xbUtil::DumpDbtHeader(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ if( !dActiveTable->MemoFieldsExist()){
+ std::cout << "Table has no memo fields" << std::endl;
+ return;
+ }
+
+ xbMemo * mPtr;
+ mPtr = dActiveTable->GetMemoPtr();
+ mPtr->DumpMemoHeader();
+
+}
+#endif
+#endif
+
+/*************************************************************************************/
+#ifdef XB_DEBUG_SUPPORT
+#ifdef XB_MEMO_SUPPORT
+
+void xbUtil::DumpMemoFreeChain(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ if( !dActiveTable->MemoFieldsExist()){
+ std::cout << "Table has no memo fields" << std::endl;
+ return;
+ }
+ xbMemo * mPtr;
+ mPtr = dActiveTable->GetMemoPtr();
+ mPtr->DumpMemoFreeChain();
+}
+#endif
+#endif
+
+/*************************************************************************************/
+void xbUtil::ListFieldInfo(){
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ DisplayActiveTable();
+ dActiveTable->DumpHeader( 2 );
+}
+/*************************************************************************************/
+void xbUtil::UpdateFieldData(){
+ xbInt16 rc;
+ char cFldName[40];
+ char cFldData[256];
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ std::cout << "Enter Field Name " << std::endl;
+ std::cin.getline( cFldName, 40 );
+
+ std::cout << "Enter Field Data " << std::endl;
+ std::cin.getline( cFldData, 256 );
+
+ if(( rc = dActiveTable->PutField( cFldName, cFldData )) != XB_NO_ERROR ){
+ x.DisplayError( rc );
+ return;
+ }
+ std::cout << "Success" << std::endl;
+}
+/*************************************************************************************/
+#ifdef XB_MEMO_SUPPORT
+void xbUtil::ShowMemoFieldData(){
+ xbInt16 rc;
+ char cFldName[40];
+ char cBuf[15];
+ xbString sMemoData;
+ xbUInt32 ulRecNo;
+ xbUInt32 ulFldLen;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ if( !dActiveTable->MemoFieldsExist()){
+ std::cout << "Table has no memo fields" << std::endl;
+ return;
+ }
+ if( dActiveTable->GetCurRecNo() == 0 ){
+ std::cout << "Enter Record number" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Record number not entered" << std::endl;
+ return;
+ }
+ ulRecNo = atol( cBuf );
+ if(( rc = dActiveTable->GetRecord( ulRecNo )) != XB_NO_ERROR ){
+ x.DisplayError( rc );
+ return;
+ }
+ }
+ std::cout << "Enter Memo Field Name " << std::endl;
+ std::cin.getline( cFldName, 40 );
+ if(( rc = dActiveTable->GetMemoField( cFldName, sMemoData )) != XB_NO_ERROR ){
+ std::cout << "rc = " << rc << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+ if(( rc = dActiveTable->GetMemoFieldLen( cFldName, ulFldLen )) != XB_NO_ERROR ){
+ std::cout << "rc = " << rc << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+ std::cout << sMemoData.Str() << std::endl;
+ std::cout << "Data length = [" << ulFldLen << "]" << std::endl;
+}
+#endif
+/*************************************************************************************/
+#ifdef XB_MEMO_SUPPORT
+void xbUtil::UpdateMemoFieldData(){
+
+ xbInt16 rc;
+ char cFldName[40];
+ char cBuf[15];
+ char cMemoData[2048];
+ xbUInt32 ulRecNo;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ if( !dActiveTable->MemoFieldsExist()){
+ std::cout << "Table has no memo fields" << std::endl;
+ return;
+ }
+ if( dActiveTable->GetCurRecNo() == 0 ){
+ std::cout << "Enter Record number" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Record number not entered" << std::endl;
+ return;
+ }
+ ulRecNo = atol( cBuf );
+ if(( rc = dActiveTable->GetRecord( ulRecNo )) != XB_NO_ERROR ){
+ x.DisplayError( rc );
+ return;
+ }
+ }
+ std::cout << "Enter Memo Field Name " << std::endl;
+ std::cin.getline( cFldName, 40 );
+ std::cout << "Enter Memo Data (2048 bytes max) " << std::endl;
+ std::cin.getline( cMemoData, 2048 );
+ if(( rc = dActiveTable->UpdateMemoField( cFldName, cMemoData )) != XB_NO_ERROR ){
+ std::cout << "rc = " << rc << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+
+ if(( rc = dActiveTable->PutRecord( dActiveTable->GetCurRecNo())) != XB_NO_ERROR ){
+ std::cout << "rc = " << rc << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+}
+#endif
+
+/*************************************************************************************/
+#ifdef XB_MEMO_SUPPORT
+void xbUtil::DeleteMemoField(){
+
+ xbInt16 rc;
+ char cFldName[40];
+ char cBuf[15];
+ xbUInt32 ulRecNo;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ if( !dActiveTable->MemoFieldsExist()){
+ std::cout << "Table has no memo fields" << std::endl;
+ return;
+ }
+
+ if( dActiveTable->GetCurRecNo() == 0 ){
+ std::cout << "Enter Record number" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Record number not entered" << std::endl;
+ return;
+ }
+ ulRecNo = atol( cBuf );
+ if(( rc = dActiveTable->GetRecord( ulRecNo )) != XB_NO_ERROR ){
+ x.DisplayError( rc );
+ return;
+ }
+ }
+ std::cout << "Enter Memo Field Name " << std::endl;
+ std::cin.getline( cFldName, 40 );
+ if(( rc = dActiveTable->UpdateMemoField( cFldName, "" )) != XB_NO_ERROR ){
+ std::cout << "rc = " << rc << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+ if(( rc = dActiveTable->PutRecord( dActiveTable->GetCurRecNo())) != XB_NO_ERROR ){
+ std::cout << "rc = " << rc << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+}
+#endif
+/*************************************************************************************/
+void xbUtil::SelectActiveTable(){
+
+ char cBuf[15];
+ xbInt16 iLineNo;
+ if( x.GetOpenTableCount() == 0 ){
+ std::cout << "No open tables" << std::endl;
+ std::cout << "Use menu option =3.4 to open a table" << std::endl;
+ return;
+ }
+
+ x.DisplayTableList();
+ std::cout << std::endl << "Enter line number:" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ iLineNo = atoi( cBuf );
+ dActiveTable = x.GetDbfPtr( iLineNo );
+}
+
+/*************************************************************************************/
+void xbUtil::CommitRecord(){
+
+ xbInt16 rc = XB_NO_ERROR;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ DisplayActiveTable();
+
+ if(( rc = dActiveTable->Commit()) == XB_NO_ERROR )
+ std::cout << "Success" << std::endl;
+ else
+ x.DisplayError( rc );
+}
+/*************************************************************************************/
+void xbUtil::AbortRecord(){
+
+ xbInt16 rc = XB_NO_ERROR;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ DisplayActiveTable();
+
+
+ if(( rc = dActiveTable->Abort()) == XB_NO_ERROR )
+ std::cout << "Success" << std::endl;
+ else
+ x.DisplayError( rc );
+}
+/*************************************************************************************/
+void xbUtil::DumpRecord(){
+
+ char cBuf[15];
+ xbInt16 rc;
+ xbUInt32 lRecNo;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ DisplayActiveTable();
+
+ if( dActiveTable->GetCurRecNo() == 0 ){
+ std::cout << "Enter Record number" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Record number not entered" << std::endl;
+ return;
+ }
+ lRecNo = atol( cBuf );
+ if(( rc = dActiveTable->GetRecord( lRecNo )) != XB_NO_ERROR ){
+ x.DisplayError( rc );
+ return;
+ }
+ }
+
+ if(( rc = dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2 )) == XB_NO_ERROR )
+ std::cout << "Success" << std::endl;
+ else
+ x.DisplayError( rc );
+}
+/*************************************************************************************/
+void xbUtil::GetFirstRecord(){
+
+ xbInt16 iRc;
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ if(( iRc = dActiveTable->GetFirstRecord()) == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+/*************************************************************************************/
+void xbUtil::GetNextRecord(){
+
+ xbInt16 iRc;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ if(( iRc = dActiveTable->GetNextRecord()) == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+/*************************************************************************************/
+void xbUtil::GetPrevRecord(){
+
+ xbInt16 iRc;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ if(( iRc = dActiveTable->GetPrevRecord()) == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+/*************************************************************************************/
+void xbUtil::GetLastRecord(){
+
+ xbInt16 iRc;
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ if(( iRc = dActiveTable->GetLastRecord()) == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(),2);
+ else
+ x.DisplayError( iRc );
+}
+
+/*************************************************************************************/
+void xbUtil::UndeleteRecord(){
+
+ char cBuf[15];
+ xbInt16 rc;
+ xbUInt32 lRecNo;
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ DisplayActiveTable();
+
+ if( dActiveTable->GetCurRecNo() == 0 ){
+ std::cout << "Enter Record number" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Record number not entered" << std::endl;
+ return;
+ }
+ lRecNo = atol( cBuf );
+ if(( rc = dActiveTable->GetRecord( lRecNo )) != XB_NO_ERROR ){
+ x.DisplayError( rc );
+ return;
+ }
+ }
+
+ if(( dActiveTable->RecordDeleted()) == xbFalse )
+ std::cout << "Record is not flagged for deletion" << std::endl;
+ else{
+ if(( rc = dActiveTable->UndeleteRecord()) == XB_NO_ERROR )
+ std::cout << "Success" << std::endl;
+ else
+ x.DisplayError( rc );
+ }
+}
+
+/*************************************************************************************/
+void xbUtil::DeleteRecord(){
+
+ char cBuf[15];
+ xbInt16 rc;
+ xbUInt32 lRecNo;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ DisplayActiveTable();
+ if( dActiveTable->GetCurRecNo() == 0 ){
+ std::cout << "Enter Record number" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Record number not entered" << std::endl;
+ return;
+ }
+ lRecNo = atol( cBuf );
+ if(( rc = dActiveTable->GetRecord( lRecNo )) != XB_NO_ERROR ){
+ x.DisplayError( rc );
+ return;
+ }
+ }
+
+ if(( dActiveTable->RecordDeleted()) == xbTrue )
+ std::cout << "Record is already flagged for deletion" << std::endl;
+ else{
+ if(( rc = dActiveTable->DeleteRecord()) == XB_NO_ERROR )
+ std::cout << "Success" << std::endl;
+ else
+ x.DisplayError( rc );
+ }
+}
+
+/*************************************************************************************/
+void xbUtil::PutRecord(){
+
+ char cBuf[15];
+ xbInt16 rc;
+ xbUInt32 lRecNo;
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ DisplayActiveTable();
+
+ std::cout << "Enter Record number" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Record number not entered" << std::endl;
+ return;
+ }
+ lRecNo = atol( cBuf );
+ if(( rc = dActiveTable->PutRecord( lRecNo )) == XB_NO_ERROR )
+ std::cout << "Success" << std::endl;
+ else
+ x.DisplayError( rc );
+}
+
+/*************************************************************************************/
+void xbUtil::AppendRecord(){
+
+ xbInt16 rc;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ if(( rc = dActiveTable->AppendRecord()) == XB_NO_ERROR )
+ std::cout << "Success" << std::endl;
+ else
+ x.DisplayError( rc );
+}
+
+/*************************************************************************************/
+void xbUtil::BlankRecord(){
+
+ xbInt16 rc;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ if(( rc = dActiveTable->BlankRecord()) == XB_NO_ERROR )
+ std::cout << "Success" << std::endl;
+ else
+ x.DisplayError( rc );
+}
+
+/*************************************************************************************/
+void xbUtil::DisplayTableInfo(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ dActiveTable->DumpHeader( 1 );
+}
+
+/*************************************************************************************/
+void xbUtil::GetRecord(){
+
+ char cBuf[15];
+ xbInt16 iRc;
+ xbUInt32 lRecNo;
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ DisplayActiveTable();
+
+ std::cout << "Enter Record number" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Record number not entered" << std::endl;
+ return;
+ }
+ lRecNo = atol( cBuf );
+ if(( iRc = dActiveTable->GetRecord( lRecNo )) == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+/*************************************************************************************/
+void xbUtil::DisplayActiveTable() const{
+ if( dActiveTable ){
+ std::cout << "Active Table = [" << dActiveTable->GetTblAlias().Str() << "] ";
+ xbUInt32 ulRecCnt = 0;
+ dActiveTable->ReadHeader( 0, 1 );
+ dActiveTable->GetRecordCnt( ulRecCnt );
+ std::cout << "Total Records = [" << ulRecCnt << "] ";
+ std::cout << "Current Record = [" << dActiveTable->GetCurRecNo() << "] ";
+
+ if( dActiveTable->GetAutoCommit())
+ std::cout << " Auto Commit = [Enabled]";
+ else
+ std::cout << " Auto Commit = [Disabled]";
+
+ std::cout << std::endl;
+ #ifdef XB_INDEX_SUPPORT
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( pIx ){
+ void *vpTag = dActiveTable->GetCurTag();
+ std::cout << "Active Tag = [" << pIx->GetTagName( vpTag ).Str() << "] Type = [" << dActiveTable->GetCurIxType().Str() <<
+ "] \tFile Name = [" << pIx->GetFileName().Str() << "] Key = [" << pIx->GetKeyExpression( vpTag ).Str() << "]" << std::endl;
+ }
+ #endif // XB_INDEX_SUPPORT
+ std::cout << std::endl;
+ }
+}
+/*************************************************************************************/
+xbDbf * xbUtil::GetTablePtr( const char * cTitle ){
+
+ xbDbf *d;
+ xbInt16 iOpenTableCnt = x.GetOpenTableCount();
+ char cBuf[15];
+ xbInt16 iLineNo;
+
+ if( iOpenTableCnt == 0 ){
+ std::cout << "No open tables" << std::endl;
+ return NULL;
+ } else if( iOpenTableCnt == 1 ){
+ d = x.GetDbfPtr( 1 );
+ } else {
+ std::cout << "Select file/table " << cTitle << std::endl;
+ x.DisplayTableList();
+ std::cout << std::endl << "Enter line number:" << std::endl;
+ memset( cBuf, 0x00, 15 );
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Table not selected" << std::endl;
+ return NULL;
+ }
+ iLineNo = atoi( cBuf );
+ if( iLineNo < 1 || iLineNo > iOpenTableCnt ){
+ std::cout << "Invalid selection. Valid line numbers are 1 through " << iOpenTableCnt << std::endl;
+ return NULL;
+ }
+ d = x.GetDbfPtr( iLineNo );
+ }
+ return d;
+}
+/*************************************************************************************/
+void xbUtil::UpdateTableAutoCommit(){
+ xbDbf *d;
+ d = GetTablePtr( "" );
+ if( d ){
+ std::cout << "Xbase64 AutoCommit is functionality to determine if table updates should be posted" << std::endl;
+ std::cout << " to the table automatically, even if no xbDbf::PutRecord explicitly executed" << std::endl;
+ std::cout << " If unsure, leave the option turned on at the DBMS level (default)" << std::endl;
+ std::cout << " and don't over ride the setting at the table level" << std::endl << std::endl;
+ std::cout << " -1 ==> Use DBMS setting which is currently [";
+ if( x.GetDefaultAutoCommit() )
+ std::cout << "ON]" << std::endl;
+ else
+ std::cout << "OFF]" << std::endl;
+ std::cout << " 0 ==> Disable Auto Commit for table" << std::endl;
+ std::cout << " 1 ==> Enable Auto Commit for table" << std::endl;
+ std::cout << "Current setting is [" << d->GetAutoCommit() << "]" << std::endl;
+ char cBuf[15];
+ xbInt16 iAuto;
+ std::cout << "Enter new Table Auto Commit: " << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ) {
+ std::cout << "Not updated" << std::endl;
+ return;
+ }
+ iAuto = atoi( cBuf );
+ if( iAuto < -1 || iAuto > 1 ){
+ std::cout << "Invalid value. Must be one of -1, 0 or 1" << std::endl;
+ return;
+ }
+ d->SetAutoCommit( iAuto );
+ std::cout << "Auto Commit set to [" << d->GetAutoCommit(0) << "]" << std::endl;
+ if( d->GetAutoCommit() )
+ std::cout << "Auto Commit enabled for table" << std::endl;
+ else
+ std::cout << "Auto Commit disabled for table" << std::endl;
+ }
+}
+/*************************************************************************************/
+void xbUtil::CopyDbfStructure(){
+ xbDbf *d;
+ xbInt16 rc;
+ char filename[128];
+ xbFile f( &x );
+ xbDbf *dNewTable;
+ d = GetTablePtr( "" );
+
+ if( d ){
+
+ if( d->GetVersion() == 3 ){
+ #ifdef XB_DBF3_SUPPORT
+ dNewTable = new xbDbf3( &x );
+ #else
+ std::cout << "Dbase III file support not build into library. See XB_DBF3_SUPPORT" << std::endl;
+ return;
+ #endif
+ } else if( d->GetVersion() == 4 ){
+ #ifdef XB_DBF4_SUPPORT
+ dNewTable = new xbDbf4( &x );
+ #else
+ std::cout << "Dbase IV file support not build into library. See XB_DBF4_SUPPORT" << std::endl;
+ return;
+ #endif
+ } else {
+ std::cout << "Unsupported file type file = " << d->GetVersion() << std::endl;
+ return;
+ }
+ std::cout << "Copy Table" << std::endl;
+ std::cout << "Enter new DBF file name (ie; myfile.dbf or MYFILE.DBF): ";
+ std::cin.getline( filename, 128 );
+ f.SetFileName( filename );
+ if( strlen( filename ) == 0 ){
+ std::cout << "No file name entered" << std::endl;
+ return;
+ }
+ if(( rc = f.FileExists( f.GetFqFileName() )) == xbTrue ){
+ std::cout << "File [" << f.GetFqFileName().Str() << "] already exists " << std::endl;
+ return;
+ }
+ if(( rc = d->CopyDbfStructure( dNewTable, filename, filename, 0, XB_MULTI_USER )) != XB_NO_ERROR ){
+ std::cout << "Error " << rc << " creating new file" << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+ std::cout << "Table " << f.GetFqFileName().Str() << " created" << std::endl;
+ if(( rc = dNewTable->Close()) != XB_NO_ERROR ){
+ std::cout << "Error " << rc << " closing new file" << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+ }
+}
+/*************************************************************************************/
+void xbUtil::ZapTable(){
+
+ xbInt16 iRc;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ DisplayActiveTable();
+
+ iRc = dActiveTable->Zap();
+ if( iRc == XB_NO_ERROR )
+ std::cout << "Table Zapped (all rows deleted)" << std::endl;
+ else
+ x.DisplayError( iRc );
+}
+/*************************************************************************************/
+void xbUtil::Pack(){
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+ DisplayActiveTable();
+ xbInt16 iRc;
+ iRc = dActiveTable->Pack();
+ if( iRc == XB_NO_ERROR )
+ std::cout << "Table Packed" << std::endl;
+ else
+ x.DisplayError( iRc );
+}
+/*************************************************************************************/
+void xbUtil::DisplayTableStats(){
+
+ xbDbf *d;
+ char cBuf[15];
+ xbInt16 iOptionNo;
+ d = GetTablePtr( "" );
+ if( d ){
+ std::cout << "Enter option" << std::endl;
+ std::cout << "1 - Header data only" << std::endl;
+ std::cout << "2 - Field data only" << std::endl;
+ std::cout << "3 - Header and Field data" << std::endl;
+ std::cout << "4 - Header, Field and Memo Header if applicable" << std::endl;
+ std::cout << "5 - DBMS Settings (not stored in the file)" << std::endl << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Option not entered" << std::endl;
+ return;
+ }
+ iOptionNo = atoi( cBuf );
+ if( iOptionNo < 1 || iOptionNo > 5 ){
+ std::cout << "Invalid option [" << cBuf << "] entered. Defaulting to 1" << std::endl;
+ iOptionNo = 1;
+ }
+ if( iOptionNo < 5 ) {
+ d->ReadHeader( xbTrue, 0 );
+ d->DumpHeader( iOptionNo );
+ } else {
+ // DBMS settings
+ if( d->GetAutoCommit( 0 ) == -1 ){
+ std::cout << "Table Auto Commit = [Use DBMS Setting]" << std::endl;
+ if( x.GetDefaultAutoCommit() )
+ std::cout << "DBMS Auto Commit = [ON]" << std::endl;
+ else
+ std::cout << "DBMS Auto Commit = [OFF]" << std::endl;
+ }
+ else if( d->GetAutoCommit( 0 ) == 0 )
+ std::cout << "Table Auto Commit = [OFF]" << std::endl;
+ else
+ std::cout << "Table Auto Commit = [ON]" << std::endl;
+ }
+ }
+}
+/*************************************************************************************/
+void xbUtil::CloseAllTables(){
+
+ xbInt16 sOpenTableCnt = x.GetOpenTableCount();
+ xbInt16 rc;
+ if( sOpenTableCnt == 0 ){
+ std::cout << "No open tables" << std::endl;
+ return;
+ }
+ rc = x.CloseAllTables();
+ if( rc == XB_NO_ERROR )
+ std::cout << "All open tables closed" << std::endl;
+ else
+ x.DisplayError( rc );
+ dActiveTable = NULL;
+}
+
+/*************************************************************************************/
+void xbUtil::Close(){
+ xbDbf *d;
+// xbInt16 sOpenTableCnt = x.GetOpenTableCount();
+
+ d = GetTablePtr( "to close" );
+ if( d ){
+ d->Close();
+ std::cout << "Table closed" << std::endl;
+ if( d == dActiveTable )
+ dActiveTable = NULL;
+ }
+ else
+ printf( "Can't identify table\n");
+}
+/*************************************************************************************/
+void xbUtil::Open(){
+ xbInt16 rc;
+ xbFile f( &x );
+ xbDbf *dTable;
+ char filename[128];
+ unsigned char cFileTypeByte;
+
+ std::cout << "Open Table" << std::endl;
+ std::cout << "Enter DBF file name (.dbf or .DBF): ";
+ std::cin.getline( filename, 128 );
+ f.SetFileName( filename );
+
+ if( strlen( filename ) == 0 ){
+ std::cout << "No file name entered" << std::endl;
+ return;
+ }
+ if(( rc = f.FileExists( f.GetFqFileName() )) != xbTrue ){
+ std::cout << "File [" << f.GetFqFileName().Str() << "] does not exist " << std::endl;
+ return;
+ }
+ if(( rc = f.GetXbaseFileTypeByte( f.GetFqFileName(), cFileTypeByte )) != XB_NO_ERROR ){
+ std::cout << "Could not open file or determine file type rc = " << rc << " file = " << filename << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+ std:: cout << "File Type Byte ";
+ x.BitDump( cFileTypeByte );
+ std::cout << "\n";
+ std::cout << "Table Type = [" << f.DetermineXbaseTableVersion( cFileTypeByte ) << "]\n";
+ std::cout << "Memo Type = [" << f.DetermineXbaseMemoVersion( cFileTypeByte ) << "]\n";
+
+ if( f.DetermineXbaseTableVersion( cFileTypeByte ) == 4 ){
+ #ifdef XB_DBF4_SUPPORT
+ dTable = new xbDbf4( &x );
+ #else
+ std::cout << "Dbase IV file support not build into library. See XB_DBF4_SUPPORT" << std::endl;
+ return;
+ #endif
+
+ } else if( f.DetermineXbaseTableVersion( cFileTypeByte ) == 3 ){
+ #ifdef XB_DBF3_SUPPORT
+ dTable = new xbDbf3( &x );
+ #else
+ std::cout << "Dbase III file support not build into library. See XB_DBF3_SUPPORT" << std::endl;
+ return;
+ #endif
+ } else {
+ std::cout << "Unsupported file type file = " << filename << " type = ";
+ x.BitDump( cFileTypeByte );
+ std::cout << std::endl;
+ return;
+ }
+
+ if(( rc = dTable->Open( filename )) != 0 ){
+ std::cout << "Could not open file rc = " << rc << " file = " << filename << std::endl;
+ x.DisplayError( rc );
+ return;
+ }
+
+ dActiveTable = dTable;
+ dActiveTable->GetFirstRecord();
+
+ if( dActiveTable )
+ std::cout << dActiveTable->GetTblAlias().Str() << " opened" << std::endl;
+ else
+ std::cout << "dActiveTable not set" << std::endl;
+}
+/*************************************************************************************/
+#ifdef XB_LOCKING_SUPPORT
+void xbUtil::UpdateDefaultLockRetries(){
+ char cBuf[15];
+ std::cout << std::endl << "Enter new Default Lock Retry Count: " << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Default Lock Retry Count not updated" << std::endl;
+ return;
+ } else {
+ x.SetDefaultLockRetries( atoi( cBuf ));
+ std::cout << "Default Lock Retry Count updated to ["
+ << x.GetDefaultLockRetries() << "]" << std::endl;
+ }
+}
+
+void xbUtil::UpdateDefaultLockWait(){
+ char cBuf[15];
+ std::cout << std::endl << "Enter new Default Lock Wait Time (in millisecs 1000=1 second): " << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Default Lock Wait Time not updated" << std::endl;
+ return;
+ } else {
+ x.SetDefaultLockWait( atoi( cBuf ));
+ std::cout << "Default Lock Wait Time updated to ["
+ << x.GetDefaultLockWait() << "]" << std::endl;
+ }
+}
+
+void xbUtil::UpdateDefaultLockFlavor(){
+ char cBuf[15];
+ std::cout << std::endl;
+ std::cout << "Enter new Default Lock Flavor: " << std::endl;
+ std::cout << "1 = DBase" << std::endl;
+ std::cout << "2 = Clipper (not implemented yet)" << std::endl;
+ std::cout << "3 = Fox (not implemented yet)" << std::endl;
+ std::cout << "9 = XBase64 (not implemented yet)" << std::endl;
+ std::cin.getline( cBuf, 15 );
+ if( strlen( cBuf ) == 0 ){
+ std::cout << "Default Lock Flavor not updated" << std::endl;
+ return;
+ } else {
+ x.SetDefaultLockFlavor( atoi( cBuf ));
+ std::cout << "Default Lock Flavor updated to ["
+ << x.GetDefaultLockFlavor() << "]" << std::endl;
+ }
+}
+void xbUtil::ToggleDefaultAutoLock(){
+ if( x.GetDefaultAutoLock()){
+ x.DisableDefaultAutoLock();
+ x.WriteLogMessage( "xb_dbfutil - Default Auto Lock disabled" );
+ std::cout << "Default Auto Lock disabled" << std::endl;
+ } else {
+ x.EnableDefaultAutoLock();
+ x.WriteLogMessage( "xb_dbfutil - Default Auto Lock enabled" );
+ std::cout << "Default Auto Lock enabled" << std::endl;
+ }
+}
+
+void xbUtil::ToggleMultiUserMode(){
+ if( x.GetMultiUser()){
+ x.SetMultiUser( xbFalse );
+ x.WriteLogMessage( "xb_dbfutil - Multi user mode disabled" );
+ std::cout << "Multi user mode disabled" << std::endl;
+ } else {
+ x.SetMultiUser( xbTrue );
+ x.WriteLogMessage( "xb_dbfutil - Multu user mode enabled" );
+ std::cout << "Multi user mode enabled" << std::endl;
+ }
+}
+#endif
+/*************************************************************************************/
+void xbUtil::ListFilesInDataDirectory(){
+ std::cout << "List files for [" << x.GetDataDirectory().Str() << "]" << std::endl << std::endl;
+ xbString s1;
+ xbInt16 iCnt = 0;
+
+#ifdef WIN32
+
+ WIN32_FIND_DATA fData;
+ HANDLE hFile;
+
+ xbString sSearchPath = x.GetDataDirectory();
+ xbUInt32 l = sSearchPath.Len();
+ char cPathSeperator = sSearchPath.GetPathSeparator();
+ char cLastChar = sSearchPath.GetCharacter( l );
+
+ if( cLastChar == cPathSeperator )
+ sSearchPath += "*.*";
+ else if( cPathSeperator ){
+ sSearchPath += cPathSeperator;
+ sSearchPath += "*.*";
+ }
+ else
+ sSearchPath += "\\*.*";
+
+ hFile = FindFirstFile( sSearchPath.Str(), &fData );
+ if( hFile == INVALID_HANDLE_VALUE ){
+ std::cout << "Could not open directory" << std::endl;
+ return;
+ }
+
+ do{
+ s1 = fData.cFileName;
+ if( s1 != "." && s1 != ".." ){
+ std::cout << fData.cFileName << std::endl;
+ iCnt++;
+ }
+ } while( FindNextFile( hFile, &fData ));
+ std::cout << std::endl << iCnt << " entries" << std::endl;
+#else
+ DIR *dir;
+ struct dirent *ent;
+
+ if(( dir = opendir( x.GetDataDirectory() )) != NULL ){
+ while(( ent = readdir( dir )) != NULL ){
+ s1 = ent->d_name;
+ if( s1 != "." && s1 != ".." ){
+ std::cout << ent->d_name << std::endl;
+ iCnt++;
+ }
+ }
+ std::cout << std::endl << iCnt << " entries" << std::endl;
+ closedir( dir );
+ }
+ else
+ std::cout << "Could not open directory" << std::endl;
+#endif
+}
+/*************************************************************************************/
+void xbUtil::UpdateLogDirectory(){
+
+ char cNewDir[256];
+ cNewDir[0] = 0x00;
+ std::cout << std::endl << "Update Log Directory" << std::endl;
+ std::cout << "Current Log File Directory = [" << x.GetLogDirectory().Str() << "]" << std::endl;
+ std::cout << "Enter '1' to erase the Log File Directory" << std::endl;
+ std::cout << "Enter '2' to change Log File Directory to [" << x.GetDefaultLogDirectory().Str() << "]" << std::endl;
+ std::cout << "Enter new log directory. Enter for no updates." << std::endl;
+ std::cin.getline( cNewDir, 256 );
+ if( strlen( cNewDir ) > 0 ){
+ if( cNewDir[0] == '1' )
+ x.SetLogDirectory( "" );
+ else if( cNewDir[0] == '2' )
+ x.SetLogDirectory( x.GetDefaultLogDirectory());
+ else
+ x.SetLogDirectory( cNewDir );
+
+ std::cout << "Log File Directory is [" << x.GetLogDirectory().Str() << "]" << std::endl;
+ }
+ else
+ std::cout << "Log Directory not updated" << std::endl;
+}
+/*************************************************************************************/
+void xbUtil::UpdateLogFileName(){
+ char cNewFile[256];
+ cNewFile[0] = 0x00;
+
+ std::cout << std::endl << "Update Log File Name" << std::endl;
+ std::cout << "Current Log File Name = [" << x.GetLogFileName().Str() << "]" << std::endl;
+ std::cout << "Enter '1' to change change Log File Name to default [" << x.GetDefaultLogFileName().Str() << "]" << std::endl;
+ std::cout << "Enter new Log File Name" << std::endl;
+ std::cin.getline( cNewFile, 256 );
+ if( strlen( cNewFile ) > 0 ){
+ if( cNewFile[0] == '1' )
+ x.SetLogFileName( x.GetDefaultLogFileName());
+ else
+ x.SetLogFileName( cNewFile );
+
+ std::cout << "Log File Name is [" << x.GetLogFileName().Str() << "]" << std::endl;
+ } else
+ std::cout << "Log File Name not updated" << std::endl;
+}
+/*************************************************************************************/
+void xbUtil::WriteLogMessage(){
+ if( x.GetLogStatus()) {
+ char cMsg[256];
+ std::cout << "Enter a message to write to the log file (256 byte max)" << std::endl;
+ std::cin.getline( cMsg, 256 );
+ x.WriteLogMessage( cMsg );
+ } else
+ std::cout << "Logging disabled" << std::endl;
+}
+/*************************************************************************************/
+void xbUtil::ToggleLoggingStatus(){
+ if( x.GetLogStatus()){
+ x.DisableMsgLogging();
+ x.WriteLogMessage( "xb_dbfutil - Logging disabled" );
+ std::cout << "Logging disabled" << std::endl;
+ } else {
+ x.EnableMsgLogging();
+ x.WriteLogMessage( "xb_dbfutil - Logging enabled" );
+ std::cout << "Logging enabled" << std::endl;
+ }
+}
+/*************************************************************************************/
+void xbUtil::ToggleDefaultAutoCommit(){
+ if( x.GetDefaultAutoCommit()){
+ x.SetDefaultAutoCommit( xbFalse );
+ x.WriteLogMessage( "xb_dbfutil - Default Auto Commit disabled" );
+ std::cout << "Default Auto Commit disabled" << std::endl;
+ } else {
+ x.SetDefaultAutoCommit( xbTrue );
+ x.WriteLogMessage( "xb_dbfutil - Default Auto Commit enabled" );
+ std::cout << "Default Auto Commit enabled" << std::endl;
+ }
+}
+/*************************************************************************************/
+void xbUtil::UpdateDataDirectory(){
+ char cNewDir[256];
+ cNewDir[0] = 0x00;
+ std::cout << std::endl << "Update Default Data Directory" << std::endl;
+ std::cout << "Current Default Data Directory = [" << x.GetDataDirectory().Str() << "]" << std::endl;
+ std::cout << "Enter '1' to erase the Default Data Directory" << std::endl;
+ std::cout << "Enter '2' to change Default Data Directory to [" << PROJECT_DATA_DIR << "]" << std::endl;
+ std::cout << "Enter new directory" << std::endl;
+ std::cin.getline( cNewDir, 256 );
+ if( strlen( cNewDir ) > 0 ){
+ if( cNewDir[0] == '1' )
+ x.SetDataDirectory( "" );
+ else if( cNewDir[0] == '2' )
+ x.SetDataDirectory( PROJECT_DATA_DIR );
+ else
+ x.SetDataDirectory( cNewDir );
+ std::cout << "Default Data Directory is [" << x.GetDataDirectory().Str() << "]" << std::endl;
+ }
+ else
+ std::cout << "Default Data Directory not updated" << std::endl;
+}
+/*************************************************************************************/
+void xbUtil::ListSystemSettings(){
+ std::cout << std::endl << "List System Settings" << std::endl;
+ std::cout << "Default Data Directory = [" << x.GetDataDirectory().Str() << "]" << std::endl;
+// std::cout << "Default File Version = [" << x.GetDefaultFileVersion() << "]" << std::endl;
+ #ifdef XB_LOCKING_SUPPORT
+ std::cout << "Default Auto Locking = [";
+ if( x.GetDefaultAutoLock())
+ std::cout << "ON]" << std::endl;
+ else
+ std::cout << "OFF]" << std::endl;
+
+ std::cout << "Default Lock Retries = [" << x.GetDefaultLockRetries() << "]" << std::endl;
+ std::cout << "Default Lock Wait Time = [" << x.GetDefaultLockWait() << "] (millisecs)" << std::endl;
+
+ std::cout << "Default Lock Flavor = [";
+ switch (x.GetDefaultLockFlavor()){
+ case 1:
+ std::cout << "Dbase]" << std::endl;
+ break;
+ case 2:
+ std::cout << "Clipper]" << std::endl;
+ break;
+ case 3:
+ std::cout << "Fox]" << std::endl;
+ break;
+ case 9:
+ std::cout << "Xbase64]" << std::endl;
+ break;
+ default:
+ std::cout << "Unknown]" << std::endl;
+ break;
+ }
+ #endif
+ std::cout << "Default Log Directory = [" << x.GetDefaultLogDirectory().Str() << "]" << std::endl;
+ std::cout << "Default Logfile Name = [" << x.GetDefaultLogFileName().Str() << "]" << std::endl;
+ std::cout << "Default Auto Commit = [";
+ if( x.GetDefaultAutoCommit())
+ std::cout << "ON]" << std::endl;
+ else
+ std::cout << "OFF]" << std::endl;
+
+ std::cout << "Logging Status = [";
+ if( x.GetLogStatus())
+ std::cout << "ON]" << std::endl;
+ else
+ std::cout << "OFF]" << std::endl;
+ std::cout << "Endian Type = [";
+ if( x.GetEndianType() == 'L' )
+ std::cout << "Little Endian]" << std::endl;
+ else
+ std::cout << "Big Endian]" << std::endl;
+
+ if( x.GetMultiUser())
+ std::cout << "Multi User Mode = [ON]";
+ else
+ std::cout << "Multi User Mode = [OFF]";
+}
+/*************************************************************************************/
+/* This method handles all the complex menu option commands */
+void xbUtil::ProcessOption( const xbString &sOption ){
+
+ if( sOption[1] == '=' ){
+ if( sOption == "=0" )
+ MainMenu();
+ else if( sOption == "=0.99" )
+ // exit right now, now cleanup or termination of anything
+ exit(0);
+ else if( sOption == "=2" )
+ SystemMenu();
+ else if( sOption == "=2.1" )
+ ListSystemSettings();
+ else if( sOption == "=2.2" )
+ UpdateDataDirectory();
+ else if( sOption == "=2.3" )
+ ToggleDefaultAutoCommit();
+ else if( sOption == "=2.4" )
+ UpdateLogDirectory();
+ else if( sOption == "=2.5" )
+ UpdateLogFileName();
+ else if( sOption == "=2.6" )
+ ToggleLoggingStatus();
+ else if( sOption == "=2.7" )
+ WriteLogMessage();
+ #ifdef XB_LOCKING_SUPPORT
+ else if( sOption == "=2.8" )
+ UpdateDefaultLockRetries();
+ else if( sOption == "=2.9" )
+ ToggleDefaultAutoLock();
+ else if( sOption == "=2.10" )
+ UpdateDefaultLockFlavor();
+ else if( sOption == "=2.11" )
+ UpdateDefaultLockWait();
+ else if( sOption == "=2.12" )
+ ToggleMultiUserMode();
+ #endif
+ else if( sOption == "=3" )
+ FileMenu();
+ else if( sOption == "=3.1" )
+ ListFilesInDataDirectory();
+ else if( sOption == "=3.2" )
+ UpdateDataDirectory();
+ else if( sOption == "=3.3" )
+ x.DisplayTableList();
+ else if( sOption == "=3.4" )
+ Open();
+ else if( sOption == "=3.5" )
+ Close();
+ else if( sOption == "=3.6" )
+ CloseAllTables();
+ else if( sOption == "=3.7" )
+ SelectActiveTable();
+ else if( sOption == "=3.8" )
+ DisplayTableStats();
+ else if( sOption == "=3.10" )
+ Pack();
+ else if( sOption == "=3.11" )
+ ZapTable();
+ else if( sOption == "=3.12" )
+ CopyDbfStructure();
+ else if( sOption == "=3.13" )
+ UpdateTableAutoCommit();
+ else if( sOption == "=3.14" )
+ DisplayTableInfo();
+ else if( sOption == "=4" )
+ RecordMenu();
+ else if( sOption == "=4.1" )
+ SelectActiveTable();
+ else if( sOption == "=4.2" )
+ GetRecord();
+ else if( sOption == "=4.3" )
+ BlankRecord();
+ else if( sOption == "=4.4" )
+ AppendRecord();
+ else if( sOption == "=4.5" )
+ PutRecord();
+ else if( sOption == "=4.6" )
+ DeleteRecord();
+ else if( sOption == "=4.7" )
+ UndeleteRecord();
+ else if( sOption == "=4.8" )
+ GetFirstRecord();
+ else if( sOption == "=4.9" )
+ GetNextRecord();
+ else if( sOption == "=4.10" )
+ GetPrevRecord();
+ else if( sOption == "=4.11" )
+ GetLastRecord();
+ else if( sOption == "=4.12" )
+ DumpRecord();
+ else if( sOption == "=4.13" )
+ AbortRecord();
+ else if( sOption == "=4.14" )
+ CommitRecord();
+ #ifdef XB_FILTER_SUPPORT
+ else if( sOption == "=4.20" )
+ SetFilter();
+ else if( sOption == "=4.21" )
+ GetFirstFilterRec();
+ else if( sOption == "=4.22" )
+ GetNextFilterRec();
+ else if( sOption == "=4.23" )
+ GetPrevFilterRec();
+ else if( sOption == "=4.24" )
+ GetLastFilterRec();
+ #endif // XB_FILTER_SUPPORT
+ else if( sOption == "=5" )
+ FieldMenu();
+ else if( sOption == "=5.1" )
+ SelectActiveTable();
+ else if( sOption == "=5.2" )
+ ListFieldInfo();
+ else if( sOption == "=5.3" )
+ DumpRecord();
+ else if( sOption == "=5.4" )
+ UpdateFieldData();
+ #ifdef XB_MEMO_SUPPORT
+ else if( sOption == "=5.5" )
+ ShowMemoFieldData();
+ else if( sOption == "=5.6" )
+ UpdateMemoFieldData();
+ else if( sOption == "=5.7" )
+ DeleteMemoField();
+ #endif
+
+ #ifdef XB_LOCKING_SUPPORT
+ else if( sOption == "=6" )
+ LockingMenu();
+ else if( sOption == "=6.1" )
+ DisplayFileLockSettings();
+ else if( sOption == "=6.2" )
+ UpdateFileLockRetryCount();
+ else if( sOption == "=6.3" )
+ UpdateFileLockFlavor();
+ else if( sOption == "=6.4" )
+ UpdateFileAutoLock();
+ else if( sOption == "=6.5" )
+ LockDbf();
+ else if( sOption == "=6.6" )
+ UnlockDbf();
+ else if( sOption == "=6.7" )
+ LockRecord();
+ else if( sOption == "=6.8" )
+ UnlockRecord();
+ else if( sOption == "=6.9" )
+ LockAppend();
+ else if( sOption == "=6.10" )
+ UnlockAppend();
+ else if( sOption == "=6.11" )
+ LockHeader();
+ else if( sOption == "=6.12" )
+ UnlockHeader();
+ #ifdef XB_MEMO_SUPPORT
+ else if( sOption == "=6.13" )
+ LockMemo();
+ else if( sOption == "=6.14" )
+ UnlockMemo();
+ #endif
+
+ #ifdef XB_DEBUG_SUPPORT
+ else if( sOption == "=6.20" )
+ xbFileLock();
+ else if( sOption == "=6.21" )
+ xbFileUnlock();
+ #endif
+ #endif
+
+ #ifdef XB_EXPRESSION_SUPPORT
+ else if( sOption == "=7" )
+ ExpressionMenu();
+ else if( sOption == "=7.1" )
+ ParseExpression( 0 );
+ else if( sOption == "=7.2" )
+ ProcessParsedExpression( 0 );
+ else if( sOption == "=7.3" )
+ ParseAndProcessExpression();
+ #ifdef XB_DEBUG_SUPPORT
+ else if (sOption == "=7.4" )
+ DumpExpressionTree();
+ #endif // XB_DEBUG_SUPPORT
+ else if (sOption == "=7.10" )
+ Date8ToJul();
+ else if (sOption == "=7.11" )
+ JulToDate8();
+ else if (sOption == "=7.12" )
+ IsLeapYear();
+ #endif // XB_EXPRESSION_SUPPORT
+
+ #ifdef XB_INDEX_SUPPORT
+
+ else if( sOption == "=8" )
+ IndexMenu();
+ else if( sOption == "=8.1" )
+ SelectActiveTable();
+ else if( sOption == "=8.2" )
+ DisplayOpenIndexFiles();
+ else if( sOption == "=8.3" )
+ DisplaySupportedIndexTypes();
+ else if( sOption == "=8.4" )
+ SelectTag();
+ else if( sOption == "=8.5" )
+ OpenIndex();
+ else if( sOption == "=8.6" )
+ CloseIndexFile();
+ else if( sOption == "=8.7" )
+ CreateIndexTag();
+ else if( sOption == "=8.8" )
+ GetFirstKey();
+ else if( sOption == "=8.9" )
+ GetPrevKey();
+ else if( sOption == "=8.10" )
+ GetNextKey();
+ else if( sOption == "=8.11" )
+ GetLastKey();
+ else if( sOption == "=8.12" )
+ FindKey();
+
+ else if( sOption == "=8.13" )
+ CheckIntegrity();
+ else if( sOption == "=8.14" )
+ Reindex();
+ else if( sOption == "=8.15" )
+ DeleteTag();
+ else if( sOption == "=8.16" )
+ AssociateNonProdIx();
+
+ #ifdef XB_DEBUG_SUPPORT
+ else if( sOption == "=8.20" )
+ DumpIxHeader();
+ else if( sOption == "=8.21" )
+ DumpIxNode();
+ else if( sOption == "=8.22" )
+ DumpIxNodeChain();
+ else if( sOption == "=8.23" )
+ DumpRecsByIx(0);
+ else if( sOption == "=8.24" )
+ DumpRecsByIx(1);
+ else if( sOption == "=8.25" )
+ DumpFreeBlocks();
+ #endif // XB_DEBUG_SUPPORT
+ #endif // XB_INDEX_SUPPORT
+
+ #ifdef XB_SQL_SUPPORT
+ else if( sOption == "=10" )
+ SqlMenu();
+ else if( sOption == "=10.1" )
+ ExecSqlNonQuery();
+ else if( sOption == "=10.2" )
+ ExecSqlQuery();
+ #endif // XB_SQL_SUPPORT
+
+ #ifdef XB_NDXINF_SUPPORT
+ else if( sOption == "=11" )
+ InfFileMenu();
+ else if( sOption == "=11.1" )
+ ListInfFileData();
+ else if( sOption == "=11.2" )
+ AddInfFileData();
+ else if( sOption == "=11.3" )
+ DeleteInfFileData();
+ else if( sOption == "=11.10" )
+ InfFileHelp();
+ #endif // XB_NDXINF_SUPPORT
+
+ #ifdef XB_DEBUG_SUPPORT
+ else if( sOption == "=20" )
+ DebugMenu();
+ else if( sOption == "=20.1" )
+ SelectActiveTable();
+/*
+ #ifdef XB_MEMO_SUPPORT
+ else if( sOption == "=10.2" )
+ DumpDbtHeader();
+ else if( sOption == "=10.3" )
+ DumpMemoFreeChain();
+ #endif
+*/
+
+ #endif
+ else
+ return;
+ }
+}
+
+/*************************************************************************************/
+xbInt32 xbUtil::GetLong(){
+ char cLine[256];
+ xbString sLine;
+ memset( cLine, 0x00, 256 );
+ std::cin.getline( cLine, 256 );
+ sLine = cLine;
+ sLine.Trim();
+ return atol( cLine );
+}
+/*************************************************************************************/
+xbInt16 xbUtil::GetOption(){
+ char cLine[256];
+ xbString sLine;
+ memset( cLine, 0x00, 256 );
+ std::cin.getline( cLine, 256 );
+ sLine = cLine;
+ sLine.Trim();
+
+ if( sLine[1] == '=' || sLine.Pos(".") != 0 ){
+ ProcessOption( sLine );
+ return 0;
+ }
+ else
+ return atoi( cLine );
+}
+/************************************************************************/
+#ifdef XB_INDEX_SUPPORT
+void xbUtil::IndexMenu()
+{
+ int option = 0;
+
+ while( option != 99 ) {
+
+ std::cout << std::endl << std::endl << " 8 - Index Menu" << std::endl;
+ std::cout << "---------------------" << std::endl;
+ DisplayActiveTable();
+
+ std::cout << " 1 - Select Active Table" << std::endl;
+ std::cout << " 2 - Display Open Index Files" << std::endl;
+ std::cout << " 3 - Display Supported Index Types" << std::endl;
+ std::cout << " 4 - Select Active Tag" << std::endl;
+ std::cout << " 5 - Open Index File" << std::endl;
+ std::cout << " 6 - Close Index File" << std::endl;
+ std::cout << " 7 - Create Index Tag" << std::endl;
+ std::cout << " 8 - Get First Key" << std::endl;
+ std::cout << " 9 - Get Next Key" << std::endl;
+ std::cout << " 10 - Get Prev Key" << std::endl;
+ std::cout << " 11 - Get Last Key" << std::endl;
+ std::cout << " 12 - Find Key" << std::endl;
+ std::cout << " 13 - Check Index Integrity" << std::endl;
+ std::cout << " 14 - Reindex" << std::endl;
+ std::cout << " 15 - Delete Tag" << std::endl;
+ std::cout << " 16 - Associate NDX file" << std::endl;
+
+ #ifdef XB_DEBUG_SUPPORT
+ std::cout << std::endl;
+ std::cout << " 20 - Dump Header" << std::endl;
+ std::cout << " 21 - Dump Node(s)" << std::endl;
+ std::cout << " 22 - Dump Node Chain" << std::endl;
+ std::cout << " 23 - Dump Recs by Tag Fwd" << std::endl;
+ std::cout << " 24 - Dump Recs by Tag Bwd" << std::endl;
+ std::cout << " 25 - Dump Free Blocks / MDX ulBlock2" << std::endl;
+ #endif // XB_DEBUG_SUPPORT
+
+ std::cout << std::endl;
+ std::cout << std::endl;
+
+ std::cout << " 99 - Exit Menu" << std::endl;
+ option = GetOption();
+
+ switch( option ){
+ case 0: break;
+ case 1: SelectActiveTable(); break;
+ case 2: DisplayOpenIndexFiles(); break;
+ case 3: DisplaySupportedIndexTypes(); break;
+ case 4: SelectTag(); break;
+ case 5: OpenIndex(); break;
+ case 6: CloseIndexFile(); break;
+ case 7: CreateIndexTag(); break;
+
+ case 8: GetFirstKey(); break;
+ case 9: GetNextKey(); break;
+ case 10: GetPrevKey(); break;
+ case 11: GetLastKey(); break;
+
+ case 12: FindKey(); break;
+ case 13: CheckIntegrity(); break;
+ case 14: Reindex(); break;
+ case 15: DeleteTag(); break;
+ case 16: AssociateNonProdIx(); break;
+
+ #ifdef XB_DEBUG_SUPPORT
+ case 20: DumpIxHeader(); break;
+ case 21: DumpIxNode(); break;
+ case 22: DumpIxNodeChain(); break;
+ case 23: DumpRecsByIx(0); break;
+ case 24: DumpRecsByIx(1); break;
+ case 25: DumpFreeBlocks(); break;
+ #endif
+
+ case 99: break;
+ default: std::cout << "Invalid option" << std::endl; break;
+ }
+ }
+}
+#endif
+/************************************************************************/
+#ifdef XB_EXPRESSION_SUPPORT
+void xbUtil::ExpressionMenu()
+{
+ int option = 0;
+
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << " 7 - Expression Menu" << std::endl;
+ std::cout << " --------------" << std::endl;
+ DisplayActiveTable();
+ std::cout << " 1 - Parse Expression" << std::endl;
+ std::cout << " 2 - Process Parsed Expression" << std::endl;
+ std::cout << " 3 - Parse and Process Expression" << std::endl;
+ #ifdef XB_DEBUG_SUPPORT
+ std::cout << " 4 - Dump Expression Internals" << std::endl;
+ #endif
+ std::cout << " 10 - Date8 To Julian Date" << std::endl;
+ std::cout << " 11 - Julian Date to Date8" << std::endl;
+ std::cout << " 12 - Check Leap Year" << std::endl;
+ std::cout << " 99 - Exit Menu" << std::endl;
+ option = GetOption();
+ switch( option ){
+ case 0: break;
+ case 1: ParseExpression( 0 ); break;
+ case 2: ProcessParsedExpression( 0 ); break;
+ case 3: ParseAndProcessExpression(); break;
+ #ifdef XB_DEBUG_SUPPORT
+ case 4: DumpExpressionTree(); break;
+ #endif
+ case 10: Date8ToJul(); break;
+ case 11: JulToDate8(); break;
+ case 12: IsLeapYear(); break;
+ case 99: break;
+ default: std::cout << "Invalid option" << std::endl; break;
+ }
+ }
+}
+#endif
+/************************************************************************/
+#ifdef XB_LOCKING_SUPPORT
+void xbUtil::LockingMenu()
+{
+ int option = 0;
+
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << " 6 - Locking Menu" << std::endl;
+ std::cout << "-------------" << std::endl;
+ DisplayActiveTable();
+
+ std::cout << " 1 - Display File Specific Settings" << std::endl;
+ std::cout << " 2 - Update File Retry Count" << std::endl;
+ std::cout << " 3 - Update Locking Flavor" << std::endl;
+ std::cout << " 4 - Update Auto Lock" << std::endl;
+ std::cout << " 5 - Lock table (dbf file)" << std::endl;
+ std::cout << " 6 - Unlock table (dbf file)" << std::endl;
+ std::cout << " 7 - Lock Record" << std::endl;
+ std::cout << " 8 - Unlock Record" << std::endl;
+ std::cout << " 9 - Lock Append" << std::endl;
+ std::cout << " 10 - Unlock Append" << std::endl;
+ std::cout << " 11 - Lock Header" << std::endl;
+ std::cout << " 12 - Unlock Header" << std::endl;
+
+
+ #ifdef XB_MEMO_SUPPORT
+ std::cout << " 13 - Lock Memo File" << std::endl;
+ std::cout << " 14 - Unlock Memo File" << std::endl;
+ #endif // XB_MEMO_SUPPORT
+
+ #ifdef XB_INDEX_SUPPORT
+ std::cout << " 15 - Lock Index File(s)" << std::endl;
+ std::cout << " 16 - Unlock Index File(s)" << std::endl;
+ #endif // XB_INDEX_SUPPORT
+
+ #ifdef XB_DEBUG_SUPPORT
+ std::cout << " 20 - Native xbFile - Lock Bytes" << std::endl;
+ std::cout << " 21 - Native xbFile - Unlock Bytes" << std::endl;
+ #endif // XB_DEBUG_SUPPORT
+
+ std::cout << " 99 - Exit Menu" << std::endl;
+ option = GetOption();
+
+ switch( option ) {
+ case 0: break;
+ case 1: DisplayFileLockSettings(); break;
+ case 2: UpdateFileLockRetryCount(); break;
+ case 3: UpdateFileLockFlavor(); break;
+ case 4: UpdateFileAutoLock(); break;
+ case 5: LockDbf(); break;
+ case 6: UnlockDbf(); break;
+ case 7: LockRecord(); break;
+ case 8: UnlockRecord(); break;
+ case 9: LockAppend(); break;
+ case 10: UnlockAppend(); break;
+ case 11: LockHeader(); break;
+ case 12: UnlockHeader(); break;
+
+ #ifdef XB_MEMO_SUPPORT
+ case 13: LockMemo(); break;
+ case 14: UnlockMemo(); break;
+ #endif // XB_MEMO_SUPPORT
+
+ #ifdef XB_INDEX_SUPPORT
+ case 15: LockIndices(); break;
+ case 16: UnlockIndices(); break;
+ #endif // XB_INDEX_SUPPORT
+
+ #ifdef XB_DEBUG_SUPPORT
+ case 20: xbFileLock(); break;
+ case 21: xbFileUnlock(); break;
+ #endif // XB_DEBUG_SUPPORT
+
+ case 99: break;
+ default: std::cout << "Invalid Option" << std::endl;
+ }
+ }
+}
+#endif
+
+/************************************************************************/
+#ifdef XB_SQL_SUPPORT
+void xbUtil::SqlMenu()
+{
+ int option = 0;
+
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << "9 - Sql Menu" << std::endl;
+ std::cout << "-------------" << std::endl;
+ DisplayActiveTable();
+
+ std::cout << " 1 - Execute SQL Non Query" << std::endl;
+ std::cout << " 2 - Execute SQL Query" << std::endl;
+ std::cout << "99 - Exit Menu" << std::endl;
+
+ option = GetOption();
+ switch( option ){
+ case 0: break;
+ case 1: ExecSqlNonQuery(); break;
+ case 2: ExecSqlQuery(); break;
+ case 99: break;
+ default: std::cout << "Invalid option" << std::endl; break;
+ }
+ }
+}
+#endif // XB_SQL_SUPPORT
+
+/************************************************************************/
+#ifdef XB_DEBUG_SUPPORT
+void xbUtil::DebugMenu()
+{
+ int option = 0;
+
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << "10 - Debug Menu" << std::endl;
+ std::cout << "-------------" << std::endl;
+ DisplayActiveTable();
+
+ std::cout << " 1 - Select Active Table" << std::endl;
+ #ifdef XB_MEMO_SUPPORT
+ std::cout << " 2 - Dislay Memo Header Info" << std::endl;
+ std::cout << " 3 - Dump Memo Free Chain" << std::endl;
+ #endif
+
+// //std::cout << "4 - Dump index node chains to file xbase.dmp" << std::endl;
+// //std::cout << "5 - Dump index node chain" << std::endl;
+ std::cout << "99 - Exit Menu" << std::endl;
+ option = GetOption();
+ switch( option ){
+ case 0: break;
+ case 1: SelectActiveTable(); break;
+ #ifdef XB_MEMO_SUPPORT
+ case 2: DumpDbtHeader(); break;
+ case 3: DumpMemoFreeChain(); break;
+ #endif
+ case 99: break;
+ default: std::cout << "Invalid option" << std::endl; break;
+ }
+ }
+}
+#endif // XBASE_DEBUG
+/************************************************************************/
+void xbUtil::FieldMenu()
+{
+ int option = 0;
+
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << " 5 - Field Menu" << std::endl;
+ std::cout << " --------------" << std::endl;
+ DisplayActiveTable();
+ std::cout << " 1 - Select Active Table" << std::endl;
+ std::cout << " 2 - List Field Info" << std::endl;
+ std::cout << " 3 - Show Field Data (non memo field)" << std::endl;
+ std::cout << " 4 - Update Field Data" << std::endl;
+ #ifdef XB_MEMO_SUPPORT
+ std::cout << " 5 - Show Memo Field Data" << std::endl;
+ std::cout << " 6 - Update Memo Field" << std::endl;
+ std::cout << " 7 - Delete Memo Field" << std::endl;
+ #endif
+
+ std::cout << "99 - Exit Menu" << std::endl;
+ option = GetOption();
+ switch( option ){
+ case 0: break;
+ case 1: SelectActiveTable(); break;
+ case 2: ListFieldInfo(); break;
+ case 3: DumpRecord(); break;
+ case 4: UpdateFieldData(); break;
+ #ifdef XB_MEMO_SUPPORT
+ case 5: ShowMemoFieldData(); break;
+ case 6: UpdateMemoFieldData(); break;
+ case 7: DeleteMemoField(); break;
+ #endif
+ case 99: break;
+ default: std::cout << "Invalid option" << std::endl; break;
+ }
+ }
+}
+/************************************************************************/
+void xbUtil::RecordMenu()
+{
+ int option = 0;
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << " 4 - Record Menu" << std::endl;
+ std::cout << " ---------------" << std::endl;
+ DisplayActiveTable();
+ std::cout << " 1 - Select Active Table" << std::endl;
+ std::cout << " 2 - Get Record" << std::endl;
+ std::cout << " 3 - Blank Record" << std::endl;
+ std::cout << " 4 - Append Record" << std::endl;
+ std::cout << " 5 - Put Record" << std::endl;
+ std::cout << " 6 - Delete Record" << std::endl;
+ std::cout << " 7 - Undelete Record" << std::endl;
+ std::cout << " 8 - First Record" << std::endl;
+ std::cout << " 9 - Next Record" << std::endl;
+ std::cout << "10 - Prev Record" << std::endl;
+ std::cout << "11 - Last Record" << std::endl;
+ std::cout << "12 - Dump Record" << std::endl;
+ std::cout << "13 - Abort Record Updates" << std::endl;
+ std::cout << "14 - Commit Record Updates" << std::endl;
+
+ #ifdef XB_FILTER_SUPPORT
+ std::cout << "20 - Set Filter" << std::endl;
+ std::cout << "21 - Get First Filter Rec" << std::endl;
+ std::cout << "22 - Get Next Filter Rec" << std::endl;
+ std::cout << "23 - Get Prev Filter Rec" << std::endl;
+ std::cout << "24 - Get Last Filter Rec" << std::endl;
+ #endif // XB_FILTER_SUPPORT
+
+ std::cout << "99 - Exit Menu" << std::endl;
+ option = GetOption();
+
+ switch( option ){
+ case 0: break;
+ case 1: SelectActiveTable(); break;
+ case 2: GetRecord(); break;
+ case 3: BlankRecord(); break;
+ case 4: AppendRecord(); break;
+ case 5: PutRecord(); break;
+ case 6: DeleteRecord(); break;
+ case 7: UndeleteRecord(); break;
+ case 8: GetFirstRecord(); break;
+ case 9: GetNextRecord(); break;
+ case 10: GetPrevRecord(); break;
+ case 11: GetLastRecord(); break;
+ case 12: DumpRecord(); break;
+ case 13: AbortRecord(); break;
+ case 14: CommitRecord(); break;
+
+ #ifdef XB_FILTER_SUPPORT
+ case 20: SetFilter(); break;
+ case 21: GetFirstFilterRec(); break;
+ case 22: GetNextFilterRec(); break;
+ case 23: GetPrevFilterRec(); break;
+ case 24: GetLastFilterRec(); break;
+ #endif // XB_FILTER_SUPPORT
+
+ case 99: break;
+ default: std::cout << "Invalid option" << std::endl; break;
+ }
+ }
+}
+
+/************************************************************************/
+void xbUtil::FileMenu()
+{
+ int option = 0;
+
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << " 3 - File / Table Menu" << std::endl;
+ std::cout << " ---------------------" << std::endl;
+ DisplayActiveTable();
+ std::cout << " 1 - List files in Default Data Directory" << std::endl;
+ std::cout << " 2 - Update Default Data Directory" << std::endl;
+ std::cout << " 3 - List Open Tables/Files" << std::endl;
+ std::cout << " 4 - Open Table/File" << std::endl;
+ std::cout << " 5 - Close Table/File" << std::endl;
+ std::cout << " 6 - Close All Tables/Files" << std::endl;
+ std::cout << " 7 - Select Active Table" << std::endl;
+ std::cout << " 8 - Table/File Information" << std::endl;
+ std::cout << "10 - Pack" << std::endl;
+ std::cout << "11 - Zap Database" << std::endl;
+ std::cout << "12 - Copy Dbf Structure" << std::endl;
+ std::cout << "13 - Update Table Auto Commit Setting" << std::endl;
+ std::cout << "14 - Display Table Info" << std::endl;
+
+ std::cout << "99 - Exit Menu" << std::endl;
+ option = GetOption();
+
+ switch( option ){
+ case 0: break;
+ case 1: ListFilesInDataDirectory(); break;
+ case 2: UpdateDataDirectory(); break;
+ case 3: x.DisplayTableList(); break;
+ case 4: Open(); break;
+ case 5: Close(); break;
+ case 6: CloseAllTables(); break;
+ case 7: SelectActiveTable(); break;
+ case 8: DisplayTableStats(); break;
+ case 10: Pack(); break;
+ case 11: ZapTable(); break;
+ case 12: CopyDbfStructure(); break;
+ case 13: UpdateTableAutoCommit(); break;
+ case 14: DisplayTableInfo(); break;
+ case 99: break;
+
+ default: std::cout << "Invalid Option" << std::endl;
+ }
+ }
+}
+
+/************************************************************************/
+#ifdef XB_NDXINF_SUPPORT
+void xbUtil::InfFileMenu()
+{
+
+
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "No table selected" << std::endl;
+ return;
+ }
+
+ int option = 0;
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << " 11 - InfFileData Menu" << std::endl;
+ std::cout << " ---------------------" << std::endl;
+ DisplayActiveTable();
+ std::cout << " 1 - List Inf Contents" << std::endl;
+ std::cout << " 2 - Add NDX File association to [" << dActiveTable->GetTblAlias().Str() << "]" << std::endl;
+ std::cout << " 3 - Delete NDX File association from [" << dActiveTable->GetTblAlias().Str() << "]" << std::endl;
+ std::cout << "10 - Inf File Help" << std::endl;
+ std::cout << "99 - Exit Menu" << std::endl;
+ option = GetOption();
+
+ switch( option ){
+ case 0: break;
+ case 1: ListInfFileData(); break;
+ case 2: AddInfFileData(); break;
+ case 3: DeleteInfFileData(); break;
+ case 10: InfFileHelp(); break;
+ case 99: break;
+ default: std::cout << "Invalid Option" << std::endl;
+ }
+ }
+}
+#endif // XB_NDXINF_SUPPORT
+
+/************************************************************************************/
+void xbUtil::SystemMenu()
+{
+ int option = 0;
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << " 2 - System Menu" << std::endl;
+ std::cout << " ---------------" << std::endl;
+ DisplayActiveTable();
+ std::cout << " 1 - Display System Settings" << std::endl;
+ std::cout << " 2 - Update Default Data Directory" << std::endl;
+
+ std::cout << " 3 - Toggle Default Auto Commit" << std::endl;
+ std::cout << " 4 - Update Default Log Directory" << std::endl;
+ std::cout << " 5 - Update Default Log File Name" << std::endl;
+ std::cout << " 6 - Toggle Logging Status" << std::endl;
+ std::cout << " 7 - Write Test Log Message" << std::endl;
+ #ifdef XB_LOCKING_SUPPORT
+ std::cout << " 8 - Update Default Lock Retries" << std::endl;
+ std::cout << " 9 - Toggle Default Auto Lock" << std::endl;
+ //std::cout << "10 - Update Lock Flavor" << std::endl; 3/20/17, only one flavor working
+ std::cout << "11 - Update Default Lock Wait Time" << std::endl;
+ std::cout << "12 - Toggle Multi User Mode" << std::endl;
+ #endif
+
+ std::cout << "99 - Exit Menu" << std::endl;
+ option = GetOption();
+
+ switch( option ) {
+ case 0: break;
+ case 1: ListSystemSettings(); break;
+ case 2: UpdateDataDirectory(); break;
+ case 3: ToggleDefaultAutoCommit(); break;
+ case 4: UpdateLogDirectory(); break;
+ case 5: UpdateLogFileName(); break;
+ case 6: ToggleLoggingStatus(); break;
+ case 7: WriteLogMessage(); break;
+ #ifdef XB_LOCKING_SUPPORT
+ case 8: UpdateDefaultLockRetries(); break;
+ case 9: ToggleDefaultAutoLock(); break;
+ case 10: UpdateDefaultLockFlavor(); break;
+ case 11: UpdateDefaultLockWait(); break;
+ case 12: ToggleMultiUserMode(); break;
+ #endif
+
+ case 99: break;
+ default: std::cout << "Invalid Option" << std::endl;
+ }
+ }
+}
+/************************************************************************************/
+void xbUtil::MainMenu()
+{
+ int option = 0;
+ std::cout << std::endl<< std::endl << "XBase64 Utility Program";
+ DisplayActiveTable();
+ while( option != 99 ) {
+ std::cout << std::endl << std::endl << " 0 - Main Menu" << std::endl;
+ std::cout << " -------------" << std::endl;
+ std::cout << " 1 - Help" << std::endl;
+ std::cout << " 2 - System Menu" << std::endl;
+ std::cout << " 3 - File / Table Menu" << std::endl;
+ std::cout << " 4 - Record Menu" << std::endl;
+ std::cout << " 5 - Field Menu" << std::endl;
+ //std::cout << " 6 - Index Menu" << std::endl;
+ #ifdef XB_LOCKING_SUPPORT
+ std::cout << " 6 - Locking Menu" << std::endl;
+ #endif
+ #ifdef XB_EXPRESSION_SUPPORT
+ std::cout << " 7 - Expression Menu" << std::endl;
+ #endif
+ #ifdef XB_INDEX_SUPPORT
+ std::cout << " 8 - Index Menu" << std::endl;
+ #endif
+
+ #ifdef XB_FILTERS
+ std::cout << " 9 - Filter Menu" << std::endl;
+ #endif
+
+ #ifdef XB_SQL_SUPPORT
+ std::cout << "10 - SQL Menu" << std::endl;
+ #endif // XB_SQL_SUPPORT
+
+ #ifdef XB_NDXINF_SUPPORT
+ std::cout << "11 - INF File Menu" << std::endl;
+ #endif // XB_NDXINF_SUPPORT
+
+ #ifdef XB_DEBUG_SUPPORT
+ std::cout << "20 - Debug Menu" << std::endl;
+ #endif
+
+ std::cout << "99 - Exit" << std::endl;
+ option = GetOption();
+ switch( option ){
+ case 0: break;
+ case 2: SystemMenu(); break;
+ case 3: FileMenu(); break;
+ case 4: RecordMenu(); break;
+ case 5: FieldMenu(); break;
+
+ #ifdef XB_LOCKING_SUPPORT
+ case 6: LockingMenu(); break;
+ #endif
+
+ #ifdef XB_EXPRESSION_SUPPORT
+ case 7: ExpressionMenu(); break;
+ #endif
+
+ #ifdef XB_INDEX_SUPPORT
+ case 8: IndexMenu(); break;
+ #endif
+
+ #ifdef XB_FILTERS
+ case 9: FilterMenu(); break;
+ #endif
+
+ #ifdef XB_SQL_SUPPORT
+ case 10: SqlMenu(); break;
+ #endif
+
+ #ifdef XB_NDXINF_SUPPORT
+ case 11: InfFileMenu(); break;
+ #endif
+
+ #ifdef XB_DEBUG_SUPPORT
+ case 20: DebugMenu(); break;
+ #endif
+
+ case 99: std::cout << "Bye!! - Thanks for using XBase64" << std::endl; break;
+ default:
+ std::cout << option << " - Invalid function" << std::endl;
+ break;
+ }
+ }
+}
+/*************************************************************************************/
+#ifdef XB_INDEX_SUPPORT
+void xbUtil::DisplayOpenIndexFiles(){
+
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ // if not active indices, display no open NDX indices
+ xbInt32 lIxCnt = dActiveTable->GetPhysicalIxCnt();
+ if( lIxCnt == 0 ){
+ std::cout << "No open index files for table" << std::endl;
+ return;
+ } else {
+ std::cout << " Open Index Files = [" << lIxCnt << "]" << std::endl;
+ std::cout << " FileName\tFile Type\n";
+ std::cout << " ========\t=========\n";
+ }
+ // For each active index
+ // display File Name, Type, Key
+ xbIxList *p = dActiveTable->GetIxList();
+ xbIx *ixp;
+ while( p ){
+ ixp = p->ix;
+ std::cout << " " << ixp->GetFileName().Str() << "\t" << p->sFmt->Str() << std::endl;
+ p = p->next;
+ }
+}
+
+void xbUtil::DisplaySupportedIndexTypes(){
+
+ std::cout << "Supported Index Type" << std::endl;
+ std::cout << "Type MaxTags Asc/Dsc Filters Description" << std::endl;
+ std::cout << "---- ------- -------- ------- --------------------------------" << std::endl;
+ #ifdef XB_NDX_SUPPORT
+ std::cout << "NDX 1 ASC No Dbase III single tag index file" << std::endl;
+ #endif
+ #ifdef XB_MDX_SUPPORT
+ std::cout << "MDX 47 ASC/DSC Yes Dbase IV multiple tag index file" << std::endl;
+ #endif
+}
+
+void xbUtil::SelectTag(){
+ std::cout << "SelectTag" << std::endl;
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+
+ xbLinkListNode<xbTag *> *llN = dActiveTable->GetTagList();
+ xbTag *pTag;
+ xbInt16 i = 1;
+ std::cout << "Line\tType\tUnique\tSort\tName\t\tKey Expression\t\tFilter" << std::endl;
+
+ char cUnique;
+ char cSort;
+ xbString s;
+ while( llN ){
+ pTag = llN->GetKey();
+ pTag->GetUnique() ? cUnique = 'Y' : cUnique = 'N';
+ pTag->GetSort() ? cSort = 'D' : cSort = 'A';
+ s.Sprintf( "%d\t%s\t%c\t%c\t%-12s\t%-20s\t%s \n", i++, pTag->GetType().Str(), cUnique, cSort, pTag->GetTagName().Str(), pTag->GetExpression().Str(), pTag->GetFilter().Str() );
+ std::cout << s.Str();
+// std::cout << i++ << "\t" << pTag->GetType() << "\t " << cUnique << "\t " << cSort << "\t" << pTag->GetTagName() << "\t" << pTag->GetExpression() << "\t" << pTag->GetFilter() << std::endl;
+ llN = llN->GetNextNode();
+ }
+ char cBuf[128];
+ std::cout << std::endl << "Enter Line No:" << std::endl;
+ std::cin.getline( cBuf, 128 );
+
+ xbInt32 iSelection = atol( cBuf );
+ if( iSelection < 1 || iSelection > i ){
+ std::cout << "Invalid selection [" << iSelection << "]" << std::endl;
+ } else {
+ llN = dActiveTable->GetTagList();
+ i = 1;
+ for( i = 1; i < iSelection; i++ )
+ llN = llN->GetNextNode();
+ pTag = llN->GetKey();
+ dActiveTable->SetCurTag( pTag->GetType(), pTag->GetIx(), pTag->GetVpTag() );
+ }
+}
+
+void xbUtil::OpenIndex(){
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+
+ char cBuf[128];
+ std::cout << "Enter index type (NDX or MDX)" << std::endl;
+ std::cin.getline( cBuf, 128 );
+ xbString sIxType = cBuf;
+
+ std::cout << "Enter File Name" << std::endl;
+ std::cin.getline( cBuf, 128 );
+ xbString sIxFileName = cBuf;
+
+ iRc = dActiveTable->OpenIndex( sIxType, sIxFileName );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::CloseIndexFile(){
+
+ std::cout << "CloseIndex\n";
+
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+
+ xbInt16 iRc = dActiveTable->CloseIndexFile( pIx );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::CreateIndexTag(){
+
+ std::cout << "CreateIndexTag\n";
+
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+
+ char cBuf[512];
+ xbString sPrompt = "Enter Index Type (";
+ #ifdef XB_NDX_SUPPORT
+ sPrompt += "NDX";
+ #endif // XB_NDX_SUPPORT
+ #ifdef XB_MDX_SUPPORT
+ sPrompt += " MDX";
+ #endif // XB_MDX_SUPPORT
+ sPrompt += "):";
+ std::cout << sPrompt.Str() << std::endl;
+
+ std::cin.getline( cBuf, 128 );
+ xbString sIxType = cBuf;
+
+ if( sIxType == "NDX" )
+ std::cout << "Enter File Name" << std::endl;
+ else if( sIxType == "MDX" )
+ std::cout << "Enter Tag Name" << std::endl;
+
+ std::cin.getline( cBuf, 128 );
+ xbString sIxName = cBuf;
+
+ if( sIxType != "NDX" && sIxType != "MDX" ){
+ std::cout << "Invalid tag type" << std::endl;
+ return;
+ }
+
+ xbString s;
+ if( sIxType == "NDX" ){
+ s = sIxName;
+ s.ToUpperCase();
+ xbUInt32 lPos = s.Pos( ".NDX" );
+ if( lPos == 0 )
+ sIxName += ".NDX";
+ }
+ if( sIxType == "MDX" ){
+ if( sIxName.Len() > 12 ){
+ std::cout << "Tag name [" << sIxName.Str() << "] to long. Must be 12 bytes or less" << std::endl;
+ return;
+ }
+ }
+
+ xbInt16 iDescending = 0;
+ xbInt16 iUnique = 0;
+
+ std::cout << "Enter Key Expression:" << std::endl;
+ std::cin.getline( cBuf, 512 );
+ xbString sKeyExpression = cBuf;
+
+ xbString sFilter;
+ if( sIxType == "MDX" ){
+ std::cout << "Enter Filter (or enter for none):" << std::endl;
+ std::cin.getline( cBuf, 512 );
+ sFilter = cBuf;
+
+ std::cout << "Descending? (Enter Y for yes):" << std::endl;
+ std::cin.getline( cBuf, 12 );
+ if( cBuf[0] == 'Y' )
+ iDescending = 1;
+ }
+
+ std::cout << "Unique Keys? (Enter Y for yes):" << std::endl;
+ std::cin.getline( cBuf, 12 );
+ if( cBuf[0] == 'Y' )
+ iUnique = 1;
+
+ xbIx *pIx;
+ void *vpTag;
+
+ xbInt16 iRc = dActiveTable->CreateTag( sIxType, sIxName, sKeyExpression, sFilter, iDescending, iUnique, 0, &pIx, &vpTag );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::GetFirstKey(){
+ std::cout << "GetFirstKey\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ void *vpCurTag = dActiveTable->GetCurTag();
+ xbInt16 iRc = pIx->GetFirstKey( vpCurTag, 1 );
+ if( iRc == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+
+void xbUtil::GetNextKey(){
+ std::cout << "GetNextKey\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ void *vpCurTag = dActiveTable->GetCurTag();
+ xbInt16 iRc = pIx->GetNextKey( vpCurTag, 1 );
+ if( iRc == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+
+void xbUtil::GetPrevKey(){
+ std::cout << "GetPrevKey\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ void *vpCurTag = dActiveTable->GetCurTag();
+ xbInt16 iRc = pIx->GetPrevKey( vpCurTag, 1 );
+ if( iRc == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+
+void xbUtil::GetLastKey(){
+ std::cout << "GetLastKey\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ void *vpCurTag = dActiveTable->GetCurTag();
+ xbInt16 iRc = pIx->GetLastKey( vpCurTag, 1 );
+ if( iRc == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+
+void xbUtil::FindKey(){
+ std::cout << "FindKey\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ void *vpCurTag = dActiveTable->GetCurTag();
+ char cKeyType = pIx->GetKeyType( vpCurTag );
+
+ switch( cKeyType ){
+ case 'C':
+ std::cout << "Enter character key value:";
+ break;
+ case 'F':
+ case 'N':
+ std::cout << "Enter numeric key value:";
+ break;
+ case 'D':
+ std::cout << "Enter date (YYYYMMDD) key value:";
+ break;
+ default:
+ std::cout << "Unknown key type [" << cKeyType << "]" << std::endl;
+ return;
+ break;
+ }
+
+ char cBuf[128];
+ std::cin.getline( cBuf, 128 );
+ xbInt16 iRc = 0;
+
+ if( cKeyType == 'C' ){
+ iRc = pIx->FindKey( vpCurTag, cBuf, (xbInt32) strlen( cBuf ), 1 );
+
+ } else if( cKeyType == 'F' || cKeyType == 'N' ){
+ xbDouble d = atof( cBuf );
+ iRc = pIx->FindKey( vpCurTag, d, 1 );
+
+ } else if( cKeyType == 'D' ){
+ xbDate dt( cBuf );
+ iRc = pIx->FindKey( vpCurTag, dt, 1 );
+ }
+
+ if( iRc == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+
+void xbUtil::CheckIntegrity(){
+ std::cout << "CheckIntegrity\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ void *vpCurTag = dActiveTable->GetCurTag();
+
+ xbInt16 iRc = pIx->CheckTagIntegrity( vpCurTag, 2 );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::Reindex(){
+ std::cout << "Reindex\n";
+
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ void *vpCurTag = dActiveTable->GetCurTag();
+ xbInt16 iRc = pIx->Reindex( &vpCurTag );
+ x.DisplayError( iRc );
+}
+
+void xbUtil::DeleteTag(){
+ std::cout << "DeleteTag\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ void *vpCurTag = dActiveTable->GetCurTag();
+ xbInt16 iRc = dActiveTable->DeleteTag( dActiveTable->GetCurIxType(), pIx->GetTagName( vpCurTag ));
+ x.DisplayError( iRc );
+}
+
+void xbUtil::AssociateNonProdIx(){
+ std::cout << "See InfFile menu option, option 11 from the main menu or =11 from here\n";
+}
+
+#ifdef XB_DEBUG_SUPPORT
+
+void xbUtil::DumpRecsByIx( xbInt16 iOpt ){
+ // iDirection = 0 - Forward - MDX
+ // = 1 - Reverse - MDX
+
+ std::cout << "DumpRecsByIx\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ std::cout << "Select destination:" << std::endl;
+ std::cout << "0 - Logfile" << std::endl;
+ std::cout << "1 - Screen" << std::endl;
+ std::cout << "2 - Both" << std::endl;
+ xbInt16 iDispOpt = GetOption();
+ std::cout << "Select format:" << std::endl;
+ std::cout << "0 - With Field Names" << std::endl;
+ std::cout << "1 - 1 line per record" << std::endl;
+ xbInt16 iDispFmt = GetOption();
+
+ x.WriteLogMessage( "--------- Dump Recs By Index -------------", iDispOpt );
+ void *vpCurTag = dActiveTable->GetCurTag();
+ xbUInt32 lRecCnt = 0;
+ xbInt16 iRc = 0;
+
+ if( iOpt == 0 ){
+ iRc = pIx->GetFirstKey( vpCurTag, 1 );
+ if( iRc == XB_NO_ERROR ){
+ lRecCnt++;
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), iDispOpt, iDispFmt );
+ while(( iRc = pIx->GetNextKey( vpCurTag, 1 )) == XB_NO_ERROR ){
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), iDispOpt, iDispFmt );
+ lRecCnt++;
+ }
+ } else {
+ x.DisplayError( iRc );
+ }
+ } else if( iOpt == 1 ) {
+ iRc = pIx->GetLastKey( vpCurTag, 1 );
+ if( iRc == XB_NO_ERROR ){
+ lRecCnt++;
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), iDispOpt, iDispFmt );
+ while(( iRc = pIx->GetPrevKey( vpCurTag, 1 )) == XB_NO_ERROR ){
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), iDispOpt, iDispFmt );
+ lRecCnt++;
+ }
+ }
+ } else {
+ std::cout << "Invalid option " << iOpt << std::endl;
+ return;
+ }
+ std::cout << lRecCnt << " record(s) dumped" << std::endl;
+}
+
+void xbUtil::DumpIxHeader(){
+ std::cout << "DumpIxHeader\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ std::cout << "0 - Logfile" << std::endl;
+ std::cout << "1 - Screen" << std::endl;
+ std::cout << "2 - Both" << std::endl;
+ xbInt16 iDispOpt = GetOption();
+ pIx->DumpHeader( iDispOpt, 3 );
+
+}
+
+void xbUtil::DumpIxNode(){
+ std::cout << "DumpIxNode\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ std::cout << "0 - Logfile" << std::endl;
+ std::cout << "1 - Screen" << std::endl;
+ std::cout << "2 - Both" << std::endl;
+ xbInt16 iDispOpt = GetOption();
+// std::cout << std::endl << "0 - All Blocks" << std::endl;
+// std::cout << "NNN - Specific block number, 0=All" << std::endl;
+// xbUInt32 iBlockOpt = (xbUInt32) GetOption();
+// if( iBlockOpt == 0 ) // dump the header if dumping all blocks
+ // pIx->DumpHeader( iDispOpt );
+ pIx->DumpTagBlocks( iDispOpt, dActiveTable->GetCurTag() );
+}
+
+void xbUtil::DumpIxNodeChain(){
+
+ std::cout << "DumpIxNodeChain\n";
+
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+
+ std::cout << "0 - Logfile" << std::endl;
+ std::cout << "1 - Screen" << std::endl;
+ std::cout << "2 - Both" << std::endl;
+ xbInt16 iDispOpt = GetOption();
+
+ void *vpCurTag = dActiveTable->GetCurTag();
+ pIx->DumpIxNodeChain( vpCurTag, iDispOpt );
+}
+
+
+void xbUtil::DumpFreeBlocks(){
+ std::cout << "Dump ulBlock2 - (Free Block or Split From Page) for MDX Index file\n";
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbIx *pIx = dActiveTable->GetCurIx();
+ if( !pIx )
+ SelectTag();
+ pIx = dActiveTable->GetCurIx();
+ if( !pIx ){
+ std::cout << "Tag not selected" << std::endl;
+ return;
+ }
+ std::cout << "0 - Logfile" << std::endl;
+ std::cout << "1 - Screen" << std::endl;
+ std::cout << "2 - Both" << std::endl;
+ xbInt16 iDispOpt = GetOption();
+ pIx->DumpFreeBlocks( iDispOpt );
+
+}
+
+
+
+#endif // XB_DEBUG_SUPPORT
+#endif // XB_INDEX_SUPPORT
+
+#ifdef XB_FILTER_SUPPORT
+void xbUtil::SetFilter()
+{
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+
+ char cBuf[128];
+ std::cout << "Enter filter expression:" << std::endl;
+ std::cin.getline( cBuf, 128 );
+ xbString s( cBuf );
+
+ if( filt )
+ delete filt;
+
+ filt = new xbFilter( &x, dActiveTable );
+ xbInt16 iRc = filt->Set( s );
+
+ x.DisplayError( iRc );
+}
+
+void xbUtil::GetFirstFilterRec()
+{
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+
+ xbInt16 iRc;
+ if(( iRc = filt->GetFirstRecord()) == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+
+void xbUtil::GetNextFilterRec()
+{
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ if(( iRc = filt->GetNextRecord()) == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+
+void xbUtil::GetPrevFilterRec()
+{
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ if(( iRc = filt->GetPrevRecord()) == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+
+void xbUtil::GetLastFilterRec()
+{
+ // verify active table selected, if not, select one
+ if( !dActiveTable )
+ dActiveTable = GetTablePtr( " - select table" );
+
+ if( !dActiveTable ){
+ std::cout << "Table not selected" << std::endl;
+ return;
+ }
+ xbInt16 iRc;
+ if(( iRc = filt->GetLastRecord()) == XB_NO_ERROR )
+ dActiveTable->DumpRecord( dActiveTable->GetCurRecNo(), 2);
+ else
+ x.DisplayError( iRc );
+}
+#endif // XB_FILTER_SUPPORT
+
+///@endcond DOXYOFF
+
+/*************************************************************************************/
+int main(int, char**)
+{
+ std::cout << "xb_dbfutil initializing" << std::endl;
+ xbUtil u;
+ u.MainMenu();
+ return 0;
+}