home *** CD-ROM | disk | FTP | other *** search
/ Boston 2 / boston-2.iso / DOS / PROGRAM / DATABASE / PCFILE3 / TECHINFO < prev    next >
Text File  |  1993-12-01  |  11KB  |  287 lines

  1. TECHINFO - Technical information on the file formats used by PC-File+ 3.0
  2.  
  3. This information is provided for programmers who wish to use PC-File+
  4. databases with their own programs--BASIC, Turbo Pascal, "C" or other
  5. languages.
  6.  
  7. PC-File+ makes an excellent "Front End" program for other systems
  8. which you might develop.  You can use PC-File+ to handle the file
  9. maintenance functions, and concentrate your efforts on the rest of the
  10. system.
  11.  
  12. File Formats
  13.  
  14. The file "filename.DTA" (where "filename" is the name you gave the
  15. database), is the main data file.  Each field of the record is stored
  16. in a fixed length format (the length that you defined for it) and
  17. padded on the right if necessary with blanks.  The fields appear in
  18. the record in the same order that they are accessed in PC-File+.
  19.  
  20. Deleted records which have not been re-used have a slash "/" in the
  21. first position of the record.  A carriage return character (HEX 0D)
  22. marks the end of each record.  A special record containing a backslash
  23. "\" as its first character is stored at the end of the database to
  24. mark the end of the file.  All records in the file are the same
  25. length.
  26.  
  27. Records are usually stored in the same sequence in which they were
  28. originally entered.  New records will be added to the end of the file
  29. unless there are deleted records.  If there are deleted records,
  30. PC-File+ will write the new record in place of a deleted one.  The
  31. sort command does not resequence the data portion of the database; it
  32. only affects the index.
  33.  
  34. The file "filename.INX" is the index file for your database.  There is
  35. one index record for each data record, including deleted records.
  36. Each index record is composed of the first two bytes from every data
  37. field, followed by a two-byte (binary format) pointer to the relative
  38. record number of the record in filename.DTA.
  39.  
  40. There is also a "filename.HDR" file for each database.  This is a
  41. standard ASCII file.  The first line is similar to this:
  42.  
  43. PCF+3;00123,Sample database
  44.  
  45. The first part of this line identifies this file as a PC-File+ 3.0
  46. file.  The next available unique number appears after the semicolon.
  47. The database description, which may be blank, appears after the comma.
  48.  
  49. After the database description line, there are two lines for each
  50. field in the database.  The first line is the field name followed by
  51. its optional mask, constant and/or calculation.  The field name always
  52. takes up the first 12 bytes.  The mask, constant and/or calculation
  53. can start at any point thereafter.
  54.  
  55. The second line contains the field length, starting row, starting
  56. column, and window size of the field.  These are stored in ASCII
  57. character format, and are separated by commas.  An example:
  58.  
  59. ZIP_CODE    :09--:
  60. 10,9,12,10
  61.  
  62. This entry is for a field named ZIP_CODE which has a mask of :09--:
  63. Its field length is 10, screen row is 9, screen column is 12, and
  64. window display size is 10.  Since the field length and window size are
  65. the same, this field is not a "window field".
  66.  
  67. There is one more part of the header file.  It's a "picture" of the
  68. data entry screen.  This portion was not always created by earlier
  69. versions of PC-File+, but is always created by PC-File+ 3.0.  Each
  70. line in the picture starts with the "|" character.  This section is
  71. quite long -- up to 1680 bytes in length.
  72.  
  73. Sample Programs
  74.  
  75. Here are sample BASIC and C programs to show you how to process the
  76. Index and Data records in your PC-File+ 3.0 database.  Note that
  77. these are very limited programs; we are providing them only as 
  78. working demonstrations of how to access PC-File+ database files.
  79.  
  80. Please note: Due to limitations in BASICA and GWBASIC, this BASIC
  81. program is NOT able to process databases containing more than 
  82. 32,767 records.
  83.  
  84. ______________________________________________________________________
  85.  
  86.  10 '+-----------------------------------------------------+
  87.  20 ':         PC-File+   Sample BASIC program.            :
  88.  40 '+-----------------------------------------------------+
  89.  60 '*  This program reads a database (named "SAMPLE")
  90.  70 '*  in sequence by the Index.
  91.  80 '*  For each record read, a line is printed.
  92. 100 '*
  93. 110 '* The sample database was defined as follows:
  94. 120 '*    NAM          20
  95. 140 '*    CITY         12
  96. 150 '*    STATE         2
  97. 160 '*    ZIP           5
  98. 180 '*              = (39) total lngth of all fields
  99. 200 '* The lngth of an index record in this database:
  100. 210 '*    2 * (number of fields) + 2.   2 * 4 + 2 = 10.
  101. 240 '* The lngth of a data record in this database:
  102. 250 '*    (Lngth of data fields) + 1.  39 + 1 = 40
  103. 320 '
  104. 360 INX.LEN = 10  'this length was calculated above
  105. 370 DTA.LEN = 40  'this length was calculated above
  106. 380 '
  107. 390 '.......... OPEN FILES FOR PROCESSING ..................
  108. 410 OPEN "SAMPLE.INX" AS #1 LEN=INX.LEN
  109. 420 FIELD#1,2 AS NM$,2 AS CI$,2 AS ST$,2 AS ZI$,2 AS PT.DTA$
  110. 430 '  Each of the above fields contains the 1st 2 bytes of
  111. 440 '    the corresponding field in the data file.
  112. 450 '  The last 2 bytes of the above index rcrd are a binary
  113. 460 '    pointer to the relative rcrd no. in the data file.
  114. 480 OPEN "SAMPLE.DTA" AS #2 LEN=DTA.LEN
  115. 490 FIELD #2, 20 AS NAM$, 12 AS CITY$, 2 AS STATE$,5 AS ZIP$
  116. 500 '
  117. 510 '.....FOR EACH INX RCRD, GET CORRESPONDING DTA RCRD.....
  118. 530 GET #1                         'Get nxt INX rcd.
  119. 540 IF LEFT$(NM$,1) = "/" THEN 530 'Bypass deleted rcrd.
  120. 550 IF LEFT$(NM$,1) = "\" THEN 600 'End of file.  "    "
  121. 560 POINTER = CVI(PT.DTA$)         'Get ptr into DTA file.
  122. 570 GET #2,POINTER                 'Random get DTA record.
  123. 580 LPRINT NAM$;" ";CITY$;" ";STATE$;" ";ZIP$
  124. 590 GOTO 530                        'Loop until end file.
  125. 600 '
  126. 610 '..... PROCESSING IS COMPLETE. SHUT DOWN .............
  127. 630 CLOSE                             'Close all files
  128. 640 END                               'Leave the program
  129.  
  130. ______________________________________________________________________
  131.  
  132.    /*  Sample C program
  133.  
  134.        This program was compiled with Microsoft C 5.1.  Note that you 
  135.        may have to change the #include statements for other compilers.
  136.  
  137.        This program reads a PC-File+ 3.0 database (named "SAMPLE")
  138.        in sequence by the index.  For each record read, a line
  139.        is printed on the printer.
  140.  
  141.        The SAMPLE database is defined as follows:
  142.  
  143.            Name        20
  144.            City        12
  145.            State        2
  146.            Zip          5
  147.                     = [39] total length of data fields
  148.  
  149.        The length of an index record in this database is:
  150.            2 * (number of fields) + 2      -->   2 * 4 + 2 = 10
  151.        The length of a data record in this database is:
  152.            Length of the data fields + 1   -->   39 + 1 = 40
  153.  
  154.     */
  155.  
  156. #include <stdio.h>
  157. #include <string.h>
  158. #include <ctype.h>
  159. #include <io.h>
  160. #include <fcntl.h>
  161.  
  162. #define  namelen   20
  163. #define  citylen   12
  164. #define  statelen   2
  165. #define  ziplen     5
  166. #define  numflds    4
  167. #define  inxlen     numflds * 2 + 2
  168. #define  dtalen     1 + namelen + citylen + statelen + ziplen
  169.  
  170.   static int dtafile;             /* data file handle */
  171.   static int inxfile;             /* index file handle */
  172.   static int fldlen[numflds];     /* array for field lengths */
  173.   struct db {                     /* structure for the sample database */
  174.          char name[namelen];
  175.          char city[citylen];      /* This structure will need to be   */
  176.          char state[statelen];    /* modified for different databases */
  177.          char zip[ziplen];
  178.   } sample;
  179.   union {
  180.          char dtastring[dtalen];  /* Length of dtastring will need to */
  181.          struct db sample;        /* be changed for different databases */
  182.   } rcd;
  183.  
  184.   main()
  185.   {
  186.     register unsigned datarecno;
  187.                  char inxstring[inxlen+1];
  188.  
  189.     initialize();
  190.  
  191.     inxfile = open("SAMPLE.INX",O_RDWR|O_BINARY);
  192.     dtafile = open("SAMPLE.DTA",O_RDWR|O_BINARY);
  193.  
  194.     for (  ;  ;  ) {
  195.          read(inxfile,inxstring,inxlen);    /* read an index record */
  196.          if (inxstring[0] == '\\')          /* end of file */
  197.              break;                            /* stop processing */
  198.          if (inxstring[0] == '/')           /* deleted record */
  199.              continue;                         /* skip deleted record */
  200.          datarecno = inxptr(inxstring);     /* resolve index pointer */
  201.          getrcd(datarecno);                 /* retrieve data */
  202.          printrcd();                        /* print data */
  203.      }
  204.  
  205.      close(inxfile);
  206.      close(dtafile);
  207.   }
  208.  
  209.  
  210.   /*.................. initialize ..............*/
  211.   static initialize()
  212.   {
  213.     fldlen[0] = namelen;
  214.     fldlen[1] = citylen;
  215.     fldlen[2] = statelen;
  216.     fldlen[3] = ziplen;
  217.   }
  218.  
  219.   /*.................. inxptr ..............*/
  220.   static inxptr(string)
  221.      char *string;
  222.   {
  223.      union {
  224.          unsigned binx;
  225.          char     charx[2];
  226.      } inx;
  227.  
  228.      /* The last two characters of an index record are a binary
  229.         pointer to the data record in the DTA file.  This routine
  230.         will determine the binary pointer given the index string,
  231.         and will return the pointer to the data record. */
  232.  
  233.      inx.charx[0] = string[inxlen - 2];
  234.      inx.charx[1] = string[inxlen - 1];
  235.      return(--inx.binx);
  236.   }
  237.  
  238.   /*.................. getrcd ...............*/
  239.   static getrcd(recno)
  240.      unsigned int recno;
  241.   {
  242.      register long offset;
  243.      register  int x;
  244.  
  245.      x = dtalen;
  246.      offset = (long)recno * (long)x;
  247.      lseek(dtafile,offset,0);                   /* seek the record */
  248.      read(dtafile,rcd.dtastring,dtalen-1);      /* read the record */
  249.   }
  250.  
  251.   /*.................. printrcd ................*/
  252.   static printrcd()
  253.   {
  254.      register int  len;
  255.               char scratch[dtalen+numflds+3];
  256.  
  257.      len = build_output(scratch);
  258.      write(4,scratch,len);               /* printer handle == 4 */
  259.   }
  260.  
  261.   /*.................. build_output ............*/
  262.   static build_output(string)
  263.      char *string;
  264.   {
  265.     register int x;
  266.     register int y;
  267.              int z;
  268.  
  269.     /* This routine will move the data for one field into the string
  270.        variable, add a space, move the data for the next field into
  271.        the string variable, add a space, etc.  After all fields have
  272.        been moved into the string variable, carriage return and
  273.        line-feed characters will be appended to the end of the string. */
  274.  
  275.     x = y = z = 0;
  276.     for (x = 0; x < numflds; x++) {   /* loop for number of fields */
  277.          for (y = 0; y < fldlen[x]; y++,z++)  /* loop for field length */
  278.               string[z] = rcd.dtastring[z - x];  /* move data */
  279.          string[z++] = ' ';           /* add a space after the field */
  280.     }
  281.     string[z++] = '\r';               /* append carriage return */
  282.     string[z++] = '\n';               /* append line feed */
  283.     return(z);                        /* return length of string */
  284.   }
  285.  
  286. ______________________________________________________________________
  287.