home *** CD-ROM | disk | FTP | other *** search
/ Eagles Nest BBS 8 / Eagles_Nest_Mac_Collection_Disc_8.TOAST / Developer Environments / TurPasDBTlbx / TP-Database Toolbox / Access Samples / TADemo.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-12-11  |  14.3 KB  |  438 lines  |  [TEXT/TPAS]

  1. (*********************************************************************)
  2. (*                  Turbo Pascal Database Toolbox                    *)
  3. (*                       For the Macintosh                           *)
  4. (*            Copyright (C) 1987 Borland International               *)
  5. (*                     Toolbox version: 1.0                          *)
  6. (*                                                                   *)
  7. (*            Turbo Access High-Level Demonstration Program          *)
  8. (*                                                                   *)
  9. (*        Purpose: Shows how to implement a sample database using    *)
  10. (*                 the Turbo Access low-level calls.                 *)
  11. (*                                                                   *)
  12. (*********************************************************************)
  13.  
  14. (*********************************************************************)
  15. (*              TADemo - Configuration for compilation               *)
  16. (*                                                                   *)
  17. (*    Follow these steps in order to compile TADemo.pas:             *)
  18. (*                                                                   *)
  19. (*    1.  Copy TAccess.unit and TAccess.RSRC from the Turbo Access   *)
  20. (*        folder into the folder or disk that contains TADemo.pas.   *)
  21. (*                                                                   *)
  22. (*    2.  Bring the source for TAccess.unit into the Turbo Pascal    *)
  23. (*        integrated environment.                                    *)
  24. (*                                                                   *)
  25. (*    3.  Modify the $I include file directive to this syntax:       *)
  26. (*        {$I TADemo.const}                                          *)
  27. (*                                                                   *)
  28. (*    4.  Compile TAccess.unit to disk.                              *)
  29. (*                                                                   *)
  30. (*    5.  Bring the TADemo.pas source file into the Turbo Pascal     *)
  31. (*        environment.                                               *)
  32. (*                                                                   *)
  33. (*    6.  Run TADemo in memory or compile to disk.                   *)
  34. (*                                                                   *)
  35. (*    For further reference, see pages 34-39 of the Turbo Pascal     *)
  36. (*    Database Toolbox Owner's Handbook.                             *)
  37. (*                                                                   *)
  38. (*********************************************************************)
  39.  
  40. Program TADemo;
  41. {$R TAccess.RSRC} { Contains Turbo Access error messages }
  42. {$U TAccess}
  43. uses 
  44.  {If a compiler error occurs here, Turbo Pascal cannot find the TAccess
  45.   unit. You must first compile this unit to this disk (or folder if using
  46.   HFS) before compiling HiTADemo. See the top of this file for detailed
  47.   instructions.
  48.  }
  49.   
  50.   MemTypes, QuickDraw, OSIntF, ToolIntf, PackIntf, TAccess;
  51.  
  52. {$I TADemo.types}
  53.  
  54. const
  55.   DataFileNm  = 'Customers.data';
  56.   IndexFileNm = 'Customers.index';
  57.  
  58. (**************************************************************)
  59. (*  Global variable are declared here.                        *)
  60. (**************************************************************)  
  61. var
  62.   CustFile : DataFile;
  63.   CodeIndx : IndexFile;
  64.   Customer : CustRec;
  65.  
  66. (***********************************************************************)
  67. (*  Utility procedures which can be called from all other procedures   *)
  68. (***********************************************************************)
  69. function UpCase(ch : char): char; 
  70. { Returns the upper case equivalent of ch } 
  71. inline 
  72.    $301F, { UpCase MOVE.W (SP)+,D0 ; GetCh }
  73.    $0C40,
  74.    $0061, { CMP.W #'a',D0 ; skip if not lower case }
  75.    $6D0A, { BLT.S @1 }
  76.    $0C40,
  77.    $007A, { CMP.W #'z',D0 }
  78.    $6E04, { BGT.S @1 }
  79.    $0440, 
  80.    $0020, { SUB.W #$20,D0 }
  81.    $3E80; { @1 MOVE.W D0,(SP) }
  82.  
  83. function Confirmed : boolean;
  84. var
  85.   Response : char;
  86. begin
  87.   repeat
  88.     Response := UpCase(ReadChar);
  89.     if not (Response in ['Y','N']) then
  90.       SysBeep(1);
  91.   until Response in ['Y','N'];
  92.   Confirmed := Response = 'Y';
  93.   Writeln;
  94. end; { Confirmed }
  95.  
  96. procedure Pause;
  97. var
  98.   ch : char;
  99. begin
  100.   Writeln;
  101.   Write(' Press any key to continue . . .');
  102.   ch := ReadChar;
  103. end; { Pause }
  104.  
  105. procedure Abort(Message : string);
  106. { Reports error to user then halts }
  107. begin
  108.   GotoXY(1, 24);
  109.   Write(^G, Message, ', Hit any key to halt.');
  110.   repeat until KeyPressed;
  111.   Halt;
  112. end;
  113.  
  114. procedure OpenDataFile(var CustFile : DataFile;
  115.                            Fname: String;
  116.                            Size : integer);
  117. { Open a Turbo Access data file if it exist, otherwise create it. }                       
  118. begin
  119.   OpenFile(CustFile, fname, Size);
  120.   if not OK then
  121.     MakeFile(CustFile,fname,Size);
  122.   if not OK then
  123.     Abort('Could not create the data file' + FName);
  124. end;  { OpenDataFile }
  125.  
  126. procedure InputInformation(var Customer : CustRec);
  127. { Obtain customer information from the user to put in the data base. }
  128. begin
  129.   Writeln;
  130.   Writeln(' Enter Customer Information ');
  131.   Writeln;
  132.   with Customer do
  133.   begin
  134.     CustStatus := 0;
  135.     Write('Customer code: '); Readln(CustCode);
  136.     Write('Entry date   : '); Readln(EntryDate);
  137.     Write('First name   : '); Readln(FirstName);
  138.     Write('Last name    : '); Readln(LastName);
  139.     Write('Company      : '); Readln(Company);
  140.     Writeln('Address ');
  141.     Write('   Number & Street   : '); Readln(Addr1);
  142.     Write('   City, State & Zip : '); Readln(Addr2);
  143.     Write('Phone     : '); Readln(Phone);
  144.     Write('Extention : '); Readln(PhoneExt);
  145.     Write('Remarks   : '); Readln(Remarks1);
  146.     Write('Remarks   : '); Readln(Remarks2);
  147.     Write('Remarks   : '); Readln(Remarks3);
  148.   end;
  149. end; { InputInformation }
  150.  
  151. procedure RebuildIndex(VAR CustFile: DataFile;
  152.                        VAR CodeIndex: IndexFile);
  153. { Rebuild index file based on existing data files. }                   
  154. var
  155.   RecordNumber : LongInt;
  156. begin
  157.   MakeIndex(CodeIndex, IndexFileNm,
  158.             SizeOf(Customer.CustCode)-1,NoDuplicates);
  159.   for RecordNumber := 1 to FileLen(CustFile) - 1 do
  160.   begin
  161.     GetRec(CustFile,RecordNumber,Customer);
  162.     If Customer.CustStatus = 0 then
  163.       AddKey(CodeIndex,RecordNumber,Customer.CustCode);
  164.   end
  165. end; { RebuildIndex }
  166.  
  167. procedure OpenIndexFile(var CodeIndx : IndexFile;
  168.                             Fname    : String;
  169.                             KeySize  : integer;
  170.                             Dups     : integer);
  171. {  Setup index file -- open if exists, otherwise create it }                           
  172. begin
  173.   OpenIndex(CodeIndx, Fname,KeySize,Dups);
  174.   if not Ok then
  175.     MakeIndex(CodeIndx, Fname, KeySize, Dups);
  176.   if not Ok then
  177.     Abort('Could not create the index file ' + Fname);
  178. end; { OpenIndexFile }
  179.  
  180. procedure DisplayCustomer(Customer: CustRec);
  181. { Place the customer information on the screen. }
  182. begin
  183.   with Customer do
  184.   begin
  185.     Writeln;
  186.     WriteLn('   Code: ',CustCode,'    Date: ',EntryDate);
  187.     Writeln('   Name: ',FirstName,' ',LastName);
  188.     WriteLn('Company: ',Company);
  189.     Writeln('Address: ',Addr1);
  190.     Writeln('         ',Addr2);
  191.     Writeln('  Phone:',Phone,' ext. ',PhoneExt);
  192.     WriteLn('Remarks: ',Remarks1);
  193.     Writeln('         ',Remarks2);
  194.     WriteLn('         ',Remarks3);
  195.   end;
  196. end; { DisplayCustomer }
  197.  
  198. procedure FindCustomer(var CustFile: DataFile;
  199.                        var CodeIndx: IndexFile );
  200. {   Find customer based on customer code (exact match)    }                     
  201. var
  202.   RecordNumber : LongInt;
  203.   SearchCode   : CodeStr;
  204.  
  205. begin
  206.   Write('Enter the Customer code: '); ReadLn(SearchCode);
  207.   FindKey(CodeIndx,RecordNumber,SearchCode);
  208.   if OK then
  209.   begin
  210.     GetRec(CustFile,RecordNumber,Customer);
  211.     DisplayCustomer(Customer);
  212.   end
  213.   else
  214.     Writeln('A record was not found for the key ',SearchCode);
  215. end { FindCustomer };
  216.  
  217. procedure SearchCustomer(var CustFile: DataFile;
  218.                          var CodeIndx: IndexFile );
  219. {  Search customer based on customer code (Partial match) }                         
  220. var
  221.   RecordNumber : LongInt;
  222.   SearchCode   : CodeStr;
  223.  
  224. begin
  225.   Write('Enter the Partial Customer code: '); ReadLn(SearchCode);
  226.   SearchKey(CodeIndx,RecordNumber,SearchCode);
  227.   if OK then
  228.   begin
  229.     GetRec(CustFile,RecordNumber,Customer);
  230.     DisplayCustomer(Customer);
  231.   end
  232.   else
  233.     Writeln('A record was not found greater than the key ',SearchCode);
  234. end; { SearchCustomer }
  235.  
  236. procedure NextCustomer(var CustFile: DataFile;
  237.                        var CodeIndx: IndexFile );
  238. {  Next customer based on customer code }                      
  239. var
  240.   RecordNumber : LongInt;
  241.   SearchCode   : string[15];
  242. begin
  243.   NextKey(CodeIndx,RecordNumber,SearchCode);
  244.   if OK then
  245.   begin
  246.     GetRec(CustFile,RecordNumber,Customer);
  247.     Write('The next customer is : ');
  248.     DisplayCustomer(Customer);
  249.   end
  250.   else
  251.     Writeln('The end of the database has been reached.');
  252. end; { NextCustomer }
  253.  
  254. procedure PreviousCustomer(var CustFile: DataFile;
  255.                            var CodeIndx: IndexFile);
  256. { Previous customer based on customer code }                          
  257. var
  258.   RecordNumber : LongInt;
  259.   SearchCode   : CodeStr;
  260. begin
  261.   PrevKey(CodeIndx,RecordNumber,SearchCode);
  262.   if OK then
  263.   begin
  264.     GetRec(CustFile,RecordNumber,Customer);
  265.     Write('The previous customer is : ');
  266.     DisplayCustomer(Customer);
  267.   end
  268.   else
  269.     Writeln('The start of the database has been reached.');
  270. end; { PreviousCustomer }
  271.  
  272. procedure ListCustomers(var CustFile: DataFile);
  273. { Access the customer records sequentially  -- no index files.
  274.   Try rewriting this routine using index files. } 
  275. var
  276.   NumberOfRecords,
  277.   RecordNumber    : LongInt;
  278. begin
  279.   NumberOfRecords := FileLen(CustFile);
  280.   Writeln('                   Customers  ');
  281.   Writeln;
  282.   for RecordNumber := 1 to NumberOfRecords - 1 do
  283.   begin
  284.     GetRec(CustFile,RecordNumber,Customer); 
  285.     if Customer.CustStatus = 0 then { If valid record }
  286.       DisplayCustomer(Customer);
  287.   end;
  288. end; { ListCustomers }
  289.  
  290. procedure AddCustomer(var CustFile: DataFile;
  291.                       var CodeIndx: IndexFile);
  292. { AddCustomer inserts records into the data file and keys into the 
  293.   index file. }                    
  294. var
  295.   RecordNumber    : LongInt;
  296.   TempCode        : CodeStr;
  297. begin
  298.   repeat
  299.     InputInformation(Customer);
  300.     TempCode := Customer.CustCode;
  301.     FindKey(CodeIndx,RecordNumber,TempCode);
  302.     If not OK then
  303.     begin
  304.       AddRec(CustFile,RecordNumber,Customer);
  305.       AddKey(CodeIndx,RecordNumber,Customer.CustCode);
  306.       Write('Add another record? ');
  307.     end
  308.     else
  309.       Write('Duplicate code exists. Try another code? ');
  310.   until not Confirmed;
  311. end; { AddCustomer }
  312.  
  313. procedure DeleteCustomer(var CustFile: DataFile;
  314.                          var CodeIndx: IndexFile);
  315. { DeleteCustomer accepts the customer code and deletes data and key info. }                       
  316. var
  317.   RecordNumber    : LongInt;
  318.   CustomerCode    : CodeStr;
  319. begin
  320.   repeat
  321.     Write(' Enter code of customer to be deleted: '); Readln(CustomerCode);
  322.     FindKey(CodeIndx,RecordNumber,CustomerCode);
  323.     if OK then
  324.     begin
  325.       DeleteKey(CodeIndx,RecordNumber,CustomerCode);
  326.       DeleteRec(CustFile,RecordNumber);
  327.       Write('Delete another record? ');
  328.     end
  329.     else
  330.       Write('Customer code was not fould. Try another code? ');
  331.   until not Confirmed;
  332. end; { DeleteCustomer }
  333.  
  334. procedure UpdateCustomer(var  CustFile: DataFile;
  335.                          var  CodeIndx: IndexFile);
  336. { UpdateCustomer shows a customer and then allows reentry of information. }                         
  337. var
  338.   RecordNumber    : LongInt;
  339.   CustomerCode    : CodeStr;
  340.  
  341. begin
  342.   repeat
  343.     Write('Enter code of customer to be updated: ');
  344.     Readln(CustomerCode);
  345.     FindKey(CodeIndx, RecordNumber, CustomerCode);
  346.     if OK then
  347.     begin
  348.       GetRec(CustFile,RecordNumber,Customer);
  349.       DisplayCustomer(Customer);
  350.       InputInformation(Customer);
  351.       PutRec(CustFile,RecordNumber,Customer);
  352.       If CustomerCode <> Customer.CustCode Then
  353.       begin
  354.         DeleteKey(CodeIndx,RecordNumber,CustomerCode);
  355.         AddKey(CodeIndx,RecordNumber,Customer.CustCode);
  356.       end;
  357.       Write('Update another record? ');
  358.     end
  359.     else
  360.       Write('Customer code was not found. Try another code? ');
  361.   until not Confirmed;
  362. end; { UpdateCustomer }
  363.  
  364.  
  365. (*******************************************************************)
  366. (*                          Main menu                              *)
  367. (*******************************************************************)
  368. function Menu: char;
  369. var
  370.   action: char;
  371. begin
  372.   ClearScreen;
  373.   GotoXY(1,3);
  374.   Writeln('   Enter Number or First Letter');
  375.   Writeln;
  376.   Writeln(' 1)  List Customer Records ');
  377.   Writeln(' 2)  Find a Record by Customer Code ');
  378.   Writeln(' 3)  Search on Partial Customer Code ');
  379.   Writeln(' 4)  Next Customer');
  380.   Writeln(' 5)  Previous Customer');
  381.   Writeln(' 6)  Add to Customer Database ');
  382.   Writeln(' 7)  Update a Customer Record ');
  383.   Writeln(' 8)  Delete a Customer Record ');
  384.   Writeln(' 9)  Rebuild Index files ');
  385.   Writeln(' 0)  Exit ');
  386.   Writeln(' ');
  387.   Action := ReadChar;
  388.   Writeln;
  389.   Menu := UpCase(action);
  390. end { menu };
  391.  
  392. procedure CleanUp;
  393. { Called before termination of the program }
  394. begin
  395.   CloseIndex(CodeIndx);
  396.   CloseFile(CustFile);
  397. end; { CleanUp }
  398.  
  399. procedure SetUpDatabase;
  400. begin
  401.   OpenDataFile(CustFile, DataFileNm,SizeOf(CustRec));
  402.   OpenIndexFile(CodeIndx,IndexFileNm,
  403.                 SizeOf(Customer.CustCode)-1,NoDuplicates);
  404.   TAErrorProc := @CleanUp;
  405.   { Set up fatal error handler so it will close the database files. }
  406. end; { SetUpDatabase }
  407.  
  408. (***********************************************************************)
  409. (*                            Main program                             *)
  410. (***********************************************************************)
  411. var
  412.   Finished: Boolean;
  413. begin
  414.   Finished := false;
  415.   SetUpDatabase;
  416.   repeat
  417.     case Menu of
  418.       '1','L': ListCustomers(CustFile);
  419.       '2','F': FindCustomer(CustFile,CodeIndx);
  420.       '3','S': SearchCustomer(CustFile,CodeIndx);
  421.       '4','N': NextCustomer(CustFile,CodeIndx);
  422.       '5','P': PreviousCustomer(CustFile,CodeIndx);
  423.       '6','A': AddCustomer(CustFile,CodeIndx);
  424.       '7','U': UpdateCustomer(CustFile,CodeIndx);
  425.       '8','D': DeleteCustomer(CustFile,CodeIndx);
  426.       '9','R': begin 
  427.                  CloseIndex(CodeIndx);
  428.                  RebuildIndex(CustFile,CodeIndx);
  429.                end;
  430.       '0','E': Finished := true;
  431.       otherwise Write('Choose 0-9: ');
  432.     end; { case }
  433.     if not Finished then
  434.       Pause;
  435.   until Finished;
  436.   CleanUp;
  437. end.
  438.