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

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