Advantage Client Engine
#include <windows.h>
#include "Ace.h"
/*******************************************************************************
* Function : DoAof
* API's Used : AdsSetAOF
* AdsClearAOF
* AdsRefreshAOF
* AdsGetAOF
* AdsGetAOFOptLevel
* AdsEvalAOF
*
* AdsOpenTable
* AdsCloseTable
* AdsCreateIndex
* AdsCloseAllIndexes
* AdsShowError
* AdsGetRecordCount
* AdsGotoTop
*******************************************************************************/
UNSIGNED32 DoAof( void )
{
UNSIGNED32 ulRetVal;
ADSHANDLE hTable1;
ADSHANDLE hIndex1;
UNSIGNED8 aucNonOpt[64];
UNSIGNED8 aucAOF[64];
UNSIGNED16 usOptLevel;
UNSIGNED16 usLength;
UNSIGNED32 ulRecCount0;
UNSIGNED32 ulRecCount1;
UNSIGNED32 ulRecCount2;
UNSIGNED32 ulRecCount3;
UNSIGNED32 ulRecCount4;
UNSIGNED32 ulRecCount5;
UNSIGNED32 aulRecords[10];
UNSIGNED16 bIsInAOF;
/* open the table */
ulRetVal = AdsOpenTable( 0, "X:\\DATA\\DEMO1000.DBF", "TABLE1",
ADS_CDX, ADS_ANSI, ADS_PROPRIETARY_LOCKING,
ADS_CHECKRIGHTS,
ADS_DEFAULT, &hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
/* some kind of error, tell the user what happened */
AdsShowError( "ACE Couldn't open table" );
return ulRetVal;
}
/* Create a simple character index */
ulRetVal = AdsCreateIndex( hTable1, "Index1", "TAG1",
"Lastname", NULL, NULL,
ADS_COMPOUND, &hIndex1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "Create Index failed on table" );
return ulRetVal;
}
/* Check how AOF's are optimized */
ulRetVal = AdsEvalAOF( hTable1,
"LASTNAME < 'Smith' AND LASTNAME >
Jefferson'", &usOptLevel );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsEvalAOF 1 failed on table" );
return ulRetVal;
}
/*
* The index and the expression are both on LASTNAME,
* so it should be fully optimized.
*/
if ( usOptLevel != ADS_OPTIMIZED_FULL )
MessageBox( NULL, "AdsEvalAOF 1 returned wrong result", "DoAof",
MB_OK );
ulRetVal = AdsEvalAOF( hTable1, "LASTNAME < 'Smith' AND FIRSTNAME >
'Mark'", &usOptLevel );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsEvalAOF 2 failed on table" );
return ulRetVal;
}
/* ADS_OPTIMIZED_FULL && ADS_OPTIMIZED_NONE == ADS_OPTIMIZED_PART */
if ( usOptLevel != ADS_OPTIMIZED_PART )
MessageBox( NULL, "AdsEvalAOF 2 returned wrong result", "DoAof",
MB_OK );
ulRetVal = AdsEvalAOF( hTable1, "LASTNAME < 'Smith' OR FIRSTNAME >
'Mark'", &usOptLevel );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsEvalAOF 3 failed on table" );
return ulRetVal;
}
/* ADS_OPTIMIZED_FULL || ADS_OPTIMIZED_NONE == ADS_OPTIMIZED_NONE */
if ( usOptLevel != ADS_OPTIMIZED_NONE )
MessageBox( NULL, "AdsEvalAOF 3 returned wrong result", "DoAof",
MB_OK );
/* Set an Advantage Optimized Filter */
ulRetVal = AdsSetAOF( hTable1, "LASTNAME < 'Smith' AND FIRSTNAME >
'Mark'", ADS_RESOLVE_DYNAMIC );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsSetAOF failed" );
return ulRetVal;
}
/* Save the full Record count for later */
ulRetVal = AdsGetRecordCount( hTable1, ADS_IGNOREFILTERS,
&ulRecCount0 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGetRecordCount 0 failed" );
return ulRetVal;
}
/* You can always find out what AOF is set */
usLength = sizeof(aucAOF);
ulRetVal = AdsGetAOF( hTable1, aucAOF, &usLength );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGetAOF failed" );
return ulRetVal;
}
if ( strcmp( "LASTNAME < 'Smith' AND FIRSTNAME > 'Mark'", aucAOF ) )
MessageBox( NULL, "AdsGetAOF returned wrong string", "DoAof",
MB_OK );
/* Find out what part of our expression is not optimized */
usLength = sizeof(aucNonOpt);
ulRetVal = AdsGetAOFOptLevel( hTable1, &usOptLevel, aucNonOpt,
&usLength );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGetAOFOptLevel failed on table" );
return ulRetVal;
}
if ( usOptLevel != ADS_OPTIMIZED_PART )
MessageBox( NULL, "AdsGetAOFOptLevel returned wrong Level",
"DoAof", MB_OK );
if ( strcmp( "FIRSTNAME>'Mark'", aucNonOpt ) )
MessageBox( NULL, "AdsGetAOFOptLevel returned wrong string",
"DoAof", MB_OK );
/* How many records pass the filter */
ulRetVal = AdsGetRecordCount( hTable1, ADS_RESPECTFILTERS,
&ulRecCount1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGetRecordCount 1 failed" );
return ulRetVal;
}
if ( ulRecCount1 >= ulRecCount0 )
MessageBox( NULL, "AdsGetRecordCount did not decrease.", "DoAof",
MB_OK );
/*
* Remove one record from the optimized portion of the filter
* The record will still pass the filter until the filter is Refreshed
*/
ulRetVal = AdsGotoTop( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoTop failed" );
return ulRetVal;
}
ulRetVal = AdsSetField( hTable1, "LASTNAME", "Smith", 5 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "SetField failed" );
return ulRetVal;
}
/* The same number of records should pass the filter */
ulRetVal = AdsGetRecordCount( hTable1, ADS_RESPECTFILTERS,
&ulRecCount2 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGetRecordCount 2 failed" );
return ulRetVal;
}
if ( ulRecCount1 != ulRecCount2 )
MessageBox( NULL, "AdsGetRecordCount returned a different result",
"DoAof", MB_OK );
/* Refresh the AOF and the record should be removed from the filter */
ulRetVal = AdsRefreshAOF( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsRefreshAOF failed" );
return ulRetVal;
}
ulRetVal = AdsGetRecordCount( hTable1, ADS_RESPECTFILTERS,
&ulRecCount3 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGetRecordCount 3 failed" );
return ulRetVal;
}
if ( ( ulRecCount1 - 1 ) != ulRecCount3 )
MessageBox( NULL, "AdsGetRecordCount 3 is not one less", "DoAof",
MB_OK );
/* Remove one record from the non-optimized portion of the filter
* The record will be removed right away because ADS_RESOLVE_DYNAMIC
* is specified.
*
* If ADS_RESOLVE_IMMEDIATE had been specified, it would not be
* removed until the AOF was refreshed (just like the optimized
* portion).
*
* ADS_RESOLVE_IMMEDIATE will also cause AdsGetRecordCount to be
* faster.
*/
ulRetVal = AdsGotoTop( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoTop failed" );
return ulRetVal;
}
ulRetVal = AdsSetField( hTable1, "FIRSTNAME", "Aaron", 5 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "SetField 2 failed" );
return ulRetVal;
}
/* The record should be removed */
ulRetVal = AdsGetRecordCount( hTable1, ADS_RESPECTFILTERS,
&ulRecCount4 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGetRecordCount 4 failed" );
return ulRetVal;
}
if ( ( ulRecCount3 - 1 ) != ulRecCount4 )
MessageBox( NULL, "AdsGetRecordCount 4 is not one less", "DoAof",
MB_OK );
/* Clear the AOF and the record count should be restored */
ulRetVal = AdsClearAOF( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsClearAOF failed" );
return ulRetVal;
}
ulRetVal = AdsGetRecordCount( hTable1, ADS_RESPECTFILTERS,
&ulRecCount5 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGetRecordCount 5 failed" );
return ulRetVal;
}
if ( ulRecCount5 != ulRecCount0 )
MessageBox( NULL, "AdsGetRecordCount is not restored.", "DoAof",
MB_OK );
/*
* Try out a customized AOF. Start with a completely empty filter and
* add some records to it. Using ".F." as the filter expression creates
* a fully optimized empty filter.
*/
ulRetVal = AdsSetAOF( hTable1, ".F.", ADS_RESOLVE_DYNAMIC );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsSetAOF failed" );
return ulRetVal;
}
/* add 4 records to the AOF */
aulRecords[0] = 25;
aulRecords[1] = 50;
aulRecords[2] = 75;
aulRecords[3] = 100;
ulRetVal = AdsCustomizeAOF( hTable1, 4, /* 4 records in the array */
aulRecords, ADS_AOF_ADD_RECORD );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsCustomizeAOF failed" );
return ulRetVal;
}
/*
* Verify that one of the records is in the AOF bitmap. Note that this
* call results in a server request. The work done on the server is very
* minimal, but the network can be a bottleneck if this function is used
* indiscriminately,
*/
ulRetVal = AdsIsRecordInAOF( hTable1, 25, &bIsInAOF );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsRecordInOAF failed" );
return ulRetVal;
}
if ( !bIsInAOF )
MessageBox( NULL, "Record 25 should have been in the AOF", "DoAof", MB_OK );
/* count the records - should be 4 records only */
ulRetVal = AdsGetRecordCount( hTable1, ADS_RESPECTFILTERS, &ulRecCount0 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGetRecordCount 0 failed" );
return ulRetVal;
}
if ( ulRecCount0 != 4 )
MessageBox( NULL, "Expected to find 4 records in the AOF",
"DoAof", MB_OK );
/* Cleanup */
ulRetVal = AdsCloseAllIndexes( hTable1 );
if ( ulRetVal != AE_SUCCESS )
return ulRetVal;
ulRetVal = AdsCloseTable( hTable1 );
if ( ulRetVal != AE_SUCCESS )
return ulRetVal;
return AE_SUCCESS;
} /* DoAof */
/*******************************************************************************
* Function : DoEncrypt
* API's Used : AdsDecryptRecord
* AdsDecryptTable
* AdsDisableEncryption
* AdsEnableEncryption
* AdsEncrypRecord
* AdsEncryptTable
* AdsIsRecordEncrypted
* AdsIsTableEncrypted
* AdsIsEncryptionEnabled
*
* AdsOpenTable
* AdsCloseTable
* AdsShowError
* AdsGotoRecord
* AdsSetField
* AdsGetField
*******************************************************************************/
UNSIGNED32 DoEncrypt( void )
{
UNSIGNED32 ulRetVal;
ADSHANDLE hTable1;
UNSIGNED8 aucBuffer[64];
UNSIGNED32 ulLength;
UNSIGNED16 usIsEncrypted;
UNSIGNED16 usIsEnabled;
/* open the table */
ulRetVal = AdsOpenTable( 0, "X:\\DATA\\DEMO1000.DBF", "TABLE1", ADS_CDX, ADS_ANSI, ADS_PROPRIETARY_LOCKING, ADS_CHECKRIGHTS, ADS_EXCLUSIVE, &hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
/* some kind of error, tell the user what happened */
AdsShowError( "ACE Couldn't open table" );
return ulRetVal;
}
/* Enable encryption
* Write to record 1; This should be written in encryped form
*/
ulRetVal = AdsEnableEncryption( hTable1, "secret" );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsEnableEncryption 1 failed" );
return ulRetVal;
}
ulRetVal = AdsGotoRecord( hTable1, 1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoRecord( 1 ) failed" );
return ulRetVal;
}
ulRetVal = AdsSetField( hTable1, "LASTNAME", "Smith", 5 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "SetField 1 failed" );
return ulRetVal;
}
/*
* You may encrypt a single record without changing the
* content of the record
*/
ulRetVal = AdsGotoRecord( hTable1, 2 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoRecord( 2 ) failed" );
return ulRetVal;
}
ulRetVal = AdsEncryptRecord( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsEncryptRecord( 2 ) failed" );
}
/* Disable encryption
* Write to record 3; This should be written in plain text.
*/
ulRetVal = AdsGotoRecord( hTable1, 3 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoRecord( 3 ) failed" );
return ulRetVal;
}
ulRetVal = AdsDisableEncryption( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsDisableEncryption failed" );
return ulRetVal;
}
ulRetVal = AdsSetField( hTable1, "LASTNAME", "Smith", 5 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "SetField 3 failed" );
return ulRetVal;
}
/*
* The table should not be encrypted
* Only record 1 and 2 should be encrypted
*/
ulRetVal = AdsIsTableEncrypted( hTable1, &usIsEncrypted );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsTableEncrypted 1 failed" );
return ulRetVal;
}
if ( usIsEncrypted != FALSE )
MessageBox( NULL, "AdsIsTableEncrypted 1 returned wrong result",
"DoEncrypt", MB_OK );
/* Check record 1 */
ulRetVal = AdsGotoRecord( hTable1, 1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoRecord( 1 ) failed" );
return ulRetVal;
}
ulRetVal = AdsIsRecordEncrypted( hTable1, &usIsEncrypted );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsRecordEncrypted 1 failed" );
return ulRetVal;
}
if ( usIsEncrypted == FALSE )
MessageBox( NULL, "AdsIsRecordEncrypted 1 returned wrong result",
"DoEncrypt", MB_OK );
ulRetVal = AdsSetField( hTable1, "LASTNAME", "Wong", 4 );
if ( ulRetVal == AE_SUCCESS )
{
AdsShowError( "SetField 1 on encrypted record should not succeed without enabling encryption" );
return ulRetVal;
}
/* Read field should give us garbage */
ulLength = sizeof( aucBuffer );
ulRetVal = AdsGetField( hTable1, "LASTNAME", aucBuffer, &ulLength, ADS_NONE );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "GetField 1 on encrypted record failed" );
return ulRetVal;
}
if ( strncmp( aucBuffer, "Smith", 5 ) == 0 )
MessageBox( NULL, "Record 1 does not appear to be encrypted",
"DoEncrypt", MB_OK );
/* Check record 2 */
ulRetVal = AdsGotoRecord( hTable1, 2 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoRecord( 2 ) failed" );
return ulRetVal;
}
ulRetVal = AdsIsRecordEncrypted( hTable1, &usIsEncrypted );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsRecordEncrypted 2 failed" );
return ulRetVal;
}
if ( usIsEncrypted == FALSE )
MessageBox( NULL, "AdsIsRecordEncrypted 2 returned wrong result",
"DoEncrypt", MB_OK );
/* Check record 3 */
ulRetVal = AdsGotoRecord( hTable1, 3 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoRecord( 3 ) failed" );
return ulRetVal;
}
ulRetVal = AdsIsRecordEncrypted( hTable1, &usIsEncrypted );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsRecordEncrypted 3 failed" );
return ulRetVal;
}
if ( usIsEncrypted != FALSE )
MessageBox( NULL, "AdsIsRecordEncrypted 3 returned wrong result",
"DoEncrypt", MB_OK );
ulRetVal = AdsEnableEncryption( hTable1, "secret" );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsEnableEncryption 2 failed" );
return ulRetVal;
}
/* You can test the current encryption status */
ulRetVal = AdsIsEncryptionEnabled( hTable1, &usIsEnabled );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsEncryptionEnabled 1 failed" );
return ulRetVal;
}
if ( usIsEnabled == FALSE )
MessageBox( NULL, "AdsIsEncryptionEnabled 1 returned wrong result",
"DoEncrypt", MB_OK );
/* Read field automatically decrypts the record when encryption is enabled */
/* Check record 1 */
ulRetVal = AdsGotoRecord( hTable1, 1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoRecord( 1 ) failed" );
return ulRetVal;
}
ulLength = sizeof( aucBuffer );
ulRetVal = AdsGetField( hTable1, "LASTNAME", aucBuffer, &ulLength, ADS_NONE );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "GetField 1 on encrypted record failed" );
return ulRetVal;
}
if ( strncmp( aucBuffer, "Smith", 5 ) != 0 )
MessageBox( NULL, "Record 1 did not decrypt correcct",
"DoEncrypt", MB_OK );
/* Decrypt a record */
ulRetVal = AdsGotoRecord( hTable1, 2 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsGotoRecord( 2 ) failed" );
return ulRetVal;
}
ulRetVal = AdsDecryptRecord( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsDecryptRecord( 2 ) failed" );
return ulRetVal;
}
ulRetVal = AdsIsRecordEncrypted( hTable1, &usIsEncrypted );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsRecordEncrypted 2 failed" );
return ulRetVal;
}
if ( usIsEncrypted != FALSE )
MessageBox( NULL, "AdsIsRecordEncrypted 2 returned wrong result",
"DoEncrypt", MB_OK );
/* AdsEncryptTable encrypts all non-encrypted records
* You must have encryption enabled to encrypt a table
* Also notice that the table was opened with ADS_EXCLUSIVE
*
*/
ulRetVal = AdsEncryptTable( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsEncryptTable failed" );
return ulRetVal;
}
ulRetVal = AdsDisableEncryption( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsDisableEncryption 2 failed" );
return ulRetVal;
}
/* You can ask ACE if the current table is encrypted */
ulRetVal = AdsIsTableEncrypted( hTable1, &usIsEncrypted );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsTableEncrypted 2 failed" );
return ulRetVal;
}
if ( usIsEncrypted == FALSE )
MessageBox( NULL, "AdsIsTableEncrypted 2 returned wrong result",
"DoEncrypt", MB_OK );
/* Try to use the wrong password */
ulRetVal = AdsEnableEncryption( hTable1, "PassWord" );
if ( ulRetVal == AE_SUCCESS )
{
AdsShowError( "AdsEnableEncryption 4 should failed" );
return ulRetVal;
}
/* You can test the current encryption status */
ulRetVal = AdsIsEncryptionEnabled( hTable1, &usIsEnabled );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsEncryptionEnabled 2 failed" );
return ulRetVal;
}
if ( usIsEnabled != FALSE )
MessageBox( NULL, "AdsIsEncryptionEnabled 2 returned wrong result",
"DoEncrypt", MB_OK );
/* AdsDecryptTable decrypts all encrypted records
* You must have encryption enabled to decrypt a table
*/
ulRetVal = AdsEnableEncryption( hTable1, "secret" );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsEnableEncryption 5 failed" );
return ulRetVal;
}
ulRetVal = AdsDecryptTable( hTable1 );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsDecryptTable failed" );
return ulRetVal;
}
/* After the whole table is decrypted, encryption should be disabled */
ulRetVal = AdsIsEncryptionEnabled( hTable1, &usIsEnabled );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsEncryptionEnabled 3 failed" );
return ulRetVal;
}
if ( usIsEnabled != FALSE )
MessageBox( NULL, "AdsIsEncryptionEnabled 3 returned wrong result",
"DoEncrypt", MB_OK );
/* AdsIsTableEncrypted should return FALSE */
ulRetVal = AdsIsTableEncrypted( hTable1, &usIsEncrypted );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsIsTableEncrypted 3 failed" );
return ulRetVal;
}
if ( usIsEncrypted != FALSE )
MessageBox( NULL, "AdsIsTableEncrypted 3 returned wrong result",
"DoEncrypt", MB_OK );
/* Now it is OK to switch to another password */
ulRetVal = AdsEnableEncryption( hTable1, "PassWord" );
if ( ulRetVal != AE_SUCCESS )
{
AdsShowError( "AdsEnableEncryption 5 failed" );
return ulRetVal;
}
/* Cleanup */
ulRetVal = AdsCloseTable( hTable1 );
if ( ulRetVal != AE_SUCCESS )
return ulRetVal;
return AE_SUCCESS;
} /* DoEncrypt */