home *** CD-ROM | disk | FTP | other *** search
/ Datatid 1999 #6 / Datatid_1999-06.iso / internet / Tango352Promo / P.SQL / PTKPKG.1 / BTRSAMP.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-07  |  16.6 KB  |  573 lines

  1. /*************************************************************************
  2. **
  3. **  Copyright 1982-1997 Pervasive Software Inc. All Rights Reserved
  4. **
  5. *************************************************************************/
  6. /***************************************************************************
  7.   BTRSAMP.C
  8.     This is a simple sample designed to allow you to confirm your
  9.     ability to compile, link, and execute a Btrieve application for
  10.     your target environment using your compiler tools.
  11.  
  12.     This program demonstrates the C/C++ interface for Btrieve for DOS,
  13.     Extended DOS, OS2 (16 and 32-bit), MS Windows, NetWare NLM, MS
  14.     Windows NT and Windows 95.
  15.  
  16.     This program does the following operations on the sample database:
  17.     - gets the Microkernel Database Engine version
  18.     - opens sample.btr
  19.     - gets a record on a known value of Key 0
  20.     - displays the retrieved record
  21.     - performs a stat operation
  22.     - creates an empty 'clone' of sample.btr and opens it
  23.     - performs a 'Get Next Extended' operation to extract a subset
  24.       of the records in sample.btr
  25.     - inserts those records into the cloned file
  26.     - closes both files
  27.  
  28.     IMPORTANT:
  29.     You must specify the complete path to the directory that contains
  30.     the sample Btrieve data file, 'sample.btr'.  See IMPORTANT, below.
  31.  
  32.     You can compile and run this program on any of the platforms
  33.     supported by the interface modules.  Platforms are indicated by the
  34.     platform switches listed in 'btrapi.h'.  For MS Windows you should
  35.     make an application that allows standard output via printf().  Note
  36.     that most C/C++ compilers support standard I/O Windows applications.
  37.     For MS Windows NT or OS2, you should make a console application.
  38.  
  39.     See the prologue in 'btrapi.h' for information on how to select
  40.     a target platform for your application.  You must specify a target
  41.     platform.
  42.  
  43. ****************************************************************************/
  44. #include <stdlib.h>
  45. #include <stdio.h>
  46. #include <string.h>
  47. #include <btrapi.h>
  48. #include <btrconst.h>
  49.  
  50. /***************************************************************************
  51.   Constants
  52. ****************************************************************************/
  53. /********************************************************************
  54.    IMPORTANT: You should modify the following to specify the
  55.               complete path to 'sample.btr' for your environment.
  56. ********************************************************************/
  57. #ifdef BTI_NLM
  58. #define FILE1_NAME "sys:\\pvsw\\samples\\sample.btr"
  59. #else
  60. #define FILE1_NAME "c:\\pvsw\\samples\\sample.btr"
  61. #endif
  62.  
  63. #ifdef BTI_NLM
  64. #define FILE2_NAME "sys:\\pvsw\\samples\\sample2.btr"
  65. #else
  66. #define FILE2_NAME "c:\\pvsw\\samples\\sample2.btr"
  67. #endif
  68.  
  69. #define EXIT_WITH_ERROR     1
  70. #define TRUE                1
  71. #define FALSE               0
  72. #define VERSION_OFFSET      0
  73. #define REVISION_OFFSET     2
  74. #define PLATFORM_ID_OFFSET  4
  75. #define MY_THREAD_ID        50
  76.  
  77. /* Don't pad our structures */
  78. #if defined(__BORLANDC__)
  79.   #pragma option -a-
  80. #else
  81.   #if defined(_MSC_VER) || defined(__WATCOMC__)
  82.     #pragma pack(1)
  83.   #endif
  84. #endif
  85.  
  86. /***************************************************************************
  87.   Type definitions for Client ID and version Structures
  88. ****************************************************************************/
  89. typedef struct
  90. {
  91.   BTI_CHAR networkAndNode[12];
  92.   BTI_CHAR applicationID[2];
  93.   BTI_WORD threadID;
  94. } CLIENT_ID;
  95.  
  96. typedef struct
  97. {
  98.   BTI_SINT  Version;
  99.   BTI_SINT  Revision;
  100.   BTI_CHAR  MKDEId;
  101. } VERSION_STRUCT;
  102.  
  103. /***************************************************************************
  104.   Definition of record from 'sample.btr'
  105. ****************************************************************************/
  106. typedef struct
  107. {
  108.   BTI_LONG  ID;
  109.   BTI_CHAR  FirstName[16];
  110.   BTI_CHAR  LastName[26];
  111.   BTI_CHAR  Street[31];
  112.   BTI_CHAR  City[31];
  113.   BTI_CHAR  State[3];
  114.   BTI_CHAR  Zip[11];
  115.   BTI_CHAR  Country[21];
  116.   BTI_CHAR  Phone[14];
  117. } PERSON_STRUCT;
  118.  
  119. /***************************************************************************
  120.   Type definitions for Stat/Create structure
  121. ****************************************************************************/
  122. typedef struct
  123. {
  124.   BTI_SINT recLength;
  125.   BTI_SINT pageSize;
  126.   BTI_SINT indexCount;
  127.   BTI_CHAR reserved[4];
  128.   BTI_SINT flags;
  129.   BTI_BYTE dupPointers;
  130.   BTI_BYTE notUsed;
  131.   BTI_SINT allocations;
  132. } FILE_SPECS;
  133.  
  134. typedef struct
  135. {
  136.   BTI_SINT position;
  137.   BTI_SINT length;
  138.   BTI_SINT flags;
  139.   BTI_CHAR reserved[4];
  140.   BTI_CHAR type;
  141.   BTI_CHAR null;
  142.   BTI_CHAR notUsed[2];
  143.   BTI_BYTE manualKeyNumber;
  144.   BTI_BYTE acsNumber;
  145. } KEY_SPECS;
  146.  
  147. typedef struct
  148. {
  149.   FILE_SPECS fileSpecs;
  150.   KEY_SPECS  keySpecs[5];
  151. } FILE_CREATE_BUF;
  152.  
  153. /***************************************************************************
  154.   Structure type definitions for Get Next Extended operation
  155. ****************************************************************************/
  156. typedef struct
  157. {
  158.   BTI_SINT    descriptionLen;
  159.   BTI_CHAR    currencyConst[2];
  160.   BTI_SINT    rejectCount;
  161.   BTI_SINT    numberTerms;
  162. } GNE_HEADER;
  163.  
  164. typedef struct
  165. {
  166.   BTI_CHAR    fieldType;
  167.   BTI_SINT    fieldLen;
  168.   BTI_SINT    fieldOffset;
  169.   BTI_CHAR    comparisonCode;
  170.   BTI_CHAR    connector;
  171.   BTI_CHAR value[3];
  172. } TERM_HEADER;
  173.  
  174. typedef struct
  175. {
  176.   BTI_SINT    maxRecsToRetrieve;
  177.   BTI_SINT    noFieldsToRetrieve;
  178. } RETRIEVAL_HEADER;
  179.  
  180. typedef struct
  181. {
  182.   BTI_SINT    fieldLen;
  183.   BTI_SINT    fieldOffset;
  184. } FIELD_RETRIEVAL_HEADER;
  185.  
  186. typedef struct
  187. {
  188.   GNE_HEADER              gneHeader;
  189.   TERM_HEADER             term1;
  190.   TERM_HEADER             term2;
  191.   RETRIEVAL_HEADER        retrieval;
  192.   FIELD_RETRIEVAL_HEADER  recordRet;
  193. } PRE_GNE_BUFFER;
  194.  
  195. typedef struct
  196. {
  197.   BTI_SINT      recLen;
  198.   BTI_LONG      recPos;
  199.   PERSON_STRUCT personRecord;
  200. } RETURNED_REC;
  201.  
  202. typedef struct
  203. {
  204.   BTI_SINT      numReturned;
  205.   RETURNED_REC  recs[20];
  206. } POST_GNE_BUFFER;
  207.  
  208. typedef union
  209. {
  210.   PRE_GNE_BUFFER  preBuf;
  211.   POST_GNE_BUFFER postBuf;
  212. } GNE_BUFFER, BTI_FAR* GNE_BUFFER_PTR;
  213.  
  214. /* restore structure packing */
  215. #if defined(__BORLANDC__)
  216.   #pragma option -a.
  217. #else
  218.   #if defined(_MSC_VER) || defined(__WATCOMC__)
  219.     #pragma pack()
  220.   #endif
  221. #endif
  222.  
  223. /***************************************************************************
  224.   Main
  225. ****************************************************************************/
  226. int main(void)
  227. {
  228.   /* Btrieve function parameters */
  229.   BTI_BYTE posBlock1[128];
  230.   BTI_BYTE posBlock2[128];
  231.   BTI_BYTE dataBuf[255];
  232.   BTI_WORD dataLen;
  233.   BTI_BYTE keyBuf1[255];
  234.   BTI_BYTE keyBuf2[255];
  235.   BTI_WORD keyNum = 0;
  236.  
  237.   BTI_BYTE btrieveLoaded = FALSE;
  238.   BTI_LONG personID;
  239.   BTI_BYTE file1Open = FALSE;
  240.   BTI_BYTE file2Open = FALSE;
  241.   BTI_SINT status;
  242.   BTI_SINT getStatus = -1;
  243.   BTI_SINT i;
  244.   BTI_SINT posCtr;
  245.  
  246.   CLIENT_ID       clientID;
  247.   VERSION_STRUCT  versionBuffer[3];
  248.   FILE_CREATE_BUF fileCreateBuf;
  249.   GNE_BUFFER_PTR  gneBuffer;
  250.   PERSON_STRUCT   personRecord;
  251.  
  252.   printf("**************** Btrieve C/C++ Interface Demo ****************\n\n");
  253.  
  254.   /* set up the Client ID */
  255.   memset(clientID.networkAndNode, 0, sizeof(clientID.networkAndNode));
  256.   memcpy(clientID.applicationID, "MT", 2);  /* must be greater than "AA" */
  257.   clientID.threadID = MY_THREAD_ID;
  258.  
  259.   memset(versionBuffer, 0, sizeof(versionBuffer));
  260.   dataLen = sizeof(versionBuffer);
  261.  
  262.   status = BTRVID(
  263.               B_VERSION,
  264.               posBlock1,
  265.               &versionBuffer,
  266.               &dataLen,
  267.               keyBuf1,
  268.               keyNum,
  269.               (BTI_BUFFER_PTR)&clientID);
  270.  
  271.   if (status == B_NO_ERROR)
  272.   {
  273.     printf("Btrieve Versions returned are: \n");
  274.     for (i = 0; i < 3; i++) {
  275.       if (versionBuffer[i].Version != 0)
  276.       {
  277.         printf("   %d.%d %c\n", versionBuffer[i].Version,
  278.                 versionBuffer[i].Revision,
  279.                 versionBuffer[i].MKDEId);
  280.       }
  281.     }
  282.     printf("\n");
  283.     btrieveLoaded = TRUE;
  284.   }
  285.   else
  286.   {
  287.     printf("Btrieve B_VERSION status = %d\n", status);
  288.     if (status != B_RECORD_MANAGER_INACTIVE)
  289.     {
  290.       btrieveLoaded = TRUE;
  291.     }
  292.   }
  293.  
  294.   /* clear buffers */
  295.   if (status == B_NO_ERROR)
  296.   {
  297.     memset(dataBuf, 0, sizeof(dataBuf));
  298.     memset(keyBuf1, 0, sizeof(keyBuf1));
  299.     memset(keyBuf2, 0, sizeof(keyBuf2));
  300.   }
  301.  
  302.   /* open sample.btr */
  303.   if (status == B_NO_ERROR)
  304.   {
  305.  
  306.     strcpy((BTI_CHAR *)keyBuf1, FILE1_NAME);
  307.     strcpy((BTI_CHAR *)keyBuf2, FILE2_NAME);
  308.  
  309.     keyNum  = 0;
  310.     dataLen = 0;
  311.  
  312.     status = BTRVID(
  313.                 B_OPEN,
  314.                 posBlock1,
  315.                 dataBuf,
  316.                 &dataLen,
  317.                 keyBuf1,
  318.                 keyNum,
  319.                 (BTI_BUFFER_PTR)&clientID);
  320.  
  321.     printf("Btrieve B_OPEN status (sample.btr) = %d\n", status);
  322.     if (status == B_NO_ERROR)
  323.     {
  324.       file1Open = TRUE;
  325.     }
  326.   }
  327.  
  328.   /* get the record with key 0 = 263512477 using B_GET_EQUAL */
  329.   if (status == B_NO_ERROR)
  330.   {
  331.     memset(&personRecord, 0, sizeof(personRecord));
  332.     dataLen = sizeof(personRecord);
  333.     personID = 263512477;    /* this is really a social security number */
  334.     *(BTI_LONG BTI_FAR *)&keyBuf1[0] = personID;
  335.     keyNum = 0;
  336.  
  337.     status = BTRVID(
  338.                 B_GET_EQUAL,
  339.                 posBlock1,
  340.                 &personRecord,
  341.                 &dataLen,
  342.                 keyBuf1,
  343.                 keyNum,
  344.                 (BTI_BUFFER_PTR)&clientID);
  345.  
  346.     printf("Btrieve B_GET_EQUAL status = %d\n", status);
  347.     if (status == B_NO_ERROR)
  348.     {
  349.       printf("\n");
  350.       printf("The retrieved record is:\n");
  351.       printf("ID:      %ld\n", personRecord.ID);
  352.       printf("Name:    %s %s\n", personRecord.FirstName,
  353.                                  personRecord.LastName);
  354.       printf("Street:  %s\n", personRecord.Street);
  355.       printf("City:    %s\n", personRecord.City);
  356.       printf("State:   %s\n", personRecord.State);
  357.       printf("Zip:     %s\n", personRecord.Zip);
  358.       printf("Country: %s\n", personRecord.Country);
  359.       printf("Phone:   %s\n", personRecord.Phone);
  360.       printf("\n");
  361.     }
  362.   }
  363.  
  364.   /* perform a stat operation to populate the create buffer */
  365.   memset(&fileCreateBuf, 0, sizeof(fileCreateBuf));
  366.   dataLen = sizeof(fileCreateBuf);
  367.   keyNum = (BTI_WORD)-1;
  368.  
  369.   status = BTRVID(B_STAT,
  370.                 posBlock1,
  371.                 &fileCreateBuf,
  372.                 &dataLen,
  373.                 keyBuf1,
  374.                 keyNum,
  375.                 (BTI_BUFFER_PTR)&clientID);
  376.  
  377.   if (status == B_NO_ERROR)
  378.   {
  379.     /* create and open sample2.btr */
  380.     keyNum = 0;
  381.     dataLen = sizeof(fileCreateBuf);
  382.     status = BTRVID(B_CREATE,
  383.                   posBlock2,
  384.                   &fileCreateBuf,
  385.                   &dataLen,
  386.                   keyBuf2,
  387.                   keyNum,
  388.                   (BTI_BUFFER_PTR)&clientID);
  389.  
  390.     printf("Btrieve B_CREATE status = %d\n", status);
  391.   }
  392.  
  393.   if (status == B_NO_ERROR)
  394.   {
  395.     keyNum = 0;
  396.     dataLen = 0;
  397.  
  398.     status = BTRVID(
  399.                 B_OPEN,
  400.                 posBlock2,
  401.                 dataBuf,
  402.                 &dataLen,
  403.                 keyBuf2,
  404.                 keyNum,
  405.                 (BTI_BUFFER_PTR)&clientID);
  406.  
  407.     printf("Btrieve B_OPEN status (sample2.btr) = %d\n", status);
  408.     if (status == B_NO_ERROR)
  409.     {
  410.       file2Open = TRUE;
  411.     }
  412.   }
  413.  
  414.   /* now extract data from the original file, insert into new one */
  415.   if (status == B_NO_ERROR)
  416.   {
  417.     /* getFirst to establish currency */
  418.     keyNum = 2; /* STATE-CITY index */
  419.     memset(&personRecord, 0, sizeof(personRecord));
  420.     memset(&keyBuf2[0], 0, sizeof(keyBuf2));
  421.     dataLen = sizeof(personRecord);
  422.  
  423.     getStatus = BTRVID(
  424.                    B_GET_FIRST,
  425.                    posBlock1,
  426.                    &personRecord,
  427.                    &dataLen,
  428.                    keyBuf1,
  429.                    keyNum,
  430.                    (BTI_BUFFER_PTR)&clientID);
  431.  
  432.     printf("Btrieve B_GET_FIRST status (sample.btr) = %d\n\n", getStatus);
  433.   }
  434.  
  435.   gneBuffer = malloc(sizeof(GNE_BUFFER));
  436.   if (gneBuffer == NULL)
  437.   {
  438.      printf("Insufficient memory to allocate buffer");
  439.     return(EXIT_WITH_ERROR);
  440.   }
  441.   memset(gneBuffer, 0, sizeof(GNE_BUFFER));
  442.   memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0], "UC", 2);
  443.   while (getStatus == B_NO_ERROR)
  444.   {
  445.     gneBuffer->preBuf.gneHeader.rejectCount = 0;
  446.     gneBuffer->preBuf.gneHeader.numberTerms = 2;
  447.     posCtr = sizeof(GNE_HEADER);
  448.  
  449.     /* fill in the first condition */
  450.     gneBuffer->preBuf.term1.fieldType = 11;
  451.     gneBuffer->preBuf.term1.fieldLen = 3;
  452.     gneBuffer->preBuf.term1.fieldOffset = 108;
  453.     gneBuffer->preBuf.term1.comparisonCode = 1;
  454.     gneBuffer->preBuf.term1.connector = 2;
  455.     memcpy(&gneBuffer->preBuf.term1.value[0], "TX", 2);
  456.     posCtr += sizeof(TERM_HEADER);
  457.  
  458.     /* fill in the second condition */
  459.     gneBuffer->preBuf.term2.fieldType = 11;
  460.     gneBuffer->preBuf.term2.fieldLen = 3;
  461.     gneBuffer->preBuf.term2.fieldOffset = 108;
  462.     gneBuffer->preBuf.term2.comparisonCode = 1;
  463.     gneBuffer->preBuf.term2.connector = 0;
  464.     memcpy(&gneBuffer->preBuf.term2.value[0], "CA", 2);
  465.     posCtr += sizeof(TERM_HEADER);
  466.  
  467.     /* fill in the projection header to retrieve whole record */
  468.     gneBuffer->preBuf.retrieval.maxRecsToRetrieve = 20;
  469.     gneBuffer->preBuf.retrieval.noFieldsToRetrieve = 1;
  470.     posCtr += sizeof(RETRIEVAL_HEADER);
  471.     gneBuffer->preBuf.recordRet.fieldLen = sizeof(PERSON_STRUCT);
  472.     gneBuffer->preBuf.recordRet.fieldOffset = 0;
  473.     posCtr += sizeof(FIELD_RETRIEVAL_HEADER);
  474.     gneBuffer->preBuf.gneHeader.descriptionLen = posCtr;
  475.  
  476.     dataLen = sizeof(GNE_BUFFER);
  477.     getStatus = BTRVID(
  478.                    B_GET_NEXT_EXTENDED,
  479.                    posBlock1,
  480.                    gneBuffer,
  481.                    &dataLen,
  482.                    keyBuf1,
  483.                    keyNum,
  484.                    (BTI_BUFFER_PTR)&clientID);
  485.  
  486.      printf("Btrieve B_GET_NEXT_EXTENDED status = %d\n", getStatus);
  487.  
  488.     /* Get Next Extended can reach end of file and still return some records */
  489.     if ((getStatus == B_NO_ERROR) || (getStatus == B_END_OF_FILE))
  490.     {
  491.       printf("GetNextExtended returned %d records.\n", gneBuffer->postBuf.numReturned);
  492.       for (i = 0; i < gneBuffer->postBuf.numReturned; i++)
  493.       {
  494.         dataLen = sizeof(PERSON_STRUCT);
  495.         memcpy(dataBuf, &gneBuffer->postBuf.recs[i].personRecord, dataLen);
  496.         status = BTRVID(
  497.                     B_INSERT,
  498.                     posBlock2,
  499.                     dataBuf,
  500.                     &dataLen,
  501.                     keyBuf2,
  502.                     -1,   /* no currency change */
  503.                     (BTI_BUFFER_PTR)&clientID);
  504.       }
  505.       printf("Inserted %d records in new file, status = %d\n\n", gneBuffer->postBuf.numReturned, status);
  506.     }
  507.     memset(gneBuffer, 0, sizeof(GNE_BUFFER));
  508.     memcpy(&gneBuffer->preBuf.gneHeader.currencyConst[0], "EG", 2);
  509.   }
  510.  
  511.   free(gneBuffer);
  512.   gneBuffer = NULL;
  513.  
  514.   /* close open files */
  515.   if (file1Open)
  516.   {
  517.     dataLen = 0;
  518.  
  519.     status = BTRVID(
  520.                 B_CLOSE,
  521.                 posBlock1,
  522.                 dataBuf,
  523.                 &dataLen,
  524.                 keyBuf1,
  525.                 keyNum,
  526.                 (BTI_BUFFER_PTR)&clientID);
  527.  
  528.     printf("Btrieve B_CLOSE status (sample.btr) = %d\n", status);
  529.   }
  530.  
  531.   if (file2Open)
  532.   {
  533.     dataLen = 0;
  534.  
  535.     status = BTRVID(
  536.                 B_CLOSE,
  537.                 posBlock2,
  538.                 dataBuf,
  539.                 &dataLen,
  540.                 keyBuf2,
  541.                 keyNum,
  542.                 (BTI_BUFFER_PTR)&clientID);
  543.  
  544.     printf("Btrieve B_CLOSE status (sample2.btr) = %d\n", status);
  545.   }
  546.  
  547.   /**********************************************************************
  548.      ISSUE THE BTRIEVE STOP OPERATION - For multi-tasking environments,
  549.      such as MS Windows, OS2, and NLM, 'stop' frees all Btrieve resources
  550.      for this client.  In DOS and Extended DOS, it removes the Btrieve
  551.      engine from memory, which we choose not to do in this example.  In
  552.      multi-tasking environments, the engine will not unload on 'stop'
  553.      unless it has no more clients.
  554.   ***********************************************************************/
  555.   #if !defined(BTI_DOS) && !defined(BTI_DOS_32R) && \
  556.   !defined(BTI_DOS_32B) && !defined(BTI_DOS_32P)
  557.   if (btrieveLoaded)
  558.   {
  559.     dataLen = 0;
  560.     status = BTRVID(B_STOP, posBlock1, dataBuf, &dataLen, keyBuf1, keyNum,
  561.              (BTI_BUFFER_PTR)&clientID);
  562.     printf("Btrieve STOP status = %d\n", status);
  563.     if (status != B_NO_ERROR)
  564.     {
  565.        status = EXIT_WITH_ERROR;
  566.     }
  567.   }
  568.   #endif
  569.  
  570.   return(status);
  571. }
  572.  
  573.