home *** CD-ROM | disk | FTP | other *** search
/ Datatid 1999 #6 / Datatid_1999-06.iso / internet / Tango352Promo / P.SQL / PTKPKG.1 / BTRSAMPD.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-11-07  |  15.9 KB  |  519 lines

  1. {*************************************************************************
  2. **
  3. **  Copyright 1982-1997 Pervasive Software Inc. All Rights Reserved
  4. **
  5. *************************************************************************}
  6. {*************************************************************************
  7.   BTRSAMPD.PAS
  8.     This program demonstrates the Btrieve Interface using Borland Pascal
  9.     for MS Windows.
  10.  
  11.     This program does the following operations on the sample file:
  12.     - gets the Microkernel Database Engine version using BTRVID
  13.     - opens sample.btr
  14.     - gets a record on a known value of Key 0
  15.     - displays the retrieved record
  16.     - performs a stat operation
  17.     - creates an empty 'clone' of sample.btr and opens it
  18.     - performs a 'Get Next Extended' operation to extract a subset
  19.       of the records in sample.btr
  20.     - inserts those records into the cloned file
  21.     - closes both files
  22.  
  23.     IMPORTANT:
  24.     You must specify the complete path to the directory that contains
  25.     the sample Btrieve data file, 'sample.btr'.  See IMPORTANT, below.
  26. *************************************************************************}
  27. program btrsampd;
  28.  
  29. uses
  30.   Strings,    { Pascal System functions }
  31.   btrapid,    { btrieve interface unit }
  32.   btrconst;   { Btrieve Constants Unit }
  33.  
  34. const
  35.   {********************************************************************
  36.       IMPORTANT: You should modify the following to specify the
  37.                 complete path to 'sample.btr' for your environment.
  38.   ********************************************************************}
  39.   FILE1_NAME          = 'c:\pvsw\samples\sample.btr' + #0;
  40.   FILE2_NAME          = 'c:\pvsw\samples\sample2.btr' + #0;
  41.  
  42.   { program constants }
  43.   MY_THREAD_ID        = 50;
  44.   EXIT_WITH_ERROR     = 1;
  45.   VERSION_OFFSET      = 0;
  46.   REVISION_OFFSET     = 2;
  47.   PLATFORM_ID_OFFSET  = 4;
  48.  
  49. {***************************************************************************
  50.   Record type definitions for Version operation
  51. ****************************************************************************}
  52. type
  53.   CLIENT_ID = packed record
  54.     networkandnode : array[0..11] of char;
  55.     applicationID  : array[0..2] of char;
  56.     threadID       : integer;
  57.   end;
  58.  
  59.   VERSION_STRUCT = packed record
  60.     version   : integer;
  61.     revision  : integer;
  62.     MKDEId    : char;
  63.   end;
  64.  
  65. {***************************************************************************
  66.   Definition of record from 'sample.btr'
  67. ****************************************************************************}
  68.  
  69.   {* Use 'zero-based' arrays of char for writeln() compatibility *}
  70.   PERSON_STRUCT = packed record
  71.     ID          : longint;
  72.     FirstName   : array[0..15] of char;
  73.     LastName    : array[0..25] of char;
  74.     Street      : array[0..30] of char;
  75.     City        : array[0..30] of char;
  76.     State       : array[0..2]  of char;
  77.     Zip         : array[0..10] of char;
  78.     Country     : array[0..20] of char;
  79.     Phone       : array[0..13] of char;
  80.   end;
  81.  
  82. {***************************************************************************
  83.   Record type definitions for Stat and Create operations
  84. ****************************************************************************}
  85.   FILE_SPECS = packed record
  86.     recLength   : integer;
  87.     pageSize    : integer;
  88.     indexCount  : integer;
  89.     reserved    : array[0..3] of char;
  90.     flags       : integer;
  91.     dupPointers : byte;
  92.     notUsed     : byte;
  93.     allocations : integer;
  94.   end;
  95.  
  96.   KEY_SPECS = packed record
  97.     position : integer;
  98.     length : integer;
  99.     flags : integer;
  100.     reserved : array [0..3] of char;
  101.     keyType : char;
  102.     nullChar : char;
  103.     notUsed : array[0..1] of char;
  104.     manualKeyNumber : byte;
  105.     acsNumber : byte;
  106.   end;
  107.  
  108.   FILE_CREATE_BUF = packed record
  109.     fileSpecs : FILE_SPECS;
  110.     keySpecs  : array[0..4] of KEY_SPECS;
  111.   end;
  112.  
  113. {***************************************************************************
  114.   Record type definitions for Get Next Extended operation
  115. ****************************************************************************}
  116.  
  117.   GNE_HEADER = packed record
  118.     descriptionLen  : integer;
  119.     currencyConst   : array[0..1] of char;
  120.     rejectCount     : integer;
  121.     numberTerms     : integer;
  122.   end;
  123.  
  124.   TERM_HEADER = packed record
  125.     fieldType       : byte;
  126.     fieldLen        : integer;
  127.     fieldOffset     : integer;
  128.     comparisonCode  : byte;
  129.     connector       : byte;
  130.     value           : array[0..2] of char;
  131.   end;
  132.  
  133.   RETRIEVAL_HEADER = packed record
  134.     maxRecsToRetrieve   : integer;
  135.     noFieldsToRetrieve  : integer;
  136.   end;
  137.  
  138.   FIELD_RETRIEVAL_HEADER = packed record
  139.     fieldLen    : integer;
  140.     fieldOffset : integer;
  141.   end;
  142.  
  143.   PRE_GNE_BUFFER = packed record
  144.     gneHeader : GNE_HEADER;
  145.     term1     : TERM_HEADER;
  146.     term2     : TERM_HEADER;
  147.     retrieval : RETRIEVAL_HEADER;
  148.     recordRet : FIELD_RETRIEVAL_HEADER;
  149.   end;
  150.  
  151.   RETURNED_REC = packed record
  152.     recLen        : integer;
  153.     recPos        : longint;
  154.     personRecord  : PERSON_STRUCT;
  155.   end;
  156.  
  157.   POST_GNE_BUFFER = packed record
  158.     numReturned : integer;
  159.     recs        : packed array[0..19] of RETURNED_REC;
  160.   end;
  161.  
  162.   GNE_BUFFER_PTR = ^GNE_BUFFER;
  163.   GNE_BUFFER = packed record
  164.   case byte of
  165.     1 : (preBuf  : PRE_GNE_BUFFER);
  166.     2 : (postBuf : POST_GNE_BUFFER);
  167.   end;
  168.  
  169. {***********************************************************************
  170.   Variables
  171. ************************************************************************}
  172. var
  173.   { Btrieve function parameters }
  174.   posBlock1     : string[128];
  175.   posBlock2     : string[128];
  176.   dataBuffer    : array[0..255] of char;
  177.   dataLen       : word;
  178.   keyBuf1       : string[255];
  179.   keyBuf2       : string[255];
  180.   keyNum        : integer;
  181.  
  182.   btrieveLoaded : boolean;
  183.   personID      : longint;
  184.   file1Open     : boolean;
  185.   file2Open     : boolean;
  186.   status        : integer;
  187.   getStatus     : integer;
  188.   i             : integer;
  189.   posCtr        : integer;
  190.  
  191.   client        : CLIENT_ID;
  192.   versionBuffer : array[1..3] of VERSION_STRUCT;
  193.   fileCreateBuf : FILE_CREATE_BUF;
  194.   gneBuffer     : GNE_BUFFER_PTR;
  195.   personRecord  : PERSON_STRUCT;
  196.  
  197. {***********************************************************************
  198.   Program starts here
  199. ************************************************************************}
  200. begin { btrsamp }
  201.   { initialize variables }
  202.   btrieveLoaded := FALSE;
  203.   file1Open := FALSE;
  204.   file2Open := FALSE;
  205.   keyNum := 0;
  206.   status := B_NO_ERROR;
  207.   getStatus := B_NO_ERROR;
  208.  
  209.   writeln;
  210.   writeln('************ Btrieve Pascal Interface for Windows Demo ************');
  211.   writeln;
  212.  
  213.   { set up the Client ID }
  214.   fillchar(client.networkAndNode, sizeof(client.networkAndNode), #0);
  215.  
  216. {$ifdef ver70} {Note: Delphi 1.0 is ver80}
  217.   client.applicationID := 'MT' + #0;     { must be greater than "AA" }
  218. {$else}
  219.   strpcopy(client.applicationID, 'MT');  { must be greater than "AA" }
  220.   strcat(client.applicationID, #0);
  221. {$endif}
  222.  
  223.   client.threadID := MY_THREAD_ID;
  224.  
  225.   fillchar(versionBuffer, sizeof(versionBuffer), #0);
  226.   dataLen := sizeof(versionBuffer);
  227.  
  228.   status := BTRVID(
  229.               B_VERSION,
  230.               posBlock1,
  231.               versionBuffer,
  232.               dataLen,
  233.               keyBuf1[1],
  234.               keyNum,
  235.               client);
  236.  
  237.   if status = B_NO_ERROR then begin
  238.     writeln('Btrieve Versions returned are:');
  239.     for i := 1 to 3 do begin
  240.       with versionBuffer[i] do begin
  241.         if (version > 0) then begin
  242.           writeln(version, '.', revision, ' ', MKDEId);
  243.         end
  244.       end
  245.     end;
  246.     btrieveLoaded := TRUE;
  247.   end else begin
  248.     writeln('Btrieve B_VERSION status = ', status);
  249.     if status <> B_RECORD_MANAGER_INACTIVE then begin
  250.       btrieveLoaded := TRUE;
  251.     end
  252.   end;
  253.  
  254.   {* open sample.btr *}
  255.   if status = B_NO_ERROR then begin
  256.     fillchar(dataBuffer, sizeof(dataBuffer), #0);
  257.     fillchar(keyBuf1, sizeof(keyBuf1), #0);
  258.     keyNum := 0;
  259.     dataLen := 0;
  260.  
  261.     keyBuf1 := FILE1_NAME;
  262.     keyBuf2 := FILE2_NAME;
  263.  
  264.     status := BTRVID(
  265.                   B_OPEN,
  266.                   posBlock1,
  267.                   dataBuffer,
  268.                   dataLen,
  269.                   keyBuf1[1],
  270.                   keyNum,
  271.                   client);
  272.  
  273.     writeln('Btrieve B_OPEN status = ', status);
  274.     if status = B_NO_ERROR then begin
  275.       file1Open := TRUE;
  276.     end
  277.   end;
  278.  
  279.   {* get the record using key 0 = a known value using B_GET_EQUAL *}
  280.   if status = B_NO_ERROR then begin
  281.     fillchar(personRecord, sizeof(personRecord), #0);
  282.     dataLen := sizeof(personRecord);
  283.     personID := 263512477;  {* this is really a social security number *}
  284.  
  285.     status := BTRVID(
  286.                 B_GET_EQUAL,
  287.                 posBlock1,
  288.                 personRecord,
  289.                 dataLen,
  290.                 personID,
  291.                 keyNum,
  292.                 client);
  293.  
  294.     writeln('Btrieve B_GET_EQUAL status = ', status);
  295.     if status = B_NO_ERROR then with personRecord do begin
  296.       writeln;
  297.       writeln('Selected fields from the retrieved record are:');
  298.       writeln('ID:      ', ID);
  299.       writeln('Name:    ', FirstName, ' ',
  300.                             LastName);
  301.       writeln('Street:  ', Street);
  302.       writeln('City:    ', City);
  303.       writeln('State:   ', State);
  304.       writeln('Zip:     ', Zip);
  305.       writeln('Country: ', Country);
  306.       writeln('Phone:   ', Phone);
  307.       writeln;
  308.     end;
  309.   end;
  310.  
  311.   { perform a stat operation to populate the create buffer }
  312.   fillchar(fileCreateBuf, sizeof(fileCreateBuf), #0);
  313.   dataLen := sizeof(fileCreateBuf);
  314.   keyNum  := -1;
  315.   status := BTRVID(B_STAT,
  316.                 posBlock1,
  317.                 fileCreateBuf,
  318.                 dataLen,
  319.                 keyBuf1[1],
  320.                 keyNum,
  321.                 client);
  322.  
  323.   if (status = B_NO_ERROR) then begin
  324.     { create and open sample2.btr }
  325.     keyNum := 0;
  326.     dataLen := sizeof(fileCreateBuf);
  327.     status := BTRVID(B_CREATE,
  328.                   posBlock2,
  329.                   fileCreateBuf,
  330.                   dataLen,
  331.                   keyBuf2[1],
  332.                   keyNum,
  333.                   client);
  334.  
  335.     writeln('Btrieve B_CREATE status = ', status);
  336.   end;
  337.  
  338.   if (status = B_NO_ERROR) then begin
  339.     keyNum  := 0;
  340.     dataLen := 0;
  341.  
  342.     status := BTRVID(
  343.                 B_OPEN,
  344.                 posBlock2,
  345.                 dataBuffer,
  346.                 dataLen,
  347.                 keyBuf2[1],
  348.                 keyNum,
  349.                 client);
  350.     writeln('Btrieve B_OPEN status (sample2.btr) = ', status);
  351.     if (status = B_NO_ERROR) then begin
  352.       file2Open := TRUE;
  353.     end;
  354.   end;
  355.  
  356.   { now extract data from the original file, insert into new one }
  357.   if (status = B_NO_ERROR) then begin
  358.     { getFirst to establish currency }
  359.     keyNum := 2; { STATE-CITY index }
  360.     fillchar(personRecord, sizeof(personRecord), #0);
  361.     fillchar(keyBuf1, sizeof(keyBuf1), #0);
  362.     dataLen := sizeof(personRecord);
  363.  
  364.     getStatus := BTRVID(
  365.                    B_GET_FIRST,
  366.                    posBlock1,
  367.                    personRecord,
  368.                    dataLen,
  369.                    keyBuf1[1],
  370.                    keyNum,
  371.                    client);
  372.  
  373.     writeln('Btrieve B_GET_FIRST status (sample.btr) = ', getStatus);
  374.     writeln;
  375.   end;
  376.  
  377.   if maxavail < SizeOf(GNE_BUFFER) then begin
  378.     writeln('Insufficient memory to allocate buffer');
  379.     halt(EXIT_WITH_ERROR);
  380.   end else begin
  381.     { Allocate memory on heap }
  382.     gneBuffer := new(GNE_BUFFER_PTR);
  383.   end;
  384.   fillchar(gneBuffer^, sizeof(GNE_BUFFER), #0);
  385.   strPCopy(gneBuffer^.preBuf.gneHeader.currencyConst, 'UC');
  386.   while (getStatus = B_NO_ERROR) do begin
  387.     gneBuffer^.preBuf.gneHeader.rejectCount := 0;
  388.     gneBuffer^.preBuf.gneHeader.numberTerms := 2;
  389.     posCtr := sizeof(GNE_HEADER);
  390.  
  391.     { fill in the first condition }
  392.     gneBuffer^.preBuf.term1.fieldType := 11;
  393.     gneBuffer^.preBuf.term1.fieldLen := 3;
  394.     gneBuffer^.preBuf.term1.fieldOffset := 108;
  395.     gneBuffer^.preBuf.term1.comparisonCode := 1;
  396.     gneBuffer^.preBuf.term1.connector := 2;
  397.  
  398.     strPCopy(gneBuffer^.preBuf.term1.value, 'TX');
  399.     inc(posCtr, (sizeof(TERM_HEADER)));
  400.  
  401.     { fill in the second condition }
  402.     gneBuffer^.preBuf.term2.fieldType := 11;
  403.     gneBuffer^.preBuf.term2.fieldLen := 3;
  404.     gneBuffer^.preBuf.term2.fieldOffset := 108;
  405.     gneBuffer^.preBuf.term2.comparisonCode := 1;
  406.     gneBuffer^.preBuf.term2.connector := 0;
  407.     strPCopy(gneBuffer^.preBuf.term2.value, 'CA');
  408.     inc(posCtr, sizeof(TERM_HEADER));
  409.  
  410.     { fill in the projection header to retrieve whole record }
  411.     gneBuffer^.preBuf.retrieval.maxRecsToRetrieve := 20;
  412.     gneBuffer^.preBuf.retrieval.noFieldsToRetrieve := 1;
  413.     inc(posCtr, sizeof(RETRIEVAL_HEADER));
  414.     gneBuffer^.preBuf.recordRet.fieldLen := sizeof(PERSON_STRUCT);
  415.     gneBuffer^.preBuf.recordRet.fieldOffset := 0;
  416.     inc(posCtr, sizeof(FIELD_RETRIEVAL_HEADER));
  417.     gneBuffer^.preBuf.gneHeader.descriptionLen := posCtr;
  418.  
  419.     dataLen := sizeof(GNE_BUFFER);
  420.     getStatus := BTRVID(
  421.                    B_GET_NEXT_EXTENDED,
  422.                    posBlock1,
  423.                    gneBuffer^,
  424.                    dataLen,
  425.                    keyBuf1,
  426.                    keyNum,
  427.                    client);
  428.  
  429.      writeln('Btrieve B_GET_NEXT_EXTENDED status = ', getStatus);
  430.  
  431.     { Get Next Extended can reach end of file and still return some records }
  432.     if ((getStatus = B_NO_ERROR) or (getStatus = B_END_OF_FILE)) then begin
  433.       writeln('GetNextExtended returned ', gneBuffer^.postBuf.numReturned, ' records.');
  434.       for i := 0 to gneBuffer^.postBuf.numReturned - 1 do begin
  435. {$ifdef ver70}
  436.         dataLen := sizeof(PERSON_STRUCT);
  437.         personRecord := gneBuffer^.postBuf.recs[i].personRecord;
  438.         status := BTRVID(
  439.                     B_INSERT,
  440.                     posBlock2,
  441.                     personRecord,
  442.                     dataLen,
  443.                     keyBuf2,
  444.                     -1,   { no currency change }
  445.                     client);
  446.         if (status <> B_NO_ERROR) then begin
  447.           writeln('Btrieve B_INSERT status = ', status);
  448.           break;
  449.         end;
  450.  
  451. {$else} {Turbo Pascal for Windows 1.5 does not support 'break'}
  452.         if (status = B_NO_ERROR) then begin
  453.           dataLen := sizeof(PERSON_STRUCT);
  454.           personRecord := gneBuffer^.postBuf.recs[i].personRecord;
  455.           status := BTRVID(
  456.                       B_INSERT,
  457.                       posBlock2,
  458.                       personRecord,
  459.                       dataLen,
  460.                       keyBuf2,
  461.                       -1,   { no currency change }
  462.                       client);
  463.         end;
  464.         if (status <> B_NO_ERROR) then begin
  465.           writeln('Btrieve B_INSERT status = ', status);
  466.         end;
  467. {$endif}
  468.  
  469.       writeln('Inserted ', gneBuffer^.postBuf.numReturned, ' records in new file, status = ', status);
  470.       writeln;
  471.     end;
  472.     fillchar(gneBuffer^, sizeof(GNE_BUFFER), #0);
  473.     gneBuffer^.preBuf.gneHeader.currencyConst := 'EG';
  474.   end;
  475.   dispose(gneBuffer);
  476.  
  477.   { close open files }
  478.   keyNum := 0;
  479.   if file1Open = TRUE then begin
  480.     dataLen := 0;
  481.  
  482.     status := BTRVID(
  483.                 B_CLOSE,
  484.                 posBlock1,
  485.                 dataBuffer,
  486.                 dataLen,
  487.                 keyBuf1[1],
  488.                 keyNum,
  489.                 client);
  490.  
  491.     writeln('Btrieve B_CLOSE status (sample.btr) = ', status);
  492.   end;
  493.  
  494.   if file2Open = TRUE then begin
  495.     dataLen := 0;
  496.  
  497.     status := BTRVID(
  498.                 B_CLOSE,
  499.                 posBlock2,
  500.                 dataBuffer,
  501.                 dataLen,
  502.                 keyBuf2[1],
  503.                 keyNum,
  504.                 client);
  505.  
  506.     writeln('Btrieve B_CLOSE status (sample2.btr) = ', status);
  507.   end;
  508.  
  509. { Free Resources }
  510. {$IFNDEF BTI_DOS_16P}
  511.    dataLen := 0;
  512.    status := BTRVID( B_STOP, posBlock1, DataBuffer,
  513.                 dataLen, keyBuf1[1], 0, client );
  514.    writeln( 'Btrieve B_STOP status = ', status )
  515. {$ENDIF}
  516.  
  517. END.
  518.  
  519.