PreviousTutorials and Guide to Samples (9.1 revision 1) Next

C/C++

Show this topic in Library frames

This section includes the following information:

C++ Program Example

The following example program, which is included on your distribution media, shows how to perform several of the more common Btrieve operations, and it performs those operations in the order required by the MicroKernel's dependencies (for example, you must open a file before performing I/O to it).

For an example of the Btrieve Login operation, see C++ Program Example of Btrieve Login .

Example 7-1 Btrsamp.c
/********************************************************** 
**  Copyright 2003 Pervasive Software Inc. All Rights Reserved 
** 
************************************************************/ 
/*********************************************************** 
  BTRSAMP.C 
This is a simple sample designed to allow you to confirm your ability 
to compile, link, and execute a Btrieve application for your target 
environment using your compiler tools. 
This program demonstrates the C/C++ interface for Btrieve for MS 
Windows, NetWare NLM, MS Windows NT/2000 and Windows 9X. 
    This program does the following operations on the sample database: 
    - gets the Microkernel Database Engine version 
    - opens sample.btr 
    - gets a record on a known value of Key 0 
    - displays the retrieved record 
    - performs a stat operation 
    - creates an empty `clone' of sample.btr and opens it 
    - performs a `Get Next Extended' operation to extract a subset of 
the records in sample.btr 
    - inserts those records into the cloned file 
    - closes both files 
    IMPORTANT: 
    You must specify the complete path to the directory that contains 
the sample Btrieve data file, `sample.btr'.  See IMPORTANT, below. 
    You can compile and run this program on any of the platforms 
    supported by the interface modules.  Platforms are indicated by the 
platform switches listed in `btrapi.h'.  For MS Windows you should make 
an application that allows standard output via printf().  Note that most 
C/C++ compilers support standard I/O Windows applications. 
    For MS Windows NT, you should make a console application. 
    See the prologue in `btrapi.h' for information on how to select a 
target platform for your application.  You must specify a target 
platform. 
***********************************************************/ 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <btrapi.h> 
#include <btrconst.h> 
/*********************************************************** 
  Constants 
************************************************************/ 
/*********************************************************** 
   IMPORTANT: You should modify the following to specify the 
              complete path to `sample.btr' for your environment. 
***********************************************************/ 
#ifdef BTI_NLM 
#define FILE1_NAME "sys:\\pvsw\\samples\\sample.btr" 
#else 
#define FILE1_NAME "c:\\pvsw\\samples\\sample.btr" 
#endif 
#ifdef BTI_NLM 
#define FILE2_NAME "sys:\\pvsw\\samples\\sample2.btr" 
#else 
#define FILE2_NAME "c:\\pvsw\\samples\\sample2.btr" 
#endif 
#define EXIT_WITH_ERROR     1 
#define TRUE                1 
#define FALSE               0 
#define VERSION_OFFSET      0 
#define REVISION_OFFSET     2 
#define PLATFORM_ID_OFFSET  4 
#define MY_THREAD_ID        50 
/* Don't pad our structures */ 
#if defined(__BORLANDC__) 
  #pragma option -a- 
#else 
  #if defined(_MSC_VER) || defined(__WATCOMC__) 
    #pragma pack(1) 
  #endif 
#endif 
/*********************************************************** 
  Type definitions for Client ID and version Structures 
************************************************************/ 
typedef struct 
{ 
  BTI_CHAR networkAndNode[12]; 
  BTI_CHAR applicationID[2]; 
  BTI_WORD threadID; 
} CLIENT_ID; 
typedef struct 
{ 
  BTI_SINT  Version; 
  BTI_SINT  Revision; 
  BTI_CHAR  MKDEId; 
} VERSION_STRUCT; 
/*********************************************************** 
  Definition of record from `sample.btr' 
************************************************************/ 
typedef struct 
{ 
  BTI_LONG  ID; 
  BTI_CHAR  FirstName[16]; 
  BTI_CHAR  LastName[26]; 
  BTI_CHAR  Street[31]; 
  BTI_CHAR  City[31]; 
  BTI_CHAR  State[3]; 
  BTI_CHAR  Zip[11]; 
  BTI_CHAR  Country[21]; 
  BTI_CHAR  Phone[14]; 
} PERSON_STRUCT; 
/*********************************************************** 
  Type definitions for Stat/Create structure 
************************************************************/ 
typedef struct 
{ 
  BTI_SINT recLength; 
  BTI_SINT pageSize; 
  BTI_SINT indexCount; 
  BTI_CHAR reserved[4]; 
  BTI_SINT flags; 
  BTI_BYTE dupPointers; 
  BTI_BYTE notUsed; 
  BTI_SINT allocations; 
} FILE_SPECS; 
typedef struct 
{ 
  BTI_SINT position; 
  BTI_SINT length; 
  BTI_SINT flags; 
  BTI_CHAR reserved[4]; 
  BTI_CHAR type; 
  BTI_CHAR null; 
  BTI_CHAR notUsed[2]; 
  BTI_BYTE manualKeyNumber; 
  BTI_BYTE acsNumber; 
} KEY_SPECS; 
typedef struct 
{ 
  FILE_SPECS fileSpecs; 
  KEY_SPECS  keySpecs[5]; 
} FILE_CREATE_BUF; 
/*********************************************************** 
  Structure type definitions for Get Next Extended operation 
************************************************************/ 
typedef struct 
{ 
  BTI_SINT    descriptionLen; 
  BTI_CHAR    currencyConst[2]; 
  BTI_SINT    rejectCount; 
  BTI_SINT    numberTerms; 
} GNE_HEADER; 
typedef struct 
{ 
  BTI_CHAR    fieldType; 
  BTI_SINT    fieldLen; 
  BTI_SINT    fieldOffset; 
  BTI_CHAR    comparisonCode; 
  BTI_CHAR    connector; 
  BTI_CHAR value[3]; 
} TERM_HEADER; 
typedef struct 
{ 
  BTI_SINT    maxRecsToRetrieve; 
  BTI_SINT    noFieldsToRetrieve; 
} RETRIEVAL_HEADER; 
typedef struct 
{ 
  BTI_SINT    fieldLen; 
  BTI_SINT    fieldOffset; 
} FIELD_RETRIEVAL_HEADER; 
typedef struct 
{ 
  GNE_HEADER              gneHeader; 
  TERM_HEADER             term1; 
  TERM_HEADER             term2; 
  RETRIEVAL_HEADER        retrieval; 
  FIELD_RETRIEVAL_HEADER  recordRet; 
} PRE_GNE_BUFFER; 
typedef struct 
{ 
  BTI_SINT      recLen; 
  BTI_LONG      recPos; 
  PERSON_STRUCT personRecord; 
} RETURNED_REC; 
typedef struct 
{ 
  BTI_SINT      numReturned; 
  RETURNED_REC  recs[20]; 
} POST_GNE_BUFFER; 
typedef union 
{ 
  PRE_GNE_BUFFER  preBuf; 
  POST_GNE_BUFFER postBuf; 
} GNE_BUFFER, BTI_FAR* GNE_BUFFER_PTR; 
/* restore structure packing */ 
#if defined(__BORLANDC__) 
  #pragma option -a. 
#else 
  #if defined(_MSC_VER) || defined(__WATCOMC__) 
    #pragma pack() 
  #endif 
#endif 
/*********************************************************** 
  Main 
***********************************************************/ 
int main(void) 
{ 
  /* Btrieve function parameters */ 
  BTI_BYTE posBlock1[128]; 
  BTI_BYTE posBlock2[128]; 
  BTI_BYTE dataBuf[255]; 
  BTI_WORD dataLen; 
  BTI_BYTE keyBuf1[255]; 
  BTI_BYTE keyBuf2[255]; 
  BTI_WORD keyNum = 0; 
  BTI_BYTE btrieveLoaded = FALSE; 
  BTI_LONG personID; 
  BTI_BYTE file1Open = FALSE; 
  BTI_BYTE file2Open = FALSE; 
  BTI_SINT status; 
  BTI_SINT getStatus = -1; 
  BTI_SINT i; 
  BTI_SINT posCtr; 
  CLIENT_ID       clientID; 
  VERSION_STRUCT  versionBuffer[3]; 
  FILE_CREATE_BUF fileCreateBuf; 
  GNE_BUFFER_PTR  gneBuffer; 
  PERSON_STRUCT   personRecord; 
  printf("**************** Btrieve C/C++ Interface Demo 
****************\n\n"); 
  /* set up the Client ID */ 
  memset(clientID.networkAndNode, 0, sizeof(clientID.networkAndNode)); 
  memcpy(clientID.applicationID, "MT", 2);  /* must be greater than "AA" 
*/ 
  clientID.threadID = MY_THREAD_ID; 
  memset(versionBuffer, 0, sizeof(versionBuffer)); 
  dataLen = sizeof(versionBuffer); 
  status = BTRVID( 
              B_VERSION, 
              posBlock1, 
              &versionBuffer, 
              &dataLen, 
              keyBuf1, 
              keyNum, 
              (BTI_BUFFER_PTR)&clientID); 
  if (status == B_NO_ERROR) 
  { 
    printf("Btrieve Versions returned are: \n"); 
    for (i = 0; i < 3; i++) { 
      if (versionBuffer[i].Version != 0) 
      { 
        printf("   %d.%d %c\n", versionBuffer[i].Version, 
                versionBuffer[i].Revision, 
                versionBuffer[i].MKDEId); 
      } 
    } 
    printf("\n"); 
    btrieveLoaded = TRUE; 
  } 
  else 
  { 
    printf("Btrieve B_VERSION status = %d\n", status); 
    if (status != B_RECORD_MANAGER_INACTIVE) 
    { 
      btrieveLoaded = TRUE; 
    } 
  } 
  /* clear buffers */ 
  if (status == B_NO_ERROR) 
  { 
    memset(dataBuf, 0, sizeof(dataBuf)); 
    memset(keyBuf1, 0, sizeof(keyBuf1)); 
    memset(keyBuf2, 0, sizeof(keyBuf2)); 
  } 
  /* open sample.btr */ 
  if (status == B_NO_ERROR) 
  { 
    strcpy((BTI_CHAR *)keyBuf1, FILE1_NAME); 
    strcpy((BTI_CHAR *)keyBuf2, FILE2_NAME); 
    keyNum  = 0; 
    dataLen = 0; 
    status = BTRVID( 
                B_OPEN, 
                posBlock1, 
                dataBuf, 
                &dataLen, 
                keyBuf1, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_OPEN status (sample.btr) = %d\n", status); 
    if (status == B_NO_ERROR) 
    { 
      file1Open = TRUE; 
    } 
  } 
  /* get the record with key 0 = 263512477 using B_GET_EQUAL */ 
  if (status == B_NO_ERROR) 
  { 
    memset(&personRecord, 0, sizeof(personRecord)); 
    dataLen = sizeof(personRecord); 
    personID = 263512477;    /* this is really a social security number */ 
    *(BTI_LONG BTI_FAR *)&keyBuf1[0] = personID; 
    keyNum = 0; 
    status = BTRVID( 
                B_GET_EQUAL, 
                posBlock1, 
                &personRecord, 
                &dataLen, 
                keyBuf1, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_GET_EQUAL status = %d\n", status); 
    if (status == B_NO_ERROR) 
    { 
      printf("\n"); 
      printf("The retrieved record is:\n"); 
      printf("ID:      %ld\n", personRecord.ID); 
      printf("Name:    %s %s\n", personRecord.FirstName, 
                                 personRecord.LastName); 
      printf("Street:  %s\n", personRecord.Street); 
      printf("City:    %s\n", personRecord.City); 
      printf("State:   %s\n", personRecord.State); 
      printf("Zip:     %s\n", personRecord.Zip); 
      printf("Country: %s\n", personRecord.Country); 
      printf("Phone:   %s\n", personRecord.Phone); 
      printf("\n"); 
    } 
  } 
  /* perform a stat operation to populate the create buffer */ 
  memset(&fileCreateBuf, 0, sizeof(fileCreateBuf)); 
  dataLen = sizeof(fileCreateBuf); 
  keyNum = (BTI_WORD)-1; 
  status = BTRVID(B_STAT, 
                posBlock1, 
                &fileCreateBuf, 
                &dataLen, 
                keyBuf1, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
  if (status == B_NO_ERROR) 
  { 
    /* create and open sample2.btr */ 
    keyNum = 0; 
    dataLen = sizeof(fileCreateBuf); 
    status = BTRVID(B_CREATE, 
                  posBlock2, 
                  &fileCreateBuf, 
                  &dataLen, 
                  keyBuf2, 
                  keyNum, 
                  (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_CREATE status = %d\n", status); 
  } 
  if (status == B_NO_ERROR) 
  { 
    keyNum = 0; 
    dataLen = 0; 
    status = BTRVID( 
                B_OPEN, 
                posBlock2, 
                dataBuf, 
                &dataLen, 
                keyBuf2, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_OPEN status (sample2.btr) = %d\n", status); 
    if (status == B_NO_ERROR) 
    { 
      file2Open = TRUE; 
    } 
  } 
  /* now extract data from the original file, insert into new one */ 
  if (status == B_NO_ERROR) 
  { 
    /* getFirst to establish currency */ 
    keyNum = 2; /* STATE-CITY index */ 
    memset(&personRecord, 0, sizeof(personRecord)); 
    memset(&keyBuf2[0], 0, sizeof(keyBuf2)); 
    dataLen = sizeof(personRecord); 
    getStatus = BTRVID( 
                   B_GET_FIRST, 
                   posBlock1, 
                   &personRecord, 
                   &dataLen, 
                   keyBuf1, 
                   keyNum, 
                   (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_GET_FIRST status (sample.btr) = %d\n\n", 
getStatus); 
  } 
  gneBuffer = malloc(sizeof(GNE_BUFFER)); 
  if (gneBuffer == NULL) 
  { 
     printf("Insufficient memory to allocate buffer"); 
    return(EXIT_WITH_ERROR); 
  } 
  memset(gneBuffer, 0, sizeof(GNE_BUFFER)); 
  memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0], "UC", 2); 
  while (getStatus == B_NO_ERROR) 
  { 
    gneBuffer->preBuf.gneHeader.rejectCount = 0; 
    gneBuffer->preBuf.gneHeader.numberTerms = 2; 
    posCtr = sizeof(GNE_HEADER); 
    /* fill in the first condition */ 
    gneBuffer->preBuf.term1.fieldType = 11; 
    gneBuffer->preBuf.term1.fieldLen = 3; 
    gneBuffer->preBuf.term1.fieldOffset = 108; 
    gneBuffer->preBuf.term1.comparisonCode = 1; 
    gneBuffer->preBuf.term1.connector = 2; 
    memcpy(&gneBuffer->preBuf.term1.value[0], "TX", 2); 
    posCtr += sizeof(TERM_HEADER); 
    /* fill in the second condition */ 
    gneBuffer->preBuf.term2.fieldType = 11; 
    gneBuffer->preBuf.term2.fieldLen = 3; 
    gneBuffer->preBuf.term2.fieldOffset = 108; 
    gneBuffer->preBuf.term2.comparisonCode = 1; 
    gneBuffer->preBuf.term2.connector = 0; 
    memcpy(&gneBuffer->preBuf.term2.value[0], "CA", 2); 
    posCtr += sizeof(TERM_HEADER); 
    /* fill in the projection header to retrieve whole record */ 
    gneBuffer->preBuf.retrieval.maxRecsToRetrieve = 20; 
    gneBuffer->preBuf.retrieval.noFieldsToRetrieve = 1; 
    posCtr += sizeof(RETRIEVAL_HEADER); 
    gneBuffer->preBuf.recordRet.fieldLen = sizeof(PERSON_STRUCT); 
    gneBuffer->preBuf.recordRet.fieldOffset = 0; 
    posCtr += sizeof(FIELD_RETRIEVAL_HEADER); 
    gneBuffer->preBuf.gneHeader.descriptionLen = posCtr; 
    dataLen = sizeof(GNE_BUFFER); 
    getStatus = BTRVID( 
                   B_GET_NEXT_EXTENDED, 
                   posBlock1, 
                   gneBuffer, 
                   &dataLen, 
                   keyBuf1, 
                   keyNum, 
                   (BTI_BUFFER_PTR)&clientID); 
     printf("Btrieve B_GET_NEXT_EXTENDED status = %d\n", getStatus); 
    /* Get Next Extended can reach end of file and still return some 
records */ 
    if ((getStatus == B_NO_ERROR) || (getStatus == B_END_OF_FILE)) 
    { 
      printf("GetNextExtended returned %d records.\n", gneBuffer-
>postBuf.numReturned); 
      for (i = 0; i < gneBuffer->postBuf.numReturned; i++) 
      { 
        dataLen = sizeof(PERSON_STRUCT); 
        memcpy(dataBuf, &gneBuffer->postBuf.recs[i].personRecord, 
dataLen); 
        status = BTRVID( 
                    B_INSERT, 
                    posBlock2, 
                    dataBuf, 
                    &dataLen, 
                    keyBuf2, 
                    -1,   /* no currency change */ 
                    (BTI_BUFFER_PTR)&clientID); 
      } 
      printf("Inserted %d records in new file, status = %d\n\n", 
gneBuffer->postBuf.numReturned, status); 
    } 
    memset(gneBuffer, 0, sizeof(GNE_BUFFER)); 
    memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0], "EG", 2); 
  } 
  free(gneBuffer); 
  gneBuffer = NULL; 
  /* close open files */ 
  if (file1Open) 
  { 
    dataLen = 0; 
    status = BTRVID( 
                B_CLOSE, 
                posBlock1, 
                dataBuf, 
                &dataLen, 
                keyBuf1, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
  printf("Btrieve B_CLOSE status (sample.btr) = %d\n", status); 
  } 
  if (file2Open) 
  { 
    dataLen = 0; 
    status = BTRVID( 
                B_CLOSE, 
                posBlock2, 
                dataBuf, 
                &dataLen, 
                keyBuf2, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_CLOSE status (sample2.btr) = %d\n", status); 
  } 
  return(status); 
} 

C++ Program Example of Btrieve Login

The following example program, which is included on your distribution media as loginapi.c, shows how to perform the Btrieve login operation in the context of other operations, and it performs those operations in the order required by the MicroKernel's dependencies (for example, you must open a file before performing I/O to it).

For an example of other Btrieve operations, see C++ Program Example .

/********************************************************************* 
** 
**  Copyright 1982-2003 Pervasive Software Inc. All Rights Reserved 
** 
*********************************************************************/ 
/********************************************************************* 
  LOGINAPI.C 
    This is a simple sample designed to allow you to confirm your 
    ability to compile, link, and execute a Btrieve application for 
    your target environment using your compiler tools. 
This program demonstrates how to use new Btrieve login API with secured	
database. Login API available with Pervasive.SQL 8.50. To run a program 
	DefaultDb database should be secured and security mode set to 
database	authentication and authorization. Use PCC to set that up.  
This program does the following operations on the DefaultDb database: 
  - Logs in to DefaultDb database using Btrieve operation B_LOGIN (78) 
  - opens sample.btr 
  - gets a record on a known value of Key 0 
  - displays the retrieved record 
  - closes sample.btr 
  - logs out from DefaultDB database 
Second part demonstrates how to use URI in Btrieve Open call. 
  - opens sample.btr using URI string in a key buffer.  
  - gets a record on a known value of Key 0 
  - displays the retrieved record 
  - closes sample.btr 
    IMPORTANT: 
    You must specify the complete path to the directory that contains 
    the sample Btrieve data file, 'sample.btr'.  See IMPORTANT, below. 
    You can compile and run this program on any of the platforms 
    supported by the interface modules.  Platforms are indicated by the 
    platform switches listed in 'btrapi.h'.  For MS Windows you should 
    make an application that allows standard output via printf().  Note 
    that most C/C++ compilers support standard I/O Windows applications. 
    For MS Windows NT or OS2, you should make a console application. 
    See the prologue in 'btrapi.h' for information on how to select 
    a target platform for your application.  You must specify a target 
    platform. 
*********************************************************************/ 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <btrapi.h> 
#include <btrconst.h> 
/********************************************************************* 
  Constants 
*********************************************************************/ 
/******************************************************************** 
   IMPORTANT: You should modify the following to specify the 
              complete path to 'sample.btr' for your environment. 
********************************************************************/ 
#ifdef BTI_LINUX 
#define FILE_NAME "/usr/local/psql/data/samples/sample.btr" 
#else 
#ifdef BTI_NLM 
#define FILE_NAME "sys:\\pvsw\\samples\\sample.btr" 
#else 
#define FILE_NAME "c:\\pvsw\\samples\\sample.btr" 
#endif 
#endif 
#define EXIT_WITH_ERROR     1 
#define TRUE                1 
#define FALSE               0 
#define MY_THREAD_ID        50 
/* Don't pad our structures */ 
#if defined(__BORLANDC__) 
  #pragma option -a- 
#else 
  #if defined(_MSC_VER) || defined(__WATCOMC__) 
    #pragma pack(1) 
  #endif 
#endif 
/********************************************************************* 
  Type definitions for Client ID and version Structures 
*********************************************************************/ 
typedef struct 
{ 
  BTI_CHAR networkAndNode[12]; 
  BTI_CHAR applicationID[2]; 
  BTI_WORD threadID; 
} CLIENT_ID; 
typedef struct 
{ 
  BTI_SINT  Version; 
  BTI_SINT  Revision; 
  BTI_CHAR  MKDEId; 
} VERSION_STRUCT; 
/********************************************************************* 
  Definition of record from 'sample.btr' 
*********************************************************************/ 
typedef struct 
{ 
  BTI_LONG  ID; 
  BTI_CHAR  FirstName[16]; 
  BTI_CHAR  LastName[26]; 
  BTI_CHAR  Street[31]; 
  BTI_CHAR  City[31]; 
  BTI_CHAR  State[3]; 
  BTI_CHAR  Zip[11]; 
  BTI_CHAR  Country[21]; 
  BTI_CHAR  Phone[14]; 
} PERSON_STRUCT; 
/* restore structure packing */ 
#if defined(__BORLANDC__) 
  #pragma option -a. 
#else 
  #if defined(_MSC_VER) || defined(__WATCOMC__) 
    #pragma pack() 
  #endif 
#endif 
/********************************************************************* 
  Main 
*********************************************************************/ 
int main(void) 
{ 
  /* Btrieve function parameters */ 
  BTI_BYTE posBlock[128]; 
  BTI_BYTE dataBuf[255]; 
  BTI_WORD dataLen; 
  BTI_BYTE keyBuf[255]; 
  BTI_WORD keyNum = 0; 
  BTI_LONG personID; 
  BTI_BYTE fileOpen = FALSE; 
  BTI_SINT status = 0; 
  CLIENT_ID       clientID; 
  PERSON_STRUCT   personRecord; 
   
  /* define URI string to open sample.btr file in DefaultDb database*/ 
  /* SQL security is set for DefaultDb with User name "Master" and 
passord "master" */ 
  BTI_CHAR *URI_STRING1 = "btrv://Master@localhost/
defaultdb?pwd=master"; 
  BTI_CHAR *URI_STRING2 = "btrv://Master@localhost/defaultdb?file=/usr/
local/psql/data/samples/sample.btr&pwd=master"; 
  printf("****** Btrieve C/C++ Interface Demo for Login API *****\n\n"); 
  /* set up the Client ID */ 
  memset(clientID.networkAndNode, 0, sizeof(clientID.networkAndNode)); 
  memcpy(clientID.applicationID, "MT", 2);  /* must be > than "AA" */ 
  clientID.threadID = MY_THREAD_ID; 
  /* Login to secure database */ 
  memset(dataBuf, 0, sizeof(dataBuf)); 
  strcpy(keyBuf, URI_STRING1); 
  keyNum = 0; 
  status = BTRVID( 
                B_LOGIN, 
                posBlock, 
                dataBuf, 
                &dataLen, 
                keyBuf, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID);   
   printf("Btrieve B_LOGIN status = %d\n", status); 
   
  /* clear buffers */ 
    memset(dataBuf, 0, sizeof(dataBuf)); 
    memset(keyBuf , 0, sizeof(keyBuf)); 
  /* open sample.btr */ 
    strcpy((BTI_CHAR *)keyBuf, FILE_NAME); 
    keyNum  = 0; 
    dataLen = 0; 
    status = BTRVID( 
                B_OPEN, 
                posBlock, 
                dataBuf, 
                &dataLen, 
                keyBuf, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_OPEN status (sample.btr) = %d\n", status); 
    if (status == B_NO_ERROR) 
    { 
      fileOpen = TRUE; 
    } 
  /* get the record with key 0 = 263512477 using B_GET_EQUAL */ 
  if (status == B_NO_ERROR) 
  { 
    memset(&personRecord, 0, sizeof(personRecord)); 
    dataLen = sizeof(personRecord); 
    personID = 263512477;    /* this is really a social security number */ 
    *(BTI_LONG BTI_FAR *)&keyBuf[0] = personID; 
    keyNum = 0; 
    status = BTRVID( 
                B_GET_EQUAL, 
                posBlock, 
                &personRecord, 
                &dataLen, 
                keyBuf, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_GET_EQUAL status = %d\n", status); 
    if (status == B_NO_ERROR) 
    { 
      printf("\n"); 
      printf("The retrieved record is:\n"); 
      printf("ID:      %ld\n", personRecord.ID); 
      printf("Name:    %s %s\n", personRecord.FirstName, 
                                 personRecord.LastName); 
      printf("Street:  %s\n", personRecord.Street); 
      printf("City:    %s\n", personRecord.City); 
      printf("State:   %s\n", personRecord.State); 
      printf("Zip:     %s\n", personRecord.Zip); 
      printf("Country: %s\n", personRecord.Country); 
      printf("Phone:   %s\n", personRecord.Phone); 
      printf("\n"); 
    } 
  } 
  /* close open files */ 
  if (fileOpen) 
  { 
    dataLen = 0; 
    status = BTRVID( 
                B_CLOSE, 
                posBlock, 
                dataBuf, 
                &dataLen, 
                keyBuf, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_CLOSE status (sample.btr) = %d\n", status); 
  } 
  /* Logout from secure database */ 
   
  memset(dataBuf, 0, sizeof(dataBuf)); 
  strcpy(keyBuf, URI_STRING1); 
  keyNum = 1; 
  status = BTRVID( 
                B_LOGIN, 
                posBlock, 
                dataBuf, 
                &dataLen, 
                keyBuf, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    
   
  printf("Btrieve logout status = %d\n", status); 
  printf("\n\n"); 
   
   
  /* Following example uses URI string in Btrieve Open call */ 
  
printf("*** This example uses URI string in Btrieve Open call ***\n\n"); 
  /* set up the Client ID */ 
  memset(clientID.networkAndNode, 0, sizeof(clientID.networkAndNode)); 
  memcpy(clientID.applicationID, "MT", 2);  /* must be > than "AA" */ 
  clientID.threadID = MY_THREAD_ID; 
   
  /* clear buffers */ 
    memset(dataBuf, 0, sizeof(dataBuf)); 
    memset(keyBuf , 0, sizeof(keyBuf)); 
  /* open sample.btr */ 
    strcpy((BTI_CHAR *)keyBuf, URI_STRING2); 
    keyNum  = 0; 
    dataLen = 0; 
    status = BTRVID( 
                B_OPEN, 
                posBlock, 
                dataBuf, 
                &dataLen, 
                keyBuf, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_OPEN status (sample.btr) = %d\n", status); 
    if (status == B_NO_ERROR) 
    { 
      fileOpen = TRUE; 
    } 
  /* get the record with key 0 = 263512477 using B_GET_EQUAL */ 
  if (status == B_NO_ERROR) 
  { 
    memset(&personRecord, 0, sizeof(personRecord)); 
    dataLen = sizeof(personRecord); 
    personID = 263512477;    /* this is really a social security number */ 
    *(BTI_LONG BTI_FAR *)&keyBuf[0] = personID; 
    keyNum = 0; 
    status = BTRVID( 
                B_GET_EQUAL, 
                posBlock, 
                &personRecord, 
                &dataLen, 
                keyBuf, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_GET_EQUAL status = %d\n", status); 
    if (status == B_NO_ERROR) 
    { 
      printf("\n"); 
      printf("The retrieved record is:\n"); 
      printf("ID:      %ld\n", personRecord.ID); 
      printf("Name:    %s %s\n", personRecord.FirstName, 
                                 personRecord.LastName); 
      printf("Street:  %s\n", personRecord.Street); 
      printf("City:    %s\n", personRecord.City); 
      printf("State:   %s\n", personRecord.State); 
      printf("Zip:     %s\n", personRecord.Zip); 
      printf("Country: %s\n", personRecord.Country); 
      printf("Phone:   %s\n", personRecord.Phone); 
      printf("\n"); 
    } 
  } 
  /* close open files */ 
  if (fileOpen) 
  { 
    dataLen = 0; 
    status = BTRVID( 
                B_CLOSE, 
                posBlock, 
                dataBuf, 
                &dataLen, 
                keyBuf, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    printf("Btrieve B_CLOSE status (sample.btr) = %d\n", status); 
  } 
  return(status); 
} 

Compiling, Linking, and Running the Program Example

The C Interface for Btrieve is platform-independent and compiler-independent. In general for your compiler, you must do the following:

This section provides instructions for some common development environments. If your development environment is not discussed, you can adapt these instructions.

In Microsoft Visual C++, to compile, link, and run the program example:

  1. In the Developer Studio programming environment, choose New from the File menu.
  2. In the New dialog, on the Projects tab, do the following:
    1. Set the type to Console Application. (BtrSamp runs from a DOS prompt.)
    2. Set the Name to BtrSamp.
    3. Set the location to the \Intf\C directory.
    4. Click OK.
    5. Developer Studio creates a new project called BtrSamp.

  3. In the FileView tab of the workspace, right click on the BtrSamp project, choose the Add Files to Project command, and add the following files:
    • \Intf\C\BtrApi.c
    • \Intf\C\BtrSamp.c
    • \Intf\ImpLib\Win32\W3Btrv7.lib
    • Click OK.
  4. In the BtrSamp.c file, edit the paths to the Sample.btr and Sample2.btr files as appropriate.
  5. Choose Settings from the Project menu. On the C++ tab, do the following:
    • In the Preprocessor category, add BTI_WIN_32 in the Preprocessor Definitions box and add the current directory (.) in the Additional Include Directories box.
    • In the Code Generation category, set the Structure Member Alignment to 1 Byte.
    • Click OK.
  6. Choose Rebuild All from the Build menu.
  7. Microsoft Visual C++ builds the program example and places BtrSamp.exe in your project file directory.

  8. In a DOS prompt window, run BtrSamp.exe.

In Watcom C++, to compile, link, and run the program example:

  1. In the IDE programming environment, choose New Project from the File menu.
  2. In the Enter Project Filename dialog, set the File Name to BtrSamp.wpj and click OK.
  3. In the New Target dialog, do the following:
    • Set the Target Name to BtrSamp.
    • Set the Target Environment to Win32.
    • Set the Image Type to Executable [.exe].
    • Click OK.
  4. Choose New Source from the Sources menu and add the following files:
    • \Intf\C\BtrApi.c
    • \Intf\C\BtrSamp.c
    • \Intf\ImpLib\Win32x\W3Btrv7.lib
    • Click OK.
  5. In the BtrSamp.c file, edit the paths to the Sample.btr and Sample2.btr files as appropriate.
  6. Choose C Compiler Switches from the Source Options submenu on the Sources menu and do the following:
    • In the File Option Switches dialog, add the current directory to the Include directories box, as in the following example:
    • $(%watcom)\h;$(%watcom)\h\nt;. 
      
    • In the Source Switches dialog, add BTI_WIN_32 to the Macro Definitions box and set the Structure Alignment to Pack structures.
    • Click OK.
  7. Choose the Make All Targets button from the toolbar.
  8. WATCOM C++ builds the program example and places BtrSamp.exe in your project file directory.

  9. In a DOS prompt window, run BtrSamp.exe.

In Borland C++, to compile, link, and run the program example:

  1. In the Borland C++ programming environment, choose New Project from the Project menu.
  2. In the New Target dialog:
    • Set the Project Path and Name to \Intf\C\BtrSamp.
    • Set the Target Name to BtrSamp.
    • Set the Target Type to Application [.exe].
    • Set the Target Model to Console.
    • Turn off the Class Library checkbox in the Frameworks group.
    • Click the Advanced button and specify .C node in the Initial Nodes group and turn off the .rc and .def check boxes.
    • Click OK.
  3. In the Project window, right click on the BtrSamp project, choose Add Node, and add the following files:
    • \Intf\C\BtrApi.c
    • \Intf\C\BtrSamp.c
    • \Intf\ImpLib\Win32x\W3Btrv7.lib
    • Click OK.
  4. In the BtrSamp.c file, edit the paths to the Sample.btr and Sample2.btr files as appropriate.
  5. Choose Project from the Options menu and do the following:
    • Select the Directories topic and add the current directory to the Include list in the Source Directories group, as in the following example:
    • c:\bc5\include;. 
      
    • Select the Defines topic under Compiler and add BTI_WIN_32 to the Defines box.
    • Select the Processor topic under 32-bit Compiler and set the Data Alignment to Byte.
    • Click OK.
  6. Choose Build All from the Project menu.
  7. Borland C++ builds the program example and places BtrSamp.exe in your project file directory.

  8. In a DOS prompt window, run BtrSamp.exe.

Compiling C++ Builder Applications

In C++ Builder, to compile, link, and run the program example:

  1. Choose Open Project from the File menu and select the CBBtrv.mak file.
  2. Choose Options from the Project menu, select the Directories/Conditionals tab, and do the following:
    • Add the \Intf\C directory to the Include Path.
    • Add the \Intf\Implib\Win32x directory to the Library Path.
  3. Choose Make from the Project menu.
  4. C++ Builder builds the program example and places CBBtrv.exe in your project file directory.

  5. Choose Run from the Run menu.
  6. In the Btrieve Sample Application window, click the Run Test button.

The following example C++ Builder program shows how to perform several of the more common Btrieve operations, and it performs those operations in the order required by the MicroKernel's dependencies (for example, you must open a file before performing I/O to it).

Example 7-2 CBBMain.cpp
/********************************************************** 
** 
** Copyright 2003 Pervasive Software Inc.  
** All Rights Reserved 
***********************************************************/ 
/*********************************************************** 
  CBBMain.cpp 
 This is a simple sample designed to allow you to confirm your 
 ability to compile, link, and execute a Btrieve application  
 for your target environment using your compiler tools. 
 This program demonstrates the C/C++ interface for Btrieve for  
 MS Windows NT and Windows 9X/ME with Borland's C++ Builder. 
 This program does the following operations on the sample  
database: 
 - gets the Microkernel Database Engine version 
 - opens sample.btr 
 - gets a record on a known value of Key 0 
 - displays the retrieved record 
 - performs a stat operation 
 - creates an empty `clone' of sample.btr and opens it 
 - performs a `Get Next Extended' operation to extract a subset 
         `of the records in sample.btr 
 - inserts those records into the cloned file 
 - closes both files 
 To compile this sample, you must make the following files from  
 the Btrieve "C" interface directory available to the IDE: 
    - btrapi.c 
    - btrapi.h 
    - btrconst.h 
IMPORTANT: 
You must specify the complete path to the directory that  
contains the sample Btrieve data file, `sample.btr'.  See  
IMPORTANT, below. 
***********************************************************/ 
//---------------------------------------------------------- 
#include <vcl\vcl.h> 
#pragma hdrstop 
#include "CBBMain.h" 
#include <btrapi.h> 
#include <btrconst.h> 
//---------------------------------------------------------- 
#pragma resource "*.dfm" 
/*********************************************************** 
  Constants 
***********************************************************/ 
#define EXIT_WITH_ERROR     1 
#define TRUE                1 
#define FALSE               0 
#define VERSION_OFFSET      0 
#define REVISION_OFFSET     2 
#define PLATFORM_ID_OFFSET  4 
#define MY_THREAD_ID        50 
/* Don't pad our structures */ 
/* Borland's help says this is the default. Don't believe it.*/ 
#pragma option -a1 
/*********************************************************** 
  Type definitions for Client ID and version Structures 
***********************************************************/ 
typedef struct 
{ 
  BTI_CHAR networkAndNode[12]; 
  BTI_CHAR applicationID[2]; 
  BTI_WORD threadID; 
} CLIENT_ID; 
typedef struct 
{ 
  BTI_SINT  Version; 
  BTI_SINT  Revision; 
  BTI_CHAR  MKDEId; 
} VERSION_STRUCT; 
/*********************************************************** 
  Definition of record from `sample.btr' 
***********************************************************/ 
typedef struct 
{ 
  BTI_LONG  ID; 
  BTI_CHAR  FirstName[16]; 
  BTI_CHAR  LastName[26]; 
  BTI_CHAR  Street[31]; 
  BTI_CHAR  City[31]; 
  BTI_CHAR  State[3]; 
  BTI_CHAR  Zip[11]; 
  BTI_CHAR  Country[21]; 
  BTI_CHAR  Phone[14]; 
} PERSON_STRUCT; 
/*********************************************************** 
  Type definitions for Stat/Create structure 
***********************************************************/ 
typedef struct 
{ 
  BTI_SINT recLength; 
  BTI_SINT pageSize; 
  BTI_SINT indexCount; 
  BTI_CHAR reserved[4]; 
  BTI_SINT flags; 
  BTI_BYTE dupPointers; 
  BTI_BYTE notUsed; 
  BTI_SINT allocations; 
} FILE_SPECS; 
typedef struct 
{ 
  BTI_SINT position; 
  BTI_SINT length; 
  BTI_SINT flags; 
  BTI_CHAR reserved[4]; 
  BTI_CHAR type; 
  BTI_CHAR null; 
  BTI_CHAR notUsed[2]; 
  BTI_BYTE manualKeyNumber; 
  BTI_BYTE acsNumber; 
} KEY_SPECS; 
typedef struct 
{ 
  FILE_SPECS fileSpecs; 
  KEY_SPECS  keySpecs[5]; 
} FILE_CREATE_BUF; 
/*********************************************************** 
  Structure type definitions for Get Next Extended operation 
***********************************************************/ 
typedef struct 
{ 
  BTI_SINT    descriptionLen; 
  BTI_CHAR    currencyConst[2]; 
  BTI_SINT    rejectCount; 
  BTI_SINT    numberTerms; 
} GNE_HEADER; 
typedef struct 
{ 
  BTI_CHAR    fieldType; 
  BTI_SINT    fieldLen; 
  BTI_SINT    fieldOffset; 
  BTI_CHAR    comparisonCode; 
  BTI_CHAR    connector; 
  BTI_CHAR value[3]; 
} TERM_HEADER; 
typedef struct 
{ 
  BTI_SINT    maxRecsToRetrieve; 
  BTI_SINT    noFieldsToRetrieve; 
} RETRIEVAL_HEADER; 
typedef struct 
{ 
  BTI_SINT    fieldLen; 
  BTI_SINT    fieldOffset; 
} FIELD_RETRIEVAL_HEADER; 
typedef struct 
{ 
  GNE_HEADER              gneHeader; 
  TERM_HEADER             term1; 
  TERM_HEADER             term2; 
  RETRIEVAL_HEADER        retrieval; 
  FIELD_RETRIEVAL_HEADER  recordRet; 
} PRE_GNE_BUFFER; 
typedef struct 
{ 
  BTI_SINT      recLen; 
  BTI_LONG      recPos; 
  PERSON_STRUCT personRecord; 
} RETURNED_REC; 
typedef struct 
{ 
  BTI_SINT      numReturned; 
  RETURNED_REC  recs[20]; 
} POST_GNE_BUFFER; 
typedef union 
{ 
  PRE_GNE_BUFFER  preBuf; 
  POST_GNE_BUFFER postBuf; 
} GNE_BUFFER, BTI_FAR* GNE_BUFFER_PTR; 
//---------------------------------------------------------- 
// non-exported forward declarations 
void printLB(TListBox *LB, char *msg); 
TForm1 *Form1; 
//---------------------------------------------------------- 
__fastcall TForm1::TForm1(TComponent* Owner) 
    : TForm(Owner) 
{ 
} 
//---------------------------------------------------------- 
void __fastcall TForm1::ExitButtonClick(TObject *Sender) 
{ 
	Form1->Close(); 
} 
//---------------------------------------------------------- 
void __fastcall TForm1::RunButtonClick(TObject *Sender) 
{ 
	runTest(); 
} 
/*********************************************************** 
  Helper function to write to ListBox 
***********************************************************/ 
void printLB(TListBox *LB, char *msg) 
{ 
    LB->Items->Add(msg); 
} 
/*********************************************************** 
  This is where all the work gets done 
***********************************************************/ 
BTI_SINT runTest(void) 
{ 
  /* Btrieve function parameters */ 
  BTI_BYTE posBlock1[128]; 
  BTI_BYTE posBlock2[128]; 
  BTI_BYTE dataBuf[255]; 
  BTI_WORD dataLen; 
  BTI_BYTE keyBuf1[255]; 
  BTI_BYTE keyBuf2[255]; 
  BTI_WORD keyNum = 0; 
  BTI_BYTE btrieveLoaded = FALSE; 
  BTI_LONG personID; 
  BTI_BYTE file1Open = FALSE; 
  BTI_BYTE file2Open = FALSE; 
  BTI_SINT status; 
  BTI_SINT getStatus; 
  BTI_SINT i; 
  BTI_SINT posCtr; 
  CLIENT_ID       clientID; 
  VERSION_STRUCT  versionBuffer[3]; 
  FILE_CREATE_BUF fileCreateBuf; 
  GNE_BUFFER_PTR  gneBuffer; 
  PERSON_STRUCT   personRecord; 
  BTI_CHAR tmpBuf[1024]; 
  /********************************************************** 
     Print the program title 
  **********************************************************/ 
  printLB(Form1->ListBox1, 
        "**** Btrieve -- C++ Builder Sample ****" ); 
  /* set up the Client ID */ 
  memset(clientID.networkAndNode, 0, 
    sizeof(clientID.networkAndNode)); 
  memcpy(clientID.applicationID, "MT", 2);  
/* must be greater than "AA" */ 
  clientID.threadID = MY_THREAD_ID; 
  memset(versionBuffer, 0, sizeof(versionBuffer)); 
  dataLen = sizeof(versionBuffer); 
  status = BTRVID( 
              B_VERSION, 
              posBlock1, 
              &versionBuffer, 
              &dataLen, 
              keyBuf1, 
              keyNum, 
              (BTI_BUFFER_PTR)&clientID); 
  if (status == B_NO_ERROR) 
  { 
    strcpy(tmpBuf, "Btrieve Versions returned are: " ); 
     printLB(Form1->ListBox1, tmpBuf); 
    for (i = 0; i < 3; i++) { 
      if (versionBuffer[i].Version != 0) 
      { 
        sprintf(tmpBuf, "   %d.%d %c", versionBuffer[i].Version, 
                versionBuffer[i].Revision, 
                versionBuffer[i].MKDEId ); 
       	printLB(Form1->ListBox1, tmpBuf); 
      } 
    } 
    printLB(Form1->ListBox1, ""); 
    btrieveLoaded = TRUE; 
  } 
  else 
  { 
    sprintf(tmpBuf, "Btrieve B_VERSION status = %d", status ); 
    printLB(Form1->ListBox1, tmpBuf); 
    if ( status != B_RECORD_MANAGER_INACTIVE ) 
    { 
      btrieveLoaded = TRUE; 
    } 
  } 
  /* clear buffers */ 
  if (status == B_NO_ERROR) 
  { 
    memset(dataBuf, 0, sizeof(dataBuf)); 
    memset(keyBuf1, 0, sizeof(keyBuf1)); 
    memset(keyBuf2, 0, sizeof(keyBuf2)); 
  } 
  /* open sample.btr */ 
  if (status == B_NO_ERROR) 
  { 
    /******************************************************** 
 IMPORTANT: You should modify the following to specify the 
 complete path to `sample.btr' for your environment. 
    ********************************************************/ 
    strcpy((BTI_CHAR *)keyBuf1, "c:\\sample\\sample.btr"); 
    strcpy((BTI_CHAR *)keyBuf2, "c:\\sample\\sample2.btr"); 
    keyNum  = 0; 
    dataLen = 0; 
    status = BTRVID( 
                B_OPEN, 
                posBlock1, 
                dataBuf, 
                &dataLen, 
                keyBuf1, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    sprintf(tmpBuf, "Btrieve B_OPEN status = %d", status ); 
    printLB(Form1->ListBox1, tmpBuf); 
    if (status == B_NO_ERROR) 
    { 
      file1Open = TRUE; 
    } 
  } 
  /* get the record with key 0 = 263512477 using B_GET_EQUAL */ 
  if (status == B_NO_ERROR) 
  { 
    memset(&personRecord, 0, sizeof(personRecord)); 
    dataLen = sizeof(personRecord); 
    personID = 263512477;    /* this is really a social security number */ 
    *(BTI_LONG BTI_FAR *)&keyBuf1[0] = personID; 
    keyNum = 0; 
    status = BTRVID( 
                B_GET_EQUAL, 
                posBlock1, 
                &personRecord, 
                &dataLen, 
                keyBuf1, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    sprintf(tmpBuf, "Btrieve B_GET_EQUAL status = %d", 
			status ); 
    printLB(Form1->ListBox1, tmpBuf); 
    if (status == B_NO_ERROR) 
    { 
      sprintf(tmpBuf, "" ); 
      printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "The retrieved record is:" ); 
      printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "ID:      %ld", personRecord.ID ); 
 		printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "Name:    %s %s", personRecord.FirstName, 
                                        personRecord.LastName ); 
      printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "Street:  %s", personRecord.Street ); 
      printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "City:    %s", personRecord.City ); 
      printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "State:   %s", personRecord.State ); 
      printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "Zip:     %s", personRecord.Zip ); 
      printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "Country: %s", personRecord.Country ); 
      printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "Phone:   %s", personRecord.Phone ); 
      printLB(Form1->ListBox1, tmpBuf); 
      sprintf(tmpBuf, "" ); 
      printLB(Form1->ListBox1, tmpBuf); 
    } 
  } 
  /* perform a stat operation to populate the create buffer */ 
  memset(&fileCreateBuf, 0, sizeof(fileCreateBuf)); 
  dataLen = sizeof(fileCreateBuf); 
  keyNum = (BTI_WORD)-1; 
  status = BTRVID(B_STAT, 
                posBlock1, 
                &fileCreateBuf, 
                &dataLen, 
                keyBuf1, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
  if (status == B_NO_ERROR) 
  { 
    /* create and open sample2.btr */ 
    keyNum = 0; 
    dataLen = sizeof(fileCreateBuf); 
    status = BTRVID(B_CREATE, 
                  posBlock2, 
                  &fileCreateBuf, 
                  &dataLen, 
                  keyBuf2, 
                  keyNum, 
                  (BTI_BUFFER_PTR)&clientID); 
    sprintf(tmpBuf, "Btrieve B_CREATE status = %d", status ); 
    printLB(Form1->ListBox1, tmpBuf); 
  } 
  if (status == B_NO_ERROR) 
  { 
    keyNum = 0; 
    dataLen = 0; 
    status = BTRVID( 
                B_OPEN, 
                posBlock2, 
                dataBuf, 
                &dataLen, 
                keyBuf2, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    sprintf(tmpBuf, "Btrieve B_OPEN status = %d", status ); 
    printLB(Form1->ListBox1, tmpBuf); 
    if (status == B_NO_ERROR) 
    { 
      file2Open = TRUE; 
    } 
  } 
/* now extract data from original file, insert into new one */ 
  if (status == B_NO_ERROR) 
  { 
    /* getFirst to establish currency */ 
    keyNum = 2; /* STATE-CITY index */ 
    memset(&personRecord, 0, sizeof(personRecord)); 
    memset(&keyBuf2[0], 0, sizeof(keyBuf2)); 
    dataLen = sizeof(personRecord); 
    getStatus = BTRVID( 
                   B_GET_FIRST, 
                   posBlock1, 
                   &personRecord, 
                   &dataLen, 
                   keyBuf1, 
                   keyNum, 
                   (BTI_BUFFER_PTR)&clientID); 
    sprintf(tmpBuf, "Btrieve B_GET_FIRST status = %d", getStatus ); 
    printLB(Form1->ListBox1, tmpBuf); 
  } 
  gneBuffer = (GNE_BUFFER_PTR)malloc(sizeof(GNE_BUFFER)); 
  if (gneBuffer == NULL) 
  { 
    strcpy(tmpBuf, "Insufficient memory to allocate buffer" ); 
   	printLB(Form1->ListBox1, tmpBuf); 
    return(EXIT_WITH_ERROR); 
  } 
  memset(gneBuffer, 0, sizeof(GNE_BUFFER)); 
  memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0], "UC",
		2); 
  while (getStatus == B_NO_ERROR) 
  { 
    gneBuffer->preBuf.gneHeader.rejectCount = 0; 
    gneBuffer->preBuf.gneHeader.numberTerms = 2; 
    posCtr = sizeof(GNE_HEADER); 
    /* fill in the first condition */ 
    gneBuffer->preBuf.term1.fieldType = 11; 
    gneBuffer->preBuf.term1.fieldLen = 3; 
    gneBuffer->preBuf.term1.fieldOffset = 108; 
    gneBuffer->preBuf.term1.comparisonCode = 1; 
    gneBuffer->preBuf.term1.connector = 2; 
    memcpy(&gneBuffer->preBuf.term1.value[0], "TX", 2); 
    posCtr += sizeof(TERM_HEADER); 
    /* fill in the second condition */ 
    gneBuffer->preBuf.term2.fieldType = 11; 
    gneBuffer->preBuf.term2.fieldLen = 3; 
    gneBuffer->preBuf.term2.fieldOffset = 108; 
    gneBuffer->preBuf.term2.comparisonCode = 1; 
    gneBuffer->preBuf.term2.connector = 0; 
    memcpy(&gneBuffer->preBuf.term2.value[0], "CA", 2); 
    posCtr += sizeof(TERM_HEADER); 
    /* fill in the projection header to retrieve whole record */ 
    gneBuffer->preBuf.retrieval.maxRecsToRetrieve = 20; 
    gneBuffer->preBuf.retrieval.noFieldsToRetrieve = 1; 
    posCtr += sizeof(RETRIEVAL_HEADER); 
    gneBuffer->preBuf.recordRet.fieldLen =
		sizeof(PERSON_STRUCT); 
    gneBuffer->preBuf.recordRet.fieldOffset = 0; 
    posCtr += sizeof(FIELD_RETRIEVAL_HEADER); 
    gneBuffer->preBuf.gneHeader.descriptionLen = posCtr; 
    dataLen = sizeof(GNE_BUFFER); 
    getStatus = BTRVID( 
                   B_GET_NEXT_EXTENDED, 
                   posBlock1, 
                   gneBuffer, 
                   &dataLen, 
                   keyBuf1, 
                   keyNum, 
                   (BTI_BUFFER_PTR)&clientID); 
    sprintf(tmpBuf, "Btrieve B_GET_NEXT_EXTENDED status = %d",
		getStatus ); 
    printLB(Form1->ListBox1, tmpBuf); 
/* Get Next Extended can reach end of file and still return */ 
/* some records */ 
    if ((getStatus == B_NO_ERROR) || (getStatus ==
			B_END_OF_FILE)) 
    { 
      sprintf(tmpBuf, "GetNextExtended returned %d records.",
			gneBuffer->postBuf.numReturned); 
     	printLB(Form1->ListBox1, tmpBuf); 
      for (i = 0; i < gneBuffer->postBuf.numReturned; i++) 
      { 
        dataLen = sizeof(PERSON_STRUCT); 
        memcpy(dataBuf, &gneBuffer->
			postBuf.recs[i].personRecord, dataLen); 
        status = BTRVID( 
                    B_INSERT, 
                    posBlock2, 
                    dataBuf, 
                    &dataLen, 
                    keyBuf2, 
                    -1,   /* no currency change */ 
                    (BTI_BUFFER_PTR)&clientID); 
      } 
      sprintf(tmpBuf, "Inserted %d records in new file, 
			status = %d", 
              gneBuffer->postBuf.numReturned, status); 
     	printLB(Form1->ListBox1, tmpBuf); 
    } 
    memset(gneBuffer, 0, sizeof(GNE_BUFFER)); 
    memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0],
		"EG", 2); 
  } 
  free(gneBuffer); 
  gneBuffer = NULL; 
  /* close open files */ 
  if (file1Open) 
  { 
    dataLen = 0; 
    status = BTRVID( 
                B_CLOSE, 
                posBlock1, 
                dataBuf, 
                &dataLen, 
                keyBuf1, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    sprintf(tmpBuf, "Btrieve B_CLOSE status (sample.btr) = %d",
		status ); 
    printLB(Form1->ListBox1, tmpBuf); 
  } 
  if (file2Open) 
  { 
    dataLen = 0; 
    status = BTRVID( 
                B_CLOSE, 
                posBlock2, 
                dataBuf, 
                &dataLen, 
                keyBuf2, 
                keyNum, 
                (BTI_BUFFER_PTR)&clientID); 
    sprintf(tmpBuf, "Btrieve B_CLOSE status (sample2.btr) =
		%d", status ); 
    printLB(Form1->ListBox1, tmpBuf); 
  } 
return(status); 
} 

Chapter contents
Publication contents

Prev topic: Language Interfaces for the Btrieve API
Next topic: COBOL