summaryrefslogtreecommitdiff
path: root/src/examples
diff options
context:
space:
mode:
Diffstat (limited to 'src/examples')
-rwxr-xr-xsrc/examples/xb_ex_date.cpp212
-rwxr-xr-xsrc/examples/xb_ex_expression.cpp231
-rwxr-xr-xsrc/examples/xb_ex_log.cpp77
-rwxr-xr-xsrc/examples/xb_ex_sql.cpp111
-rwxr-xr-xsrc/examples/xb_ex_ssv.cpp136
-rwxr-xr-xsrc/examples/xb_ex_string.cpp381
-rwxr-xr-xsrc/examples/xb_ex_v3_create_dbf.cpp110
-rwxr-xr-xsrc/examples/xb_ex_v3_upd_dbf.cpp326
-rwxr-xr-xsrc/examples/xb_ex_v4_create_dbf.cpp100
-rwxr-xr-xsrc/examples/xb_ex_v4_upd_dbf.cpp294
10 files changed, 1978 insertions, 0 deletions
diff --git a/src/examples/xb_ex_date.cpp b/src/examples/xb_ex_date.cpp
new file mode 100755
index 0000000..7b92dbe
--- /dev/null
+++ b/src/examples/xb_ex_date.cpp
@@ -0,0 +1,212 @@
+/* xb_ex_date.cpp
+
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2021,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+This program demonstrates using the xbDate class
+
+*/
+
+
+#include "xbase.h"
+
+using namespace xb;
+
+int main()
+{
+
+ xbXBase x; /* initial date static variables */
+
+ xbString StringDate( "19601007" ); /* oct 7 1960 */
+ char CharDate[9] = "19611109"; /* nov 9 1961 */
+
+ xbDate d1; /* today is default */
+ xbDate d2( StringDate ); /* from string data */
+ xbDate d3( CharDate ); /* from char data */
+ xbDate d4; /* another date class */
+ xbString s;
+
+ std::cout << "This program demonstrates usage of the xbDate class" << std::endl;
+ std::cout << "Date 1 (Sysdate) is " << d1.Str() << std::endl;
+ std::cout << "Date 2 (StringDate) is " << d2.Str() << std::endl;
+ std::cout << "Date 3 (CharDate) is " << d3.Str() << std::endl;
+
+ std::cout << "This year is " << d1.YearOf() << std::endl;
+ std::cout << "Year of xbString Date is " << d2.YearOf()
+ << std::endl;
+ std::cout << "Year of char Date is " << d3.YearOf()
+ << std::endl;
+
+ std::cout << "This Month is " << d1.MonthOf() << std::endl;
+ std::cout << "Month of xbString Date is " << d2.MonthOf()
+ << std::endl;
+ std::cout << "Month of char Date is " << d3.MonthOf()
+ << std::endl;
+
+ std::cout << "Today is day " << d1.DayOf( XB_FMT_WEEK ) << " of the week" << std::endl;
+ std::cout << "StringDate is day " << d2.DayOf( XB_FMT_MONTH ) << " of the month" << std::endl;
+ std::cout << "CharDate is day " << d3.DayOf( XB_FMT_YEAR ) << " of the year" << std::endl;
+
+ if( d1.IsLeapYear())
+ std::cout << "This is a leap year" << std::endl;
+ else
+ std::cout << "This is not a leap year." << std::endl;
+
+ if( d2.IsLeapYear())
+ std::cout << "StringDate is a leap year" << std::endl;
+ else
+ std::cout << "StringDate is not a leap year." << std::endl;
+
+ if( d3.IsLeapYear())
+ std::cout << "CharDate is a leap year" << std::endl;
+ else
+ std::cout << "CharDate is not a leap year." << std::endl;
+
+ std::cout << "Today is " << d1.Sysdate() << std::endl;
+
+ if( d1.DateIsValid( "19951301" ))
+ std::cout << "19951301 is a valid date" << std::endl;
+ else
+ std::cout << "19951301 is not a valid date" << std::endl;
+
+ if( d1.DateIsValid( "19920229" ))
+ std::cout << "19920229 is a valid date" << std::endl;
+ else
+ std::cout << "19920229 is not a valid date" << std::endl;
+
+ if( d2.DateIsValid( StringDate ))
+ std::cout << StringDate.Str() << " is a valid date" << std::endl;
+ else
+ std::cout << StringDate.Str() << " is not a valid date" << std::endl;
+
+ std::cout << "Today's Julian date " << d1.JulianDays() << std::endl;
+ std::cout << "Julian date of Jan 01, 1970 " << d2.JulianDays() << std::endl;
+ std::cout << "StringDate Julian date " << d2.JulianDays() << std::endl;
+
+ std::cout << "There are " << (d1.JulianDays() - d2.JulianDays()) << " days between " << d1.Str() << " and " << d2.Str() << std::endl;
+
+ std::cout << "Todays Julian date (Number of days since Jan 1 0100):" << d1.JulianDays() << std::endl;
+
+ d4 = d1; // set d4 class = to sysdate
+ std::cout << "Object d4 initialized to " << d4.Str() << std::endl;
+ std::cout << "This should be todays date: "
+ << d4.JulToDate8(d4.JulianDays()) << std::endl;
+ std::cout << "In 7 days it will be "
+ << d4.JulToDate8(d4.JulianDays() + 7L ) << std::endl;
+
+ d1.CharDayOf( s );
+ std::cout << "Today is " << s.Str() << std::endl;
+
+ d2.CharDayOf( s );
+ std::cout << "StringDate day is " << s.Str() << std::endl;
+ d1.CharMonthOf( s );
+ std::cout << "This month is " << s.Str() << std::endl;
+ d2.CharMonthOf( s );
+ std::cout << "StringDate month is " << s.Str() << std::endl;
+
+
+ /* various format routines using different formats, strings and chars */
+ xbString sOutDate;
+
+ d1.FormatDate( "YYDDD", sOutDate );
+ std::cout << "Format (YYDDD) = " << sOutDate.Str() << std::endl;
+
+ d1.FormatDate( "MM/DD/YY", sOutDate );
+ std::cout << "Format (MM/DD/YY) = " << sOutDate.Str() << std::endl;
+
+ d1.FormatDate( "YY-MM-DD", sOutDate );
+ std::cout << "Format (YY-MM-DD) = " << sOutDate.Str() << std::endl;
+
+ d1.FormatDate( "DDDDDDDDD, MMMMMMMMMM DD YYYY", sOutDate );
+ std::cout << "Format (DDDDDDDDD, MMMMMMMMMM DD YYYY) = " << sOutDate.Str() << std::endl;
+
+ std::cout << "Last day this month " << d1.LastDayOfMonth() << std::endl;
+ std::cout << "Last day of month for StringDate is " << d2.LastDayOfMonth() << std::endl;
+
+ std::cout << "Overloaded operators test..." << std::endl;
+
+ if( d1 == d2 )
+ std::cout << d1.Str() << " is equal to " << d2.Str()
+ << std::endl;
+ else
+ std::cout << d1.Str() << " is not equal to " << d2.Str()
+ << std::endl;
+
+ if( d1 != d3 )
+ std::cout << d1.Str() << " is not equal to " << d3.Str()
+ << std::endl;
+ else
+ std::cout << d1.Str() << " is equal to " << d3.Str()
+ << std::endl;
+
+ if( d1 < d2 )
+ std::cout << d1.Str() << " is less than " << d2.Str()
+ << std::endl;
+ else
+ std::cout << d1.Str() << " is not less than " << d2.Str()
+ << std::endl;
+
+ if( d1 > d2 )
+ std::cout << d1.Str() << " is greater than " << d2.Str()
+ << std::endl;
+ else
+ std::cout << d1.Str() << " is not greater than " << d2.Str()
+ << std::endl;
+
+ if( d1 <= d2 )
+ std::cout << d1.Str() << " is less than or equal to " << d2.Str()
+ << std::endl;
+ else
+ std::cout << d1.Str() << " is not less than or equal to "
+ << d2.Str() << std::endl;
+
+ if( d1 >= d2 )
+ std::cout << d1.Str() << " is greater than or equal to "
+ << d2.Str() << std::endl;
+ else
+ std::cout << d1.Str() << " is not greater than or equal to "
+ << d2.Str() << std::endl;
+
+ d1.Sysdate();
+ d1++;
+ std::cout << "Tomorrow is " << d1.Str() << std::endl;
+ d1-=2;
+ std::cout << "Yesterday was " << d1.Str() << std::endl;
+ std::cout << "There are " << d1 - d2 << " days between " << d1.Str()
+ << " and " << d2.Str() << std::endl;
+
+ d1="20140701";
+ std::cout << "Operator = example " << d1.Str() << std::endl;
+
+ d1+=5;
+ std::cout << "Operator += 5 example " << d1.Str() << std::endl;
+
+ d1--;
+ std::cout << "Operator -- example " << d1.Str() << std::endl;
+
+ d1-4;
+ std::cout << "Operator -4 example " << d1.Str() << std::endl;
+
+ d1+10;
+ std::cout << "Operator +10 example " << d1.Str() << std::endl;
+ std::cout << "CenturyOf() " << d1.CenturyOf() << std::endl;
+
+ xbString sWorkDate;
+ d1.CTOD( "10/07/60" );
+ std::cout << "CTOD( '10/07/60' ) " << d1.Str() << std::endl;
+
+ d1.Set( "19590118" );
+ std::cout << "Set( '19590118' ) " << d1.Str() << std::endl;
+
+ std::cout << "CalcRollingCenturyForYear( 95 ) = " << d1.CalcRollingCenturyForYear( 95 ) << std::endl;
+ return 0;
+}
diff --git a/src/examples/xb_ex_expression.cpp b/src/examples/xb_ex_expression.cpp
new file mode 100755
index 0000000..f16c79f
--- /dev/null
+++ b/src/examples/xb_ex_expression.cpp
@@ -0,0 +1,231 @@
+/* xb_ex_expression.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under
+the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ xb64-devel@lists.sourceforge.net
+ xb64-users@lists.sourceforge.net
+
+
+ This example program demonstrates expression usage
+
+*/
+
+
+#include <xbase.h>
+
+using namespace xb;
+
+
+
+ xbSchema MyV4Record[] =
+ {
+ { "CFLD1", XB_CHAR_FLD, 20, 0 },
+ { "CFLD2", XB_CHAR_FLD, 10, 0 },
+ { "NFLD1", XB_NUMERIC_FLD, 5, 0 },
+ { "DATE1", XB_DATE_FLD, 8, 0 },
+ { "",0,0,0 }
+ };
+
+//*********************************************************************************************************************************
+void PrintResult( xbString *sExpression, xbExp *exp );
+void PrintResult( xbString *sExpression, xbExp *exp ){
+
+ // Determine the expression return type
+ char cExpType = exp->GetReturnType();
+
+ // Process the expression results, dependent on return type
+ if( cExpType == XB_EXP_NUMERIC ){
+ xbDouble dResult;
+ exp->GetNumericResult( dResult );
+ std::cout << "Numeric result from expression [" << sExpression->Str() << "] is [" << dResult << "]" << std::endl;
+
+ } else if( cExpType == XB_EXP_DATE ){
+ xbDate dt;
+ exp->GetDateResult( dt );
+ std::cout << "Date result from expression [" << sExpression->Str() << "] is [" << dt.Str() << "]" << std::endl;
+
+ } else if( cExpType == XB_EXP_LOGICAL ){
+ xbBool bResult;
+ exp->GetBoolResult( bResult );
+ std::cout << "Bool result from expression [" << sExpression->Str() << "] is [" << (bResult ? " True" : "False") << "]" << std::endl;
+
+ } else if( cExpType == XB_EXP_CHAR ){
+ xbString sResult;
+ exp->GetStringResult( sResult );
+ std::cout << "Char result from expression [" << sExpression->Str() << "] is [" << sResult.Str() << "]" << std::endl;
+ }
+
+}
+
+//*********************************************************************************************************************************
+//int main( int ac, char ** av ){
+
+int main(){
+
+ xbInt16 iRc = 0;
+ xbInt16 iErrorStop = 0;
+ xbIx *pIx = NULL;
+ void *pTag = NULL;
+
+ xbXBase x;
+ xbDbf *MyFile = new xbDbf4( &x );
+
+ try{
+
+ if(( iRc = MyFile->CreateTable( "EXPEXAMPL.DBF", "TestMdxX2", MyV4Record, XB_OVERLAY, XB_MULTI_USER )) != XB_NO_ERROR ){
+ iErrorStop = 100;
+ throw iRc;
+ }
+ /*
+ CreateTag( const xbString &sIxType, const xbString &sName, const xbString &sKey, const xbString &sFilter,
+ xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverLay, xbIx **xbIxOut, void **vpTagOut );
+ */
+
+ // the following index definition has two expressions
+ // 1) CFLD1+CFLD2 -- concat two char fields into an index key
+ // 2) .NOT. DELETED() -- don't include any deleted records in the index
+ if(( iRc = MyFile->CreateTag( "MDX", "TAG1", "CFLD1+CFLD2", ".NOT. DELETED()", 0, 0, XB_OVERLAY, &pIx, &pTag )) != XB_NO_ERROR ){
+ iErrorStop = 110;
+ throw iRc;
+ }
+
+ // add a record to the table
+ if(( iRc = MyFile->BlankRecord()) != XB_NO_ERROR ){
+ iErrorStop = 120;
+ throw iRc;
+ }
+
+ if(( iRc = MyFile->PutField( "CFLD1", "Some text" )) != XB_NO_ERROR ){
+ iErrorStop = 130;
+ throw iRc;
+ }
+
+ if(( iRc = MyFile->PutField( "CFLD2", "Other text" )) != XB_NO_ERROR ){
+ iErrorStop = 140;
+ throw iRc;
+ }
+
+ if(( iRc = MyFile->PutLongField( "NFLD1", 1000 )) != XB_NO_ERROR ){
+ iErrorStop = 150;
+ throw iRc;
+ }
+
+ xbDate dt;
+ dt.Set( "19890209" );
+ if(( iRc = MyFile->PutDateField( "DATE1", dt )) != XB_NO_ERROR ){
+ iErrorStop = 160;
+ throw iRc;
+ }
+
+ if(( iRc = MyFile->AppendRecord()) != XB_NO_ERROR ){
+ iErrorStop = 170;
+ throw iRc;
+ }
+
+ if(( iRc = MyFile->Commit()) != XB_NO_ERROR ){
+ iErrorStop = 180;
+ throw iRc;
+ }
+
+
+ // To use the XBase64 expression processing logic
+ // 1) Parse an expression with the xbExp::ParseExpression() method
+ // 2) Process the parsed expression with the xbExp::ProcessExpression() method
+ // 3) If needed, determine the expression return type with the xbExp::GetReturnType() method
+ // 4) Use the appriate methid to retrieve the expression value:
+ // xbExp::GetNumericResult()
+ // xbExp::GetDateResult()
+ // xbExp::GetLogicalResult()
+ // xbExp::GetStringResult()
+
+
+ // The expression only needs to be parsed once. The ProcessExpression() method can be used
+ // zero, one or many times after it is initially parsed.
+
+ // see docs/html/xbc5.html for expression documentation
+ // see example below
+
+
+ // Numeric expression example
+ xbString sExpression = "NFLD1 * (2 + RECNO())";
+ xbExp exp( &x );
+ // Parse the expression
+ if(( iRc = exp.ParseExpression( MyFile, sExpression )) != XB_NO_ERROR ){
+ iErrorStop = 190;
+ throw iRc;
+ }
+ // Process the parsed expression
+ if(( iRc = exp.ProcessExpression()) != XB_NO_ERROR ){
+ iErrorStop = 200;
+ return -1;
+ }
+ PrintResult( &sExpression, &exp );
+
+ // String expression example
+ sExpression = "CFLD1+CFLD2+'{'+DTOS(DATE1)+'}'";
+ xbExp exp2( &x );
+ if(( iRc = exp2.ParseExpression( MyFile, sExpression )) != XB_NO_ERROR ){
+ iErrorStop = 210;
+ throw iRc;
+ }
+
+ // Process the parsed expression
+ if(( iRc = exp2.ProcessExpression()) != XB_NO_ERROR ){
+ iErrorStop = 220;
+ return -1;
+ }
+
+ PrintResult( &sExpression, &exp2 );
+
+ // Date example
+ sExpression = "DATE() + 6";
+ xbExp exp3( &x );
+ if(( iRc = exp3.ParseExpression( MyFile, sExpression )) != XB_NO_ERROR ){
+ iErrorStop = 230;
+ throw iRc;
+ }
+ // Process the parsed expression
+ if(( iRc = exp3.ProcessExpression()) != XB_NO_ERROR ){
+ iErrorStop = 240;
+ return -1;
+ }
+ PrintResult( &sExpression, &exp3 );
+
+ // Logic example
+ sExpression = "NFLD1 = 5";
+ xbExp exp4( &x );
+ if(( iRc = exp4.ParseExpression( MyFile, sExpression )) != XB_NO_ERROR ){
+ iErrorStop = 250;
+ throw iRc;
+ }
+ // Process the parsed expression
+ if(( iRc = exp4.ProcessExpression()) != XB_NO_ERROR ){
+ iErrorStop = 260;
+ return -1;
+ }
+ PrintResult( &sExpression, &exp4 );
+
+ // Cleanup
+ MyFile->DeleteTable();
+ delete MyFile;
+
+
+ } catch (xbInt16 iRc ){
+
+ std::cout << "Error in program xb_ex_expression at location " << iErrorStop << std::endl;
+ std::cout << x.GetErrorMessage( iRc ) << std::endl;
+
+ }
+
+
+
+
+ return iRc;
+}
diff --git a/src/examples/xb_ex_log.cpp b/src/examples/xb_ex_log.cpp
new file mode 100755
index 0000000..cf5320f
--- /dev/null
+++ b/src/examples/xb_ex_log.cpp
@@ -0,0 +1,77 @@
+/* xb_ex_log.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+// This program demostrates how to use logging
+
+
+#include "xbase.h"
+
+using namespace xb;
+
+int main( int argCnt, char **av )
+{
+
+ #ifdef XB_LOGGING_SUPPORT
+
+ xbXBase x;
+ xbString sMsg;
+
+
+ std::cout << "Default Logfile Name is: [" << x.GetLogFqFileName().Str()
+ << "] Rollover size = [" << x.GetLogSize()
+ << "]" << std::endl;
+
+ if( x.GetLogStatus() )
+ std::cout << "Logging is active" << std::endl;
+ else
+ std::cout << "Logging is inactive" << std::endl;
+
+ x.SetLogDirectory( PROJECT_LOG_DIR ); // use the library log directory
+ x.SetLogFileName ( "MySpecialLogFile.txt" ); // set to use a special name
+ x.SetLogSize ( x.GetLogSize() * 2 ); // double the log file size
+
+ // enable the logfile and write a message for the new settings to take effect
+ x.EnableMsgLogging();
+ sMsg.Sprintf( "Program [%s] initializing...", av[0] );
+ x.WriteLogMessage( sMsg );
+
+ std::cout << "New Logfile Name is: [" << x.GetLogFqFileName().Str()
+ << "] Rollover size = [" << x.GetLogSize()
+ << "]" << std::endl;
+
+ if( x.GetLogStatus() )
+ std::cout << "Logging is active" << std::endl;
+ else
+ std::cout << "Logging is inactive" << std::endl;
+
+ // write some messages to the logfile
+ for( int i = 0; i < 5; i++ ){
+ sMsg.Sprintf( "Test message [%d]", i );
+ x.WriteLogMessage( sMsg );
+ }
+
+ sMsg.Sprintf( "Program [%s] terminating..", av[0] );
+ x.WriteLogMessage( sMsg );
+
+ x.FlushLog(); // not really needed, but here for demonstration purposes
+
+ #endif // B_LOGGING_SUPPORT
+
+ return 0;
+}
+
+
+
+
diff --git a/src/examples/xb_ex_sql.cpp b/src/examples/xb_ex_sql.cpp
new file mode 100755
index 0000000..695baa2
--- /dev/null
+++ b/src/examples/xb_ex_sql.cpp
@@ -0,0 +1,111 @@
+/* xb_ex_sql.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+ This example demonstrates the implementation of initial sql functions into the library
+
+*/
+
+#include <xbase.h>
+using namespace xb;
+
+int main( int argCnt, char **av )
+{
+ xbInt16 iRc;
+ xbXBase x; /* initialize xbase */
+
+#ifdef XB_LOGGING_SUPPORT
+ x.EnableMsgLogging();
+ std::cout << "Logfile is [" << x.GetLogFqFileName().Str() << "]" << std::endl;
+ xbString sMsg;
+ sMsg.Sprintf( "Program [%s] initializing...", av[0] );
+ x.WriteLogMessage( sMsg );
+#endif
+
+ xbSql sql( &x );
+ xbString sSql;
+
+
+ sSql.Sprintf( "USE %s", PROJECT_DATA_DIR);
+ iRc = sql.ExecuteNonQuery( sSql );
+ if( iRc != XB_NO_ERROR ){
+ std::cout << "USE PROJECT_DATA_DIR error" << std::endl;
+ x.DisplayError( iRc );
+ return 1;
+ } else {
+ std::cout << sSql << " successful" << std::endl;
+ }
+
+ sSql = "DROP TABLE IF EXISTS TESTTBL.DBF";
+ iRc = sql.ExecuteNonQuery( sSql );
+ if( iRc != XB_NO_ERROR ){
+ std::cout << "DROP TABLE error" << std::endl;
+ x.DisplayError( iRc );
+ return 1;
+ } else {
+ std::cout << "DROP TABLE successful" << std::endl;
+ }
+
+ std::cout << "Drop table completed\n";
+
+ sSql = "CREATE TABLE TESTTBL.DBF( CHRFLD CHAR(60), DTFLD DATE, INTFLD INTEGER, SMINTFLD SMALLINT, NUMFLD NUMERIC(9,4), DECFLD DECIMAL(9,4), FLTFLD FLOAT(9,4) VCHARFLD VARCHAR, LGFLD LOGICAL)";
+ iRc = sql.ExecuteNonQuery( sSql );
+ if( iRc != XB_NO_ERROR ){
+ std::cout << "CREATE TABLE error" << std::endl;
+ x.DisplayError( iRc );
+ return 1;
+ } else {
+ std::cout << "CREATE TABLE successful" << std::endl;
+ }
+
+ sSql = "CREATE INDEX TAG1 ON TESTTBL.DBF( CHRFLD )";
+ iRc = sql.ExecuteNonQuery( sSql );
+ if( iRc != XB_NO_ERROR ){
+ std::cout << "CREATE INDEX error" << std::endl;
+ x.DisplayError( iRc );
+ return 1;
+ } else {
+ std::cout << "CREATE INDEX successful" << std::endl;
+ }
+
+
+ sSql = "INSERT INTO TESTTBL.DBF ( CHRFLD ) VALUES ( 'z' )";
+ iRc = sql.ExecuteNonQuery( sSql );
+ if( iRc != XB_NO_ERROR ){
+ std::cout << "INSERT error" << std::endl;
+ x.DisplayError( iRc );
+ return 1;
+ } else {
+ std::cout << "INSERT successful" << std::endl;
+ }
+
+ char c;
+ xbString s;
+ for( xbUInt16 i = 0; i < 3 && iRc == XB_NO_ERROR; i++ ){
+ for( xbUInt16 j = 0; j < 5 && iRc == XB_NO_ERROR; j++ ){
+ c = j + 65;
+ s = c;
+ s.PadRight( c, (xbUInt32) i + 1 );
+ sSql.Sprintf( "INSERT INTO TESTTBL.DBF ( CHRFLD ) VALUES ( '%s' )", s.Str());
+ std::cout << sSql.Str() << std::endl;
+ iRc = sql.ExecuteNonQuery( sSql );
+ if( iRc != XB_NO_ERROR ){
+ std::cout << "INSERT error" << std::endl;
+ x.DisplayError( iRc );
+ return 1;
+ }
+ }
+ }
+
+ x.CloseAllTables();
+ return 0;
+}
diff --git a/src/examples/xb_ex_ssv.cpp b/src/examples/xb_ex_ssv.cpp
new file mode 100755
index 0000000..61d72a2
--- /dev/null
+++ b/src/examples/xb_ex_ssv.cpp
@@ -0,0 +1,136 @@
+/* xb_ex_ssv.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2021,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+This program demonstrates using functionality of the xbSsv class (Shared system values)
+
+*/
+
+#include "xbase.h"
+
+using namespace xb;
+
+//int main( int ac, char ** av ){
+
+int main( int, char ** av ){
+
+ xbXBase x; // set up xbase for business
+ xbString sMsg; // a message string
+
+ sMsg.Sprintf( "Program [%s] initializing...", av[0] );
+ std::cout << sMsg.Str() << std::endl;
+
+
+ // example code to set up log file usage
+ #ifdef XB_LOGGING_SUPPORT
+ char cSeperator; // is this a unix (/) or windows (\) file system
+ xbString sLog; // general string for log file activities
+ sLog = x.GetLogFqFileName().Str(); // get the system default log file name
+ std::cout << "System default logfile is [" << sLog.Str() << "]" << std::endl;
+
+ cSeperator = sLog.GetPathSeparator(); // get the seperator from
+ std::cout << "Path seperator = [" << cSeperator << "]" << std::endl;
+
+ sLog.Sprintf( "..%c", cSeperator );
+ x.SetLogDirectory( sLog );
+ std::cout << "sLog = [" << sLog.Str() << "]\n";
+
+ sLog = x.GetLogFqFileName().Str(); // get the system default log file name
+ std::cout << "New logfile is [" << sLog.Str() << "]" << std::endl;
+
+ // turn on logging after file name set
+ x.EnableMsgLogging();
+ #endif // XB_LOGGING_SUPPORT
+
+ // const char *GetErrorMessage( xbInt16 ErrorCode ) const;
+ // void DisplayError( xbInt16 ErrorCode ) const;
+ std::cout << "DisplayError( -100 ) - ";
+ x.DisplayError( -100 );
+ // << "]" << std::endl;
+
+ // void SetDefaultDateFormat( const xbString &sDefaultDateFormat );
+ // xbString& GetDefaultDateFormat() const;
+ std::cout << "GetDefaultDateFormat() - " << x.GetDefaultDateFormat().Str() << std::endl;
+
+
+ // void SetDataDirectory ( const xbString &sDataDirectory );
+ // xbString& GetDataDirectory() const;
+ std::cout << "GetDataDirectory() - " << x.GetDataDirectory().Str() << std::endl;
+
+ // xbInt16 GetEndianType() const;
+ if( x.GetEndianType() == 'L' )
+ std::cout << "Little Endian Architecture." << std::endl;
+ else
+ std::cout << "Bid Endian Architecture." << std::endl;
+
+ //xbBool GetDefaultAutoCommit() const;
+ //void SetDefaultAutoCommit( xbBool bDefaultAutoCommit );
+ if( x.GetDefaultAutoCommit())
+ std::cout << "AutoCommit is on." << std::endl;
+ else
+ std::cout << "AutoCommit is off." << std::endl;
+
+ //xbBool GetMultiUser () const;
+ //void SetMultiUser ( xbBool bMultiUser );
+ if( x.GetMultiUser())
+ std::cout << "Multi user (locking) is enabled." << std::endl;
+ else
+ std::cout << "Multi user (locking) not enabled." << std::endl;
+
+ #if defined (XB_NDX_SUPPORT) || defined (XB_MDX_SUPPORT)
+ // xbInt16 GetUniqueKeyOpt () const;
+ // xbInt16 SetUniqueKeyOpt ( xbInt16 iUniqueKeyOpt );
+ // XB_HALT_ON_DUPKEY
+ // XB_EMULATE_DBASE
+ if( x.GetUniqueKeyOpt() == XB_HALT_ON_DUPKEY )
+ std::cout << "UniqueKey option - XB_HALT_ON_DUPKEY" << std::endl;
+ else if( x.GetUniqueKeyOpt() == XB_EMULATE_DBASE )
+ std::cout << "UniqueKey option - XB_EMULATE_DBASE" << std::endl;
+ #endif // (XB_NDX_SUPPORT) || defined (XB_MDX_SUPPORT)
+
+ #ifdef XB_LOCKING_SUPPORT
+ //xbInt16 GetDefaultLockRetries () const;
+ //void SetDefaultLockRetries ( xbInt16 iRetryCount );
+ //xbInt32 GetDefaultLockWait () const;
+ //void SetDefaultLockWait ( xbInt32 lRetryWait );
+ //xbInt16 GetDefaultLockFlavor () const;
+ //void SetDefaultLockFlavor ( xbInt16 iLockFlavor );
+ //xbBool GetDefaultAutoLock () const;
+ //void SetDefaultAutoLock ( xbBool bAutoLock );
+ //void EnableDefaultAutoLock ();
+ //void DisableDefaultAutoLock ();
+
+ std::cout << "GetDefaultLockRetries() - " << x.GetDefaultLockRetries() << std::endl;
+ std::cout << "GetDefaultLockWait() - " << x.GetDefaultLockWait() << std::endl;
+ std::cout << "GetDefaultAutoLock() - " << x.GetDefaultAutoLock() << std::endl;
+ #endif // XB_LOCKING_SUPPORT
+
+ #ifdef XB_MDX_SUPPORT
+ // xbInt16 GetCreateMdxBlockSize() const;
+ // xbInt16 SetCreateMdxBlockSize( xbInt16 ulBlockSize );
+ std::cout << "GetCreateMdxBlockSize() - " << x.GetCreateMdxBlockSize() << std::endl;
+ #endif // XB_MDX_SUPPORT
+
+ #ifdef XB_BLOCKREAD_SUPPORT
+ // xbUInt32 GetDefaultBlockReadSize() const;
+ // void SetDefaultBlockReadSize( xbUInt32 ulDfltBlockReadSize );
+ std::cout << "GetDefaultBlockReadSize() - " << x.GetDefaultBlockReadSize() << std::endl;
+ #endif // XB_BLOCKREAD_SUPPORT
+
+ //xbBool BitSet ( unsigned char c, xbInt16 iBitNo ) const;
+ //void BitDump ( unsigned char c ) const;
+ //void BitDump ( char c ) const;
+ std::cout << "BitDump( 'A' ) - ";
+ x.BitDump( 'A' );
+
+ return 0;
+}
diff --git a/src/examples/xb_ex_string.cpp b/src/examples/xb_ex_string.cpp
new file mode 100755
index 0000000..0cd7671
--- /dev/null
+++ b/src/examples/xb_ex_string.cpp
@@ -0,0 +1,381 @@
+/* xb_ex_string.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2021,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+*/
+
+// This demonstrates the string class
+
+
+#include "xbase.h"
+
+using namespace xb;
+
+int main()
+{
+
+ // create a string, assign a value, print it
+ xbString s1;
+ s1 = "Test String 1";
+ fprintf( stdout, "s1 = [%s]\n", s1.Str());
+
+ // create another string, copy the value from s1 into it, print it
+ xbString s2;
+ s2 = s1;
+ std::cout << "s2 = [" << s2.Str() << "]" << std::endl;
+
+ // create another string with and print it
+ xbString s3( 'X' );
+ std::cout << "s3 = [" << s3.Str() << "]" << std::endl;
+
+ // create another string with and print it and print it out yet another way
+ xbString s4( "Class constructor test 4" );
+ printf( "s4 = [%s]\n", s4.Str() );
+
+ // create another string with a size limit and print it out
+ xbString s5( "Class constructor test 4", 7 );
+ printf( "s5 = [%s]\n", s5.Str() );
+
+ // create another string from a string
+ xbString s6( s5 );
+ printf( "s6 = [%s]\n", s6.Str() );
+
+ // create 100 byte string with nothing in it
+ xbString s7( (xbUInt32) 100 );
+ printf( "s7 = [%s]\n", s7.Str() );
+
+ // Extract character from a particular position in the string
+ printf( "[] test -- Position 7 (starts from 1) from String 1 = [%c]\n", s1[7] );
+ // or use the getCharacter method
+ printf( "getCharacter() test -- Position 7 (starts from 1) from String 1 = [%c]\n", s1.GetCharacter(7) );
+
+ // set string 7 to a character
+ s7 = 'Z';
+ printf( "updated s7 = [%s]\n", s7.Str() );
+
+ // trim methods
+ s3 = " abc ";
+ s3.Ltrim();
+ #ifdef XB_DEBUG_SUPPORT
+ s3.Dump( "LTrim test" );
+ #else
+ std::cout << s3.Str() << std::endl;
+ #endif
+
+ s3 = " abc ";
+ s3.Rtrim();
+ std::cout << "RTrim test - " << s3.Str() << std::endl;
+
+ s3.Trim();
+ std::cout << "Trim test - " << s3.Str() << std::endl;
+ printf( "s3 Len = [%d]\n", s3.Len() );
+
+ // Concatenation tests - I
+ s1 = "Concatenation test1 part 1 ";
+ s1 += "Concatenation test1 part 2 ";
+ s2 = " s2 data ";
+ s1 += s2;
+ s1 += 'z';
+
+ // Concatenation tests - II
+ s1 = "Concatenation test1 part 1 ";
+ s1 -= "Concatenation test1 part 2 ";
+ s1 -= 'X';
+ s1 -= s2;
+ std::cout << "Concatenation test 2 - " << s1.Str() << std::endl;
+
+ // Concatenation tests - III
+ s1 = "s1data ";
+ s2 = "s2data ";
+
+ s3 = s1 - s2;
+ std::cout << "Concatenation test 3a - " << s3.Str() << std::endl;
+
+ s3 = s1 + s2;
+ std::cout << "Concatenation test 3b - " << s3.Str() << std::endl;
+
+ s3 = s1 + " char * data ";
+ std::cout << "Concatenation test 3c - " << s3.Str() << std::endl;
+
+ s3 = s1 + 'Z';
+ std::cout << "Concatenation test 3d - " << s3.Str() << std::endl;
+
+ s3 = 'A';
+
+ std::cout << s3.Str() << std::endl;
+ s3 += s1;
+
+ std::cout << s3.Str() << std::endl;
+
+ // The following compiles and runs, but is not valid
+ // s3 = 'A' + s1;
+
+ std::cout << std::endl << "== operator tests" << std::endl;
+ if( s1 == s2 )
+ std::cout << s1.Str() << " == " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " != " << s2.Str() << std::endl;
+
+ s1 = s2;
+ if( s1 == s2 )
+ std::cout << s1.Str() << " == " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " != " << s2.Str() << std::endl;
+
+ if( s1 == "sometestdata" )
+ std::cout << s1.Str() << " == sometestdata" << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " != sometestdata" << s2.Str() << std::endl;
+
+ std::cout << std::endl << "!= operator tests" << std::endl;
+ s2 = "abc123";
+ std::cout << "s1 - " << s1.Str() << std::endl;
+ std::cout << "s2 - " << s2.Str() << std::endl;
+
+ if( s1 != s2 )
+ std::cout << s1.Str() << " != " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " == " << s2.Str() << std::endl;
+
+ s1 = s2;
+ if( s1 != s2 )
+ std::cout << s1.Str() << " != " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " == " << s2.Str() << std::endl;
+
+ if( s1 != "sometestdata" )
+ std::cout << s1.Str() << " != [sometestdata]" << std::endl;
+ else
+ std::cout << s1.Str() << " == [sometestdata]" << std::endl;
+
+ std::cout << std::endl << "< operator tests" << std::endl;
+ s1 = "AAA";
+ s2 = "BBB";
+
+ if( s1 < s2 )
+ std::cout << s1.Str() << " < " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " >= " << s2.Str() << std::endl;
+
+ s1 = "BBB";
+ if( s1 < s2 )
+ std::cout << s1.Str() << " < " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " >= " << s2.Str() << std::endl;
+
+ s1 = "CCC";
+ if( s1 < s2 )
+ std::cout << s1.Str() << " < " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " >= " << s2.Str() << std::endl;
+
+ std::cout << std::endl << "> operator tests" << std::endl;
+ s1 = "AAA";
+ s2 = "BBB";
+
+ if( s1 > s2 )
+ std::cout << s1.Str() << " > " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " <= " << s2.Str() << std::endl;
+
+ s1 = "BBB";
+ if( s1 > s2 )
+ std::cout << s1.Str() << " > " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " <= " << s2.Str() << std::endl;
+
+ s1 = "CCC";
+ if( s1 > s2 )
+ std::cout << s1.Str() << " > " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " <= " << s2.Str() << std::endl;
+
+ std::cout << std::endl << "<= operator tests" << std::endl;
+ s1 = "AAA";
+ s2 = "BBB";
+
+ if( s1 <= s2 )
+ std::cout << s1.Str() << " <= " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " > " << s2.Str() << std::endl;
+
+ s1 = "BBB";
+ if( s1 <= s2 )
+ std::cout << s1.Str() << " <= " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " > " << s2.Str() << std::endl;
+
+ s1 = "CCC";
+ if( s1 <= s2 )
+ std::cout << s1.Str() << " <= " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " > " << s2.Str() << std::endl;
+
+ std::cout << std::endl << ">= operator tests" << std::endl;
+ s1 = "AAA";
+ s2 = "BBB";
+
+ if( s1 >= s2 )
+ std::cout << s1.Str() << " >= " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " < " << s2.Str() << std::endl;
+
+ s1 = "BBB";
+ if( s1 >= s2 )
+ std::cout << s1.Str() << " >= " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " < " << s2.Str() << std::endl;
+
+ s1 = "CCC";
+ if( s1 >= s2 )
+ std::cout << s1.Str() << " >= " << s2.Str() << std::endl;
+ else
+ std::cout << s1.Str() << " < " << s2.Str() << std::endl;
+
+ std::cout << "(const char *) " << (const char *) s2.Str() << std::endl;
+
+ std::cout << std::endl << "CountChar() test" << std::endl;
+ s1 = "ABADFDSGA";
+ xbUInt32 i = s1.CountChar( 'A' );
+ std::cout << "There are " << i << " 'A's in " << s1.Str() << std::endl;
+
+ s1.Ltrunc( 4 );
+ std::cout << "lTunc(4) test s1 = [" << s1.Str() << "]" << std::endl;
+
+ std::cout << std::endl << "PutAt() test" << std::endl;
+ s1.PutAt( 3, 'Z' );
+ std::cout << "Third char should be a 'Z' = " << s1.Str() << std::endl;
+
+ std::cout << std::endl << "AddBackSlash() test" << std::endl;
+ s1.AddBackSlash( 'Z' );
+ std::cout << "Should be a backslash before the 'Z' = " << s1.Str() << std::endl;
+
+ std::cout << std::endl << "Assign() test" << std::endl;
+ s2 = "1234567890";
+ std::cout << "s2 = " << s2.Str() << std::endl;
+ s1.Assign( s2, 4, 5 );
+ std::cout << "assign( s2, 4, 5 ) results = " << s1.Str() << std::endl;
+ s1.Assign( s2, 4, 15 );
+ std::cout << "assign( s2, 4, 15 ) results = " << s1.Str() << std::endl;
+
+ s1.Assign( s2, 5 );
+ std::cout << "Assign( s2, 5 ) results = " << s1.Str() << std::endl;
+ s1.Assign( s2, 15 );
+ std::cout << "Assign( s2, 15 ) results = " << s1.Str() << std::endl;
+
+ std::cout << std::endl << "s1.copy() test" << std::endl;
+ s1 = "ABC";
+ std::cout << "s1 = " << s1.Str() << std::endl;
+ std::cout << "s2 = " << s2.Str() << std::endl;
+
+ s1 = s2.Copy();
+ std::cout << "s1.Copy() results" << s1.Str() << std::endl;
+
+ s1 = "0x35";
+ char hexChar;
+ s1.CvtHexChar( hexChar );
+ std::cout << "CvtHexChar test [" << s1.Str() << "] converts to [" << hexChar << "]" << std::endl;
+ s1 = "0x65";
+ s1.CvtHexChar( hexChar );
+ std::cout << "cvHexChar test [" << s1.Str() << "] converts to [" << hexChar << "]" << std::endl;
+
+ s1 = "0x610x620x630x640x65";
+ s1.CvtHexString( s2 );
+ std::cout << "CvtHexString [" << s1.Str() << "] converts to [" << s2.Str() << "]" << std::endl;
+
+ s1.ExtractElement( "aaaa|bbbb|cccc|dddd", '|', 2, 0 );
+ std::cout << "ExtractElement() " << s1.Str() << std::endl;
+
+ s1 = "123";
+ s2 = "ABC";
+ std::cout << "HasAlphaChars( " << s1.Str() << " ) = " << s1.HasAlphaChars() << std::endl;
+ std::cout << "HasAlphaChars( " << s2.Str() << " ) = " << s2.HasAlphaChars() << std::endl;
+
+ s2 = "";
+ std::cout << "IsEmpty( " << s1.Str() << " ) = " << s1.IsEmpty() << std::endl;
+ std::cout << "IsEmpty( " << s2.Str() << " ) = " << s2.IsEmpty() << std::endl;
+
+ s1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ std::cout << s1.Str() << " s1.Mid( 3,5 ) = [" << s1.Mid( 3, 5 ).Str() << "]" << std::endl;
+ std::cout << s1.Str() << " s1.Mid( 25, 10 ) = [" << s1.Mid( 25, 10 ).Str() << "]" << std::endl;
+
+ std::cout << s1.Str() << " s1.Pos('G') = " << s1.Pos( 'G' ) << std::endl;
+ std::cout << s1.Str() << " s1.Pos(\"JKL\") = " << s1.Pos( "JKL" ) << std::endl;
+
+ std::cout << "Remove( 3, 5 ) before " << s1.Str() << std::endl;
+ std::cout << s1.Str() << " s1.Remove( 3, 5 ) = [" << s1.Remove( 3, 5 ).Str() << "]" << std::endl;
+ std::cout << "Remove( 3, 5 ) after " << s1.Str() << std::endl;
+ s1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ std::cout << "s1.Remove( 20, 10 ) = [" << s1.Remove( 20, 10 ).Str() << "]" << std::endl;
+
+ std::cout << "Remove( 20, 10 ) - " << s1.Str() << std::endl;
+
+
+ s1.Sprintf( "%d", 12345 );
+ std::cout << "Sprintf( %d, 12345 ) " << s1.Str() << std::endl;
+
+ s1.SetNum( (long) 123456 );
+ std::cout << "s1.SetNum( 123456 ) = " << s1.Str() << std::endl;
+
+ s1.Set( "Yet another way to set a string value" );
+ std::cout << "Set - " << s1.Str() << std::endl;
+
+ s1 = "ABCABCABZ";
+ std::cout << "SwapChars( 'A', '9' ) before - " << s1.Str() << std::endl;
+ s1.SwapChars( 'A', '9' );
+ std::cout << "SwapChars( 'A', '9' ) after - " << s1.Str() << std::endl;
+
+ s1.ToLowerCase();
+ std::cout << "ToLowerCase - " << s1.Str() << std::endl;
+
+ s1.ToUpperCase();
+ std::cout << "ToUpperCase - " << s1.Str() << std::endl;
+
+ s1.ZapChar( '9' );
+ std::cout << "ZapChar( '9' )" << s1.Str() << std::endl;
+
+ s1.ZapLeadingChar( 'B' );
+ std::cout << "ZapLeadingChar( 'B' )" << s1.Str() << std::endl;
+
+ s1.ZapTrailingChar( 'Z' );
+ std::cout << "ZapLeadingChar( 'Z' ) - " << s1.Str() << std::endl;
+
+ s1 = "123";
+ s1.PadLeft( '0', 9 );
+ std::cout << "s1.PadLeft('0', 9 ) - " << s1.Str() << std::endl;
+
+ s1 = "abc";
+ s1.PadRight( 'Z', 9 );
+ std::cout << "s1.PadRight('Z', 9 ) " << s1.Str() << std::endl;
+
+ xbString sNullString;
+ if( sNullString.IsNull())
+ std::cout << "sNullString is null" << std::endl;
+ else
+ std::cout << "sNullString is not null" << std::endl;
+
+ xbString tstS( "ZZZZZZZZZ" );
+ tstS = s1.Left( 5 );
+
+ std::cout << "tstS = " << tstS.Str() << "\n";
+ std::cout << "s1 = " << s1.Str() << "\n";
+
+ tstS = "1234567890";
+ std::cout << "mid result = " << tstS.Mid( 3, 3 ).Str() << std::endl;
+
+ tstS = "1234567890";
+ std::cout << "left result = " << tstS.Left( 3 ).Str() << std::endl;
+
+
+ return 0;
+}
diff --git a/src/examples/xb_ex_v3_create_dbf.cpp b/src/examples/xb_ex_v3_create_dbf.cpp
new file mode 100755
index 0000000..d6f7047
--- /dev/null
+++ b/src/examples/xb_ex_v3_create_dbf.cpp
@@ -0,0 +1,110 @@
+/* xb_ex_v3_create_dbf.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+ This example demonstrates the creation of a Version III file and and indices
+
+*/
+
+#include <xbase.h>
+
+using namespace xb;
+
+int main()
+{
+
+#ifdef XB_DBF3_SUPPORT
+
+ xbSchema MyRecord[] =
+ {
+ { "FIRSTNAME", XB_CHAR_FLD, 15, 0 },
+ { "LASTNAME", XB_CHAR_FLD, 20, 0 },
+ { "BIRTHDATE", XB_DATE_FLD, 8, 0 },
+ { "AMOUNT", XB_NUMERIC_FLD, 9, 2 },
+ { "RETIRED?", XB_LOGICAL_FLD, 1, 0 },
+ { "ZIPCODE", XB_NUMERIC_FLD, 5, 0 },
+#ifdef XB_MEMO_SUPPORT
+ { "MEMO1", XB_MEMO_FLD, 10, 0 },
+#endif
+ { "",0,0,0 }
+ };
+
+ /* define the classes */
+ xbXBase x; /* initialize xbase */
+ x.SetDataDirectory( PROJECT_DATA_DIR ); /* where all the tables live */
+
+ xbDbf *MyDbfFile; /* Pointer to dbf class */
+ MyDbfFile = new xbDbf3(&x); /* Create Version 3 instance */
+
+
+// Create Dbase3 NDX style indices if support compiled in
+ #ifdef XB_NDX_SUPPORT
+ xbIxNdx MyIndex1( MyDbfFile ); /* class for index 1 */
+ xbIxNdx MyIndex2( MyDbfFile ); /* class for index 2 */
+ xbIxNdx MyIndex3( MyDbfFile ); /* class for index 3 */
+ #endif
+
+
+ // fixme
+ // Create Clipper NTX style indices if support compiled in - bring this back to life in a future release
+ #ifdef XB_INDEX_NTX
+ xbNtx MyIndex4( &MyDbfFile ); /* class for index 4 */
+ xbNtx MyIndex5( &MyDbfFile ); /* class for index 5 */
+ #endif
+
+ xbInt16 rc;
+
+ if(( rc = MyDbfFile->CreateTable( "MyV3Table1", "MyV3ExampleTableAlias", MyRecord, XB_OVERLAY, XB_MULTI_USER )) != XB_NO_ERROR )
+ x.DisplayError( rc );
+ else
+ {
+
+ #ifdef XB_NDX_SUPPORT
+
+ xbIx *pIx;
+ void *pTag;
+
+ /*
+ Create a few index tags
+ CreateTag( const xbString &sIxType, const xbString &sName, const xbString &sKey, const xbString &sFilter,
+ xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverLay, xbIx **xbIxOut, void **vpTagOut );
+ */
+
+ /* define a simple index */
+ if(( rc = MyDbfFile->CreateTag ( "NDX", "MYINDEX1.NDX", "LASTNAME", "", 0, 1, XB_OVERLAY, &pIx, &pTag )) != XB_NO_ERROR )
+ x.DisplayError( rc );
+
+
+ /* define a multi-field index "LASTNAME FIRSTNAME" */
+ if(( rc = MyDbfFile->CreateTag( "NDX", "MYINDEX2.NDX", "LASTNAME+FIRSTNAME", "", 0, 1, XB_OVERLAY, &pIx, &pTag )) != XB_NO_ERROR )
+ x.DisplayError( rc );
+
+ /* define a numeric index "ZIPCODE" */
+ if(( rc = MyDbfFile->CreateTag( "NDX", "MYINDEX3.NDX", "ZIPCODE", "", 0, 0, XB_OVERLAY, &pIx, &pTag )) != XB_NO_ERROR )
+ x.DisplayError( rc );
+
+ std::cout << "Tag Count in MYINDEX3.NDX = " << pIx->GetTagCount() << "\n";
+ xbString sTagName;
+ sTagName = pIx->GetTagName( &pTag );
+ std::cout << "Tag Name in MYINDEX3.NDX = " << sTagName.Str() << "\n";
+
+
+ #endif
+
+ }
+
+ MyDbfFile->Close(); /* Close database and associated indexes */
+ delete MyDbfFile;
+
+ #endif // XB_DBF3_SUPPORT
+ return 0;
+}
diff --git a/src/examples/xb_ex_v3_upd_dbf.cpp b/src/examples/xb_ex_v3_upd_dbf.cpp
new file mode 100755
index 0000000..eecba16
--- /dev/null
+++ b/src/examples/xb_ex_v3_upd_dbf.cpp
@@ -0,0 +1,326 @@
+/* xb_ex_v3_upd_dbf.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2021,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+ This example demonstrates how to open the DBase III table created by xb_ex_v3_create_dbf
+ and apply various updates to the table.
+
+*/
+
+#include <xbase.h>
+
+using namespace xb;
+
+int main()
+{
+
+#ifdef XB_DBF3_SUPPORT
+
+ xbInt16 fld_FIRSTNAME;
+ xbInt16 fld_LASTNAME;
+ xbInt16 fld_BIRTHDATE;
+ xbInt16 fld_AMOUNT;
+ xbInt16 fld_RETIRED;
+ xbInt16 fld_ZIPCODE;
+
+ #ifdef XB_MEMO_SUPPORT
+ xbInt16 fld_MEMO1;
+ xbString sMemoData;
+ #endif
+
+
+ /* define the classes */
+ xbXBase x; /* initialize xbase */
+ x.SetDataDirectory( PROJECT_DATA_DIR ); /* where all the tables live */
+ x.EnableMsgLogging();
+ x.WriteLogMessage( "Program [xb_ex_v3_upd_dbf] initializing..." );
+
+
+ xbDbf * MyTable = new xbDbf3( &x ); /* class for V3 table */
+
+ xbString sSearchKey; /* string for doing an index lookup */
+
+ xbInt16 iRc = 0;
+ xbInt16 iErrorStop = 0;
+
+ try{
+
+ if(( iRc = MyTable->Open( "MyV3Table1.DBF" )) != XB_NO_ERROR ){
+ iErrorStop = 100;
+ throw iRc;
+ }
+
+
+ #ifdef XB_NDX_SUPPORT
+ // V3 NDX style indices can be opened manually (vs production MDX index files opened automatically)
+
+
+ if(( iRc = MyTable->OpenIndex( "NDX", "MYINDEX1.NDX")) != XB_NO_ERROR ){
+ iErrorStop = 110;
+ throw iRc;
+ }
+
+
+/*
+ if(( iRc = MyTable->OpenIndex( "NDX", "MYINDEX2.NDX" )) != XB_NO_ERROR ){
+ iErrorStop = 120;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->OpenIndex( "NDX", "MYINDEX3.NDX" )) != XB_NO_ERROR ){
+ iErrorStop = 130;
+ throw iRc;
+ }
+*/
+
+ std::cout << "Current tag = [" << MyTable->GetCurTagName().Str() << "]\n";
+ #endif
+
+ // get the field numbers for all the fields in the table
+ fld_FIRSTNAME = MyTable->GetFieldNo( "FIRSTNAME" );
+ fld_LASTNAME = MyTable->GetFieldNo( "LASTNAME" );
+ fld_BIRTHDATE = MyTable->GetFieldNo( "BIRTHDATE" );
+ fld_AMOUNT = MyTable->GetFieldNo( "AMOUNT" );
+ fld_RETIRED = MyTable->GetFieldNo( "RETIRED?" );
+ fld_ZIPCODE = MyTable->GetFieldNo( "ZIPCODE" );
+
+
+
+ // do an index lookup for (key does not exist in this example)
+ sSearchKey = "abc123";
+ if(( iRc = MyTable->Find( sSearchKey )) != XB_NOT_FOUND ){
+ iErrorStop = 140;
+ throw iRc;
+ }
+ std::cout << "RC = " << iRc << "\n";
+
+
+
+ #ifdef XB_MEMO_SUPPORT
+ fld_MEMO1 = MyTable->GetFieldNo( "MEMO1" );
+ #endif
+
+
+
+ // Blank the record buffer
+ if(( iRc = MyTable->BlankRecord()) != XB_NO_ERROR ){
+ iErrorStop = 140;
+ throw iRc;
+ }
+
+
+ // put field examples - using field numbers
+ if(( iRc = MyTable->PutField( fld_LASTNAME, "JONES" )) != XB_NO_ERROR ){
+ iErrorStop = 150;
+ throw iRc;
+ }
+
+
+ if(( iRc = MyTable->PutField( fld_FIRSTNAME, "JERRY" )) != XB_NO_ERROR ){
+ iErrorStop = 160;
+ throw iRc;
+ }
+
+
+ if(( iRc = MyTable->PutField( fld_AMOUNT, "12.35" )) != XB_NO_ERROR ){
+ iErrorStop = 170;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutField( fld_BIRTHDATE, "19880208" )) != XB_NO_ERROR ){
+ iErrorStop = 180;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutLogicalField( fld_RETIRED, "Y" )) != XB_NO_ERROR ){
+ iErrorStop = 190;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutLongField( fld_ZIPCODE, 12345 )) != XB_NO_ERROR ){
+ iErrorStop = 200;
+ throw iRc;
+ }
+
+ #ifdef XB_MEMO_SUPPORT
+ sMemoData = "Memo data record 1";
+ if(( iRc = MyTable->UpdateMemoField( fld_MEMO1, sMemoData )) != XB_NO_ERROR ){
+ iErrorStop = 210;
+ throw iRc;
+ }
+ #endif
+
+ // Append the first record
+ if(( iRc = MyTable->AppendRecord()) != XB_NO_ERROR ){
+ // here is where you would address any errors.
+ // in this program, we simply abort and continue
+ MyTable->Abort();
+ }
+
+ // put field to the record buffer using field name (slightly less efficient than using field numbers)
+ // Blank the record buffer
+ if(( iRc = MyTable->BlankRecord()) != XB_NO_ERROR ){
+ iErrorStop = 220;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutField( "LASTNAME", "EINSTIEN" )) != XB_NO_ERROR ){
+ iErrorStop = 230;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutField( "FIRSTNAME", "ALBERT" )) != XB_NO_ERROR ){
+ iErrorStop = 240;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutField( "AMOUNT", "987.55" )) != XB_NO_ERROR ){
+ iErrorStop = 250;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutField( fld_BIRTHDATE, "19890209" )) != XB_NO_ERROR ){
+ iErrorStop = 260;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutLogicalField( "RETIRED?", "N" )) != XB_NO_ERROR ){
+ iErrorStop = 270;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutLongField( "ZIPCODE", 44256 )) != XB_NO_ERROR ){
+ iErrorStop = 280;
+ throw iRc;
+ }
+
+ #ifdef XB_MEMO_SUPPORT
+ sMemoData = "Memo data record 2";
+ if(( iRc = MyTable->UpdateMemoField( fld_MEMO1, sMemoData )) != XB_NO_ERROR ){
+ iErrorStop = 290;
+ throw iRc;
+ }
+ #endif
+
+ // Append the second record
+ if(( iRc = MyTable->AppendRecord()) != XB_NO_ERROR ){
+ // here is where you would address any errors.
+ // in this program, we simply abort and continue
+ MyTable->Abort();
+ }
+
+
+ if(( iRc = MyTable->GetRecord( 1 )) != XB_NO_ERROR ){
+ iErrorStop = 300;
+ throw iRc;
+ }
+ // get a field with a field number
+ xbString sFirstName;
+ if(( iRc = MyTable->GetField( fld_FIRSTNAME, sFirstName )) < 0 ){
+ iErrorStop = 310;
+ throw iRc;
+ }
+ std::cout << "First Name is [" << sFirstName.Str() << "]" << std::endl;
+
+ xbString sLastName;
+ if(( iRc = MyTable->GetField( "LASTNAME", sLastName )) < 0 ){
+ iErrorStop = 320;
+ throw iRc;
+ }
+ std::cout << "Last Name is [" << sLastName.Str() << "]" << std::endl;
+
+ xbInt16 iNoOfDecimals;
+ if(( iRc = MyTable->GetFieldDecimal( "AMOUNT", iNoOfDecimals )) != XB_NO_ERROR ){
+ iErrorStop = 330;
+ throw iRc;
+ }
+ std::cout << "There are " << iNoOfDecimals << " decimals in the AMOUNT field" << std::endl;
+
+ xbString FieldName;
+ if(( iRc = MyTable->GetFieldName( 4, FieldName )) != XB_NO_ERROR ){
+ iErrorStop = 340;
+ throw iRc;
+ }
+ std::cout << "Field #4 name is " << FieldName.Str() << std::endl;
+
+ xbString sRetired;
+ if(( iRc = MyTable->GetLogicalField( "RETIRED?", sRetired )) < 0 ){
+ iErrorStop = 350;
+ throw iRc;
+ }
+ std::cout << "Switch value = [" << sRetired.Str() << "]" << std::endl;
+
+ xbInt32 lZip;
+ if(( iRc = MyTable->GetLongField( "ZIPCODE", lZip )) < 0 ){
+ iErrorStop = 360;
+ throw iRc;
+ }
+ std::cout << "Long value = [" << lZip << "]" << std::endl;
+
+ // Initialize the record buffer in preparation for another record
+ if(( iRc = MyTable->BlankRecord()) != XB_NO_ERROR ){
+ iErrorStop = 370;
+ throw iRc;
+ }
+
+ // Append another record (it will be blank)
+ if(( iRc = MyTable->AppendRecord()) != XB_NO_ERROR ){
+ // here is where you would address any errors.
+ // in this program, we simply abort and continue
+ MyTable->Abort();
+ };
+
+ // mark record 1 for deletion
+ if(( iRc = MyTable->GetRecord( 1 )) != XB_NO_ERROR ){
+ iErrorStop = 300;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->DeleteRecord()) != XB_NO_ERROR ){
+ iErrorStop = 380;
+ throw iRc;
+ };
+
+ // save current record
+ if(( iRc = MyTable->PutRecord()) != XB_NO_ERROR ){
+ iErrorStop = 390;
+ throw iRc;
+ }
+ // pack the table with no options
+ if(( iRc = MyTable->Pack()) != XB_NO_ERROR ){
+ iErrorStop = 400;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->Commit()) != XB_NO_ERROR ){
+ // here is where you would address any errors.
+ // in this program, we simply abort and continue
+ MyTable->Abort();
+ }
+
+ /* Close database and associated indexes */
+ if(( iRc = MyTable->Close()) != XB_NO_ERROR ){
+ iErrorStop = 410;
+ throw iRc;
+ }
+
+ }
+ catch( xbInt16 rc ){
+ std::cout << "xb_ex_v3_upd_dbf error. Error stop point = [" << iErrorStop << "] iRc = [" << rc << "]" << std::endl;
+ std::cout << x.GetErrorMessage( rc ) << std::endl;
+ }
+
+ delete MyTable;
+
+ #endif // XB_DBF3_SUPPORT
+ return 0;
+}
diff --git a/src/examples/xb_ex_v4_create_dbf.cpp b/src/examples/xb_ex_v4_create_dbf.cpp
new file mode 100755
index 0000000..d6bfb2f
--- /dev/null
+++ b/src/examples/xb_ex_v4_create_dbf.cpp
@@ -0,0 +1,100 @@
+/* xb_ex_v4_create_dbf.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022,2023 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+ This example demonstrates the creation of a Version IV file and and indices
+
+ Creates three files in folder "PROJECT_DATA_DIR"
+ Address.DBF - Table with all the data
+ Address.DBT - Memo (variable lenght char field) data
+ Address.MDX - File with index data
+
+*/
+
+#include <xbase.h>
+
+using namespace xb;
+
+int main()
+{
+
+#ifdef XB_DBF4_SUPPORT
+
+ xbSchema MyAddressBookRecord[] =
+ {
+ { "LASTNAME", XB_CHAR_FLD, 20, 0 },
+ { "FIRSTNAME", XB_CHAR_FLD, 15, 0 },
+ { "COMPANY", XB_CHAR_FLD, 20, 0 },
+ { "ADDRESS", XB_CHAR_FLD, 35, 0 },
+ { "CITY", XB_CHAR_FLD, 30, 0 },
+ { "STATECD", XB_CHAR_FLD, 2, 0 },
+ { "ZIPCD", XB_CHAR_FLD, 10, 0 },
+
+ { "BIRTHDATE", XB_DATE_FLD, 8, 0 },
+
+ { "AMOUNT1", XB_NUMERIC_FLD, 9, 2 },
+ { "AMOUNT2", XB_FLOAT_FLD, 12, 2 },
+
+ { "FRIEND?", XB_LOGICAL_FLD, 1, 0 },
+ { "FAMILY?", XB_LOGICAL_FLD, 1, 0 },
+ { "BUSASSOC?", XB_LOGICAL_FLD, 1, 0 },
+
+ #ifdef XB_MEMO_SUPPORT
+ { "NOTES", XB_MEMO_FLD, 10, 0 },
+ #endif
+ { "",0,0,0 }
+ };
+
+ /* define the classes */
+ xbXBase x; /* initialize xbase */
+ x.SetDataDirectory( PROJECT_DATA_DIR ); /* where all the tables/files live */
+
+ xbInt16 iRc;
+ xbDbf * MyDbfFile;
+
+ #ifdef XB_MDX_SUPPORT
+ xbIx *pIx;
+ void *pTag;
+ #endif // XB_MDX_SUPPORT
+
+ MyDbfFile = new xbDbf4( &x );
+
+ if(( iRc = MyDbfFile->CreateTable( "Address.DBF", "Address", MyAddressBookRecord, XB_OVERLAY, XB_MULTI_USER )) != XB_NO_ERROR )
+ x.DisplayError( iRc );
+ else
+ {
+
+ #ifdef XB_MDX_SUPPORT
+
+ /*
+ Create a few index tags
+ CreateTag( const xbString &sIxType, const xbString &sName, const xbString &sKey, const xbString &sFilter,
+ xbInt16 iDescending, xbInt16 iUnique, xbInt16 iOverLay, xbIx **xbIxOut, void **vpTagOut );
+ */
+
+ // std::cout << "Creating three index tags\n";
+ if(( iRc = MyDbfFile->CreateTag( "MDX", "NAME", "LASTNAME+FIRSTNAME", ".NOT. DELETED()", 0, 0, XB_OVERLAY, &pIx, &pTag )) != XB_NO_ERROR )
+ x.DisplayError( iRc );
+ if(( iRc = MyDbfFile->CreateTag( "MDX", "BDDATE", "BIRTHDATE", ".NOT. DELETED()", 0, 0, XB_OVERLAY, &pIx, &pTag )) != XB_NO_ERROR )
+ x.DisplayError( iRc );
+ if(( iRc = MyDbfFile->CreateTag( "MDX", "COMPANY", "COMPANY+LASTNAME+FIRSTNAME", ".NOT. DELETED()", 0, 0, XB_OVERLAY, &pIx, &pTag )) != XB_NO_ERROR )
+ x.DisplayError( iRc );
+
+ #endif // XB_MDX_SUPPORT
+ }
+
+ MyDbfFile->Close(); /* Close database and associated indexes */
+ delete MyDbfFile;
+
+ #endif // XB_DBF4_SUPPORT
+ return 0;
+}
diff --git a/src/examples/xb_ex_v4_upd_dbf.cpp b/src/examples/xb_ex_v4_upd_dbf.cpp
new file mode 100755
index 0000000..d128eba
--- /dev/null
+++ b/src/examples/xb_ex_v4_upd_dbf.cpp
@@ -0,0 +1,294 @@
+/* xb_ex_v4_upd_dbf.cpp
+
+XBase64 Software Library
+
+Copyright (c) 1997,2003,2014,2022 Gary A Kunkel
+
+The xb64 software library is covered under the terms of the GPL Version 3, 2007 license.
+
+Email Contact:
+
+ XDB-devel@lists.sourceforge.net
+ XDB-users@lists.sourceforge.net
+
+ This example demonstrates how to open the DBase IV table created by xb_ex_v4_create_dbf
+ and apply various updates to the table.
+
+*/
+
+#include <xbase.h>
+
+using namespace xb;
+
+int main()
+{
+
+#ifdef XB_DBF4_SUPPORT
+
+
+ /* define the classes */
+ xbXBase x; /* initialize xbase */
+ x.SetDataDirectory( PROJECT_DATA_DIR ); /* where all the tables live */
+ x.EnableMsgLogging();
+ x.WriteLogMessage( "Program [xb_ex_v4_upd_dbf] initializing..." );
+
+ xbDbf *MyTable = new xbDbf4( &x ); /* class for DBase V4 table */
+
+ xbInt16 iRc = 0;
+ xbInt16 iErrorStop = 0;
+
+ try{
+
+ if(( iRc = MyTable->Open( "Address.DBF" )) != XB_NO_ERROR ){
+ iErrorStop = 100;
+ throw iRc;
+ }
+
+ /* get the field numbers for all the fields in the table */
+
+ xbInt16 iFld_FIRSTNAME = MyTable->GetFieldNo( "FIRSTNAME" );
+ xbInt16 iFld_LASTNAME = MyTable->GetFieldNo( "LASTNAME" );
+ xbInt16 iFld_BIRTHDATE = MyTable->GetFieldNo( "BIRTHDATE" );
+ xbInt16 iFld_AMOUNT1 = MyTable->GetFieldNo( "AMOUNT1" );
+ xbInt16 iFld_FRIEND = MyTable->GetFieldNo( "FRIEND?" );
+ xbInt16 iFld_ZIPCD = MyTable->GetFieldNo( "ZIPCD" );
+ xbInt16 iFld_AMOUNT2 = MyTable->GetFieldNo( "AMOUNT2" );
+
+ #ifdef XB_MEMO_FIELDS
+ zbInt16 iFld_MEMO1 = MyTable->GetFieldNo( "MEMO1" );
+ #endif
+
+
+ #ifdef XB_MDX_SUPPPORT
+ std::cout << "Current tag = [" << MyTable->GetCurTagName() << "]\n";
+ #endif
+
+ // Blank the record buffer
+ if(( iRc = MyTable->BlankRecord()) != XB_NO_ERROR ){
+ iErrorStop = 110;
+ throw iRc;
+ }
+
+ // put field examples - using field numbers
+ if(( iRc = MyTable->PutField( iFld_LASTNAME, "JONES" )) != XB_NO_ERROR ){
+ iErrorStop = 120;
+ throw iRc;
+ }
+ // could also reference by field name (see below) but referencing by number
+ // is a little bit faster because it doesn't need to look up the number for the field name
+ // Alternative--> if(( iRc = MyTable->PutField( "LASTNAME", "JONES" )) != XB_NO_ERROR ){
+
+ if(( iRc = MyTable->PutField( iFld_FIRSTNAME, "JERRY" )) != XB_NO_ERROR ){
+ iErrorStop = 130;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutField( iFld_AMOUNT1, "12.35" )) != XB_NO_ERROR ){
+ iErrorStop = 140;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutLogicalField( iFld_FRIEND, "Y" )) != XB_NO_ERROR ){
+ iErrorStop = 150;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutField( iFld_BIRTHDATE, "19880209" )) != XB_NO_ERROR ){
+ iErrorStop = 160;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutLongField( iFld_ZIPCD, 12345 )) != XB_NO_ERROR ){
+ iErrorStop = 170;
+ throw iRc;
+ }
+
+ // Append the first record
+ if(( iRc = MyTable->AppendRecord()) != XB_NO_ERROR ){
+ iErrorStop = 180;
+ throw iRc;
+ }
+
+ // Commit the updates
+ if(( iRc = MyTable->Commit()) != XB_NO_ERROR ){
+ iErrorStop = 190;
+ throw iRc;
+ }
+
+ // Blank the record buffer
+ if(( iRc = MyTable->BlankRecord()) != XB_NO_ERROR ){
+ iErrorStop = 200;
+ throw iRc;
+ }
+
+ // put field to the record buffer using field name (slightly less efficient than using field numbers)
+ if(( iRc = MyTable->PutField( "LASTNAME", "FUCKPUTIN" )) != XB_NO_ERROR ){
+ iErrorStop = 210;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutField( "FIRSTNAME", "ALBERT" )) != XB_NO_ERROR ){
+ iErrorStop = 220;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutDoubleField( "AMOUNT1", (xbDouble) 987.55 )) != XB_NO_ERROR ){
+ iErrorStop = 230;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutLogicalField( "FRIEND?", "N" )) != XB_NO_ERROR ){
+ iErrorStop = 240;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->PutLongField( "ZIPCD", 44256 )) != XB_NO_ERROR ){
+ iErrorStop = 250;
+ throw iRc;
+ }
+
+ xbFloat f = (xbFloat) 12345.67;
+ std::cout << f << std::endl;
+
+ if(( iRc = MyTable->PutFloatField( iFld_AMOUNT2, f )) != XB_NO_ERROR ){
+ iErrorStop = 260;
+ throw iRc;
+ }
+ xbDouble d = 76543.21;
+ if(( iRc = MyTable->PutDoubleField( iFld_AMOUNT1, d )) != XB_NO_ERROR ){
+ iErrorStop = 270;
+ throw iRc;
+ }
+
+ // Append the second record
+ if(( iRc = MyTable->AppendRecord()) != XB_NO_ERROR ){
+ iErrorStop = 280;
+ throw iRc;
+ }
+
+ // Commit the updates
+ if(( iRc = MyTable->Commit()) != XB_NO_ERROR ){
+ iErrorStop = 290;
+ throw iRc;
+ }
+
+
+ // get a field with a field number
+ xbString FirstName;
+ if(( iRc = MyTable->GetField( iFld_FIRSTNAME, FirstName )) < 0 ){
+ iErrorStop = 300;
+ throw iRc;
+ }
+ std::cout << "First Name is [" << FirstName.Str() << "]" << std::endl;
+
+ xbString LastName;
+ if(( iRc = MyTable->GetField( "LASTNAME", LastName )) < 0 ){
+ iErrorStop = 310;
+ throw iRc;
+ }
+ std::cout << "Last Name is [" << LastName.Str() << "]" << std::endl;
+
+ xbInt16 iNoOfDecimals;
+ if(( iRc = MyTable->GetFieldDecimal( "AMOUNT2", iNoOfDecimals )) != XB_NO_ERROR ){
+ iErrorStop = 320;
+ throw iRc;
+ }
+ std::cout << "There are " << iNoOfDecimals << " decimals in the AMOUNT field" << std::endl;
+
+ xbString FieldName;
+ if(( iRc = MyTable->GetFieldName( 4, FieldName )) != XB_NO_ERROR ){
+ iErrorStop = 330;
+ throw iRc;
+ }
+ std::cout << "Field #4 name is " << FieldName.Str() << std::endl;
+
+ xbString sFriend;
+ if(( iRc = MyTable->GetLogicalField( "FRIEND?", sFriend )) < 0 ){
+ iErrorStop = 340;
+ throw iRc;
+ }
+ std::cout << "Switch value = [" << sFriend.Str() << "]" << std::endl;
+
+ xbInt32 lZip = 0;
+ if(( iRc = MyTable->GetLongField( "ZIPCODE", lZip )) < 0 ){
+ iErrorStop = 350;
+ throw iRc;
+ }
+ std::cout << "Long value = [" << lZip << "]" << std::endl;
+
+ if(( iRc = MyTable->GetFloatField( iFld_AMOUNT2, f )) < 0 ){
+ iErrorStop = 360;
+ throw iRc;
+ }
+ printf( "Field NUMFLD1 %8.2f\n", f );
+
+
+ if(( iRc = MyTable->GetDoubleField( iFld_AMOUNT1, d )) < 0 ){
+ iErrorStop = 370;
+ throw iRc;
+ }
+ printf( "Field NUMFLD2 %8.2f\n", d );
+
+ // Initialize the record buffer in preparation for another record
+ if(( iRc = MyTable->BlankRecord()) != XB_NO_ERROR ){
+ iErrorStop = 380;
+ throw iRc;
+ }
+
+ // Append another record (it will be blank)
+ if(( iRc = MyTable->AppendRecord()) != XB_NO_ERROR ){
+ iErrorStop = 390;
+ throw iRc;
+ };
+
+ // mark current record for deletion
+ if(( iRc = MyTable->DeleteRecord()) != XB_NO_ERROR ){
+ iErrorStop = 400;
+ throw iRc;
+ };
+
+ // save current record
+ if(( iRc = MyTable->PutRecord()) != XB_NO_ERROR ){
+ iErrorStop = 410;
+ throw iRc;
+ }
+
+ if(( iRc = MyTable->Commit()) != XB_NO_ERROR ){
+ iErrorStop = 420;
+ throw iRc;
+ }
+
+ // example code to loop through the table
+ xbUInt32 ulRecCnt;
+ if(( iRc = MyTable->GetRecordCnt( ulRecCnt )) != XB_NO_ERROR ){
+ iErrorStop = 430;
+ throw iRc;
+ }
+
+ for( xbUInt32 ul = 1; ul <= ulRecCnt; ul++ ){
+ if(( iRc = MyTable->GetRecord( ul )) != XB_NO_ERROR ){
+ iErrorStop = 440;
+ throw iRc;
+ }
+ // do something with the record here
+ std::cout << "Tuple = " << MyTable->GetCurRecNo() << std::endl;
+
+ }
+
+ /* Close database and associated indexes */
+ if(( iRc = MyTable->Close()) != XB_NO_ERROR ){
+ iErrorStop = 450;
+ throw iRc;
+ }
+ delete MyTable;
+
+
+ }
+ catch( xbInt16 iRc ){
+ std::cout << "xb_ex_v4_upd_dbf error. Error stop point = [" << iErrorStop << "] iRc = [" << iRc << "]" << std::endl;
+ std::cout << x.GetErrorMessage( iRc ) << std::endl;
+ }
+
+#endif // XB_DBF4_SUPPORT
+ return 0;
+}