home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d07xx / d0766.lha / ISAM / ISAM.doc < prev    next >
Text File  |  1992-11-21  |  50KB  |  1,055 lines

  1.  
  2.                   ===========================================
  3.                   = ISAM -  for the Commodore (R) Amiga (R) =
  4.                   ===========================================
  5.  
  6.                             ----------------------
  7.                             | Version : 1.01     |
  8.                             | Released: 10/14/92 |
  9.                             ----------------------
  10.  
  11. ISAM Copyright (c) 1992 Scott C. Jacobs / RedShift Software.
  12. All Rights Reserved. GTDR.
  13.  
  14.  
  15.  
  16. ===============================================================================
  17. ===============================================================================
  18. ==                                                                           ==
  19. ==                        PROGRAM LICENSE AGREEMENT                          ==
  20. ==                                                                           ==
  21. ==   REDSHIFT SOFTWARE DISCLAIMS ALL WARRANTIES RELATING TO THIS SOFTWARE,   ==
  22. ==   WHETHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED    ==
  23. ==   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,     ==
  24. ==   AND ALL SUCH WARRANTIES ARE EXPRESSLY AND SPECIFICALLY DISCLAIMED.      ==
  25. ==   NEITHER REDSHIFT SOFTWARE NOR ANYONE ELSE WHO HAS BEEN INVOLVED IN      ==
  26. ==   THE CREATION, PRODUCTION OR DELIVERY OF THIS SOFTWARE SHALL BE LIABLE   ==
  27. ==   FOR ANY INDIRECT, CONSEQUENTIAL, OR INCIDENTAL DAMAGES ARISING OUT OF   ==
  28. ==   THE USE OR INABILITY TO USE SUCH SOFTWARE EVEN IF REDSHIFT SOFTWARE     ==
  29. ==   HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES OR CLAIMS.  IN NO   ==
  30. ==   EVENT SHALL REDSHIFT SOFTWARE'S LIABILITY FOR ANY DAMAGES EVER EXCEED   ==
  31. ==   THE PRICE PAID FOR THE LICENSE TO USE THE SOFTWARE, REGARDLESS OF THE   ==
  32. ==   FORM OF CLAIM.  THE PERSON USING THE SOFTWARE BEARS ALL RISK AS TO THE  ==
  33. ==   QUALITY AND PERFORMANCE OF THE SOFTWARE.                                ==
  34. ==      Some states do not allow the exclusion of the limit of liability     ==
  35. ==   for consequential or incidental damages, so the above limitation may    ==
  36. ==   not apply to you.                                                       ==
  37. ==      This agreement shall be governed by the laws of the United States    ==
  38. ==   of America, State of New York and shall inure to the benefit of         ==
  39. ==   RedShift Software and any successors, administrators, heirs and         ==
  40. ==   assigns.  Any action or proceeding brought by either party against      ==
  41. ==   the other arising out of or related to this agreement shall be brought  ==
  42. ==   only in a STATE or FEDERAL COURT of competent jurisdiction located in   ==
  43. ==   Monroe County, New York.                                                ==
  44. ==   The parties hereby consent to in personam jurisdiction of said courts.  ==
  45. ==                                                                           ==
  46. ==                                                                           ==
  47. ==    This software and the disk(s) on which it is contained is licensed     ==
  48. ==    to you, for your own use.  This is copyrighted software.  You are      ==
  49. ==    not obtaining title to the software or any copyright rights.  You      ==
  50. ==    may not sublicense, rent, lease, convey, modify, translate, convert    ==
  51. ==    to another programming language, decompile, or disassemble the         ==
  52. ==    software for any purpose.                                              ==
  53. ==                                                                           == 
  54. ==    You may make as any copies of this software as you need for back-up    ==
  55. ==    purposes.  You may use this software on more than one computer,        ==
  56. ==    provided that there is no chance it will be used simultaneously on     ==
  57. ==    more than one computer.  If you need to use the software on more       ==
  58. ==    than one computer simultaneously, please contact us for information    ==
  59. ==    about site licenses.                                                   ==
  60. ==                                                                           ==
  61. ==                                                                           ==
  62. ==    REGISTERED VERSIONS of this software may NOT be copied (except as      ==
  63. ==    described above for backup), and may NOT be distributed.               ==
  64. ==                                                                           ==
  65. ==    Individuals may freely copy any SHAREWARE VERSION of the software and  ==
  66. ==    share it with friends and family.                                      ==
  67. ==    Nonprofit groups (including user groups and BBSs) may distribute       ==
  68. ==    copies of the SHAREWARE VERSION.  A fee of not more than US$ 5.00      ==
  69. ==    may be charged to cover disk copying costs.  If the files in a         ==
  70. ==    SHAREWARE VERSION have dates more than a year old, we request that you ==
  71. ==    contact us for a free upgrade to the current SHAREWARE VERSION.        ==
  72. ==    Disk distributors and dealers must have written permission before      ==
  73. ==    selling copies of the SHAREWARE VERSION of this software.  When you    ==
  74. ==    contact us, you will receive a free copy of the latest SHAREWARE       ==
  75. ==    VERSION and you will be placed on our mailing list to receive updates  ==
  76. ==    as they are released.                                                  ==
  77. ==    Disk distributors may charge no more than US$ 10.00 per disk for       ==
  78. ==    copies of this software.  If, as a distributor, you supply copies to   ==
  79. ==    other resellers, the end price to the user may not exceed US$ 10.00.   ==
  80. ==                                                                           ==
  81. ==    Anyone distributing copies of the SHAREWARE VERSION of this software,  ==
  82. ==    whether for profit or as a nonprofit organization, must conform to     ==
  83. ==    the following:                                                         ==
  84. ==       The files [on each disk] may not be modified or adapted in any way. ==
  85. ==       All of the files provided [on the disk] must be distributed         ==
  86. ==       together.                                                           ==
  87. ==       Individual files or groups of files may not be sold separately.     ==
  88. ==       Additional files may be added and this software may be combined on  ==
  89. ==       a disk with other programs.                                         ==
  90. ==       This software may not be represented as anything other than share-  ==
  91. ==       ware, and the shareware concept must be explained in any ad or      ==
  92. ==       catalog that includes this software and on any packaging used to    ==
  93. ==       display the disk.                                                   ==
  94. ==       You must immediatly stop selling/distributing copies of this disk   ==
  95. ==       upon notice from the author or RedShift Software.                   ==
  96. ==                                                                           ==
  97. ===============================================================================
  98. ===============================================================================
  99.  
  100.  
  101.                              ISAM FEATURES/LIMITS
  102.                              --------------------
  103.  
  104. Multiple Keys
  105. Unique/Repeatable Keys
  106. Multi-"user"
  107. Client/Server Design
  108. Fixed-length Records
  109. File/Record Locking (Exclusive/Shared)
  110. Deleted-record-space reclaimed
  111. Minimal code size used per program
  112. Small server size
  113. Resident Library of functions
  114.  
  115. Max. Users             : 4,294,967,296       ( largest unsigned long + 1 )
  116. Max. Open ISAM Files   : 2,147,483,648       ( largest unsigned long / 2 )
  117.  
  118. Max. Number of Keys    :        65,536/file  ( largest unsigned word + 1 )
  119. Max. Key Length        :           499 Bytes ( Keynode Size - 13 )
  120. Min. Key Length        :             1 Byte
  121.  
  122. Max. Number of Records : 4,294,967,296/file  ( largest unsigned long + 1 )
  123. Max. Record Length     : 4,294,967,296 Bytes ( largest unsigned long + 1 )
  124. Min. Record Length     :             4 Bytes ( used in deleted-record-space
  125.                                                reclamation )
  126.  
  127. The above maximum figures are of course limited by available disk space
  128. and/or available memory (and CPU horsepower).
  129. If there is an upper limit on the size of a file, then the above maximum
  130. Record Count/Length figures may, of course, be smaller.
  131.  
  132.  
  133.  
  134. REQUIREMENTS:
  135.   Any Amiga, AmigaDOS (R) V1.2 or higher.
  136.   Any Language that can access Resident Libraries (such as the Amiga system
  137. libraries (Exec/Intuition/DOS/etc)).
  138.   Closest fit: users of Lattice (R) C or SAS/C (R).
  139.  
  140.  
  141.  
  142.  
  143.                                     ====
  144.                                     ISAM
  145.                                     ====
  146.  
  147. WHAT IT IS:
  148.  
  149.   ISAM - Indexed Sequential Access Method - is a method of storing records,
  150. for retrieval in any pre-selected order.  As its name implies, records
  151. are usually stored sequentially in the DATA File, in the order in which they
  152. are received.  A separate file, the INDEX File, is used to store the indices
  153. (usually referred to as "keys") that order the records.  
  154. Together, the data and index files are referred to as an ISAM FILE.
  155.  
  156. A RECORD is a group of related information, stored together.  Each piece
  157. of information is called a FIELD of the record.  For example: an "Employee"
  158. record in a business might have a field for First Name, a field for Last Name,
  159. one for Phone Number, Address, Annual Salary, Social Security Number, etc.
  160. For all records in a file, the same field is in the same position in each
  161. record.
  162.  
  163. KEYS are special areas of a record that hold information by which the records 
  164. will be ordered (kept sorted).  A key is often a single field.
  165. For example: in the above "Employee" record, a likely key would be the 
  166. employee's Last Name field; another key might be the Social Security Number.
  167. The employee's First Name, while an important piece of information, would
  168. probably not be made a key.
  169. Keys do not have to correspond to single fields.  If our "Employee" had
  170. the Last Name stored before the First Name, a key could span both the Last
  171. Name and the First Name fields.  All employees would be ordered as before,
  172. but all those with identical Last Names would themselves be ordered by
  173. First Names.  Also, to save space, a key might consist of just a part of a
  174. field.  If the Last Name field were 30 characters long, a key might be just
  175. 10 bytes long, the first 10 characters of the Last Name.
  176.  
  177. An ITERATION is a sequence of records retrieved in key order.  An iteration
  178. may consist of all of the records in the file, or it may be limited to 
  179. records having keys of one key value; it may consist of a RANGE of records
  180. from one key value to another, or all records whose keys begin with a certain
  181. PREFIX.
  182.  
  183. As implemented, this version of ISAM consists of two main parts: a SERVER and
  184. a RESIDENT (SHARED) LIBRARY.  The server is a background program that does the
  185. actual work of storing/retrieving records.  All programs that need to store/
  186. retrieve records are separate from the server, and contain only references to
  187. the functions called in the library.  The library is small and only contains
  188. enough code to allow communication with the server.
  189. This means that programs using ISAM are no larger than the program object
  190. code itself (not counting, of course, code linked from other libraries). 
  191. The ISAM library is only about 7.5K.
  192. The server occupies 54K, plus a 4K stack, plus dynamically-allocated memory
  193. for each task, file, key, iteration, etc.
  194.  
  195. Multiple programs or tasks (hereafter referred to as "users") may use ISAM
  196. concurrently, and more than one user may have the same ISAM file open at the
  197. same time.
  198. Of course, only one user will have ISAM's attention at any one instant.
  199. Requests that arrive while ISAM is busy will be serviced one at a time,
  200. in the order that they arrive.  Most functions return almost instantan-
  201. eously.
  202.  
  203. Except for record size, and the location and size of each key, ISAM does not
  204. know or care what your record looks like.  All non-key areas of a record
  205. are ignored, and the records themselves are stored/retrieved unaltered.
  206.  
  207.  
  208.  
  209.  
  210.                                    KEYS
  211.                                    ----
  212.  
  213. This implementation of ISAM allows multiple indices (keys).  Each of these
  214. may be unique or repeatable.  A UNIQUE key only allows each possible key value
  215. to appear once in the file.  A REPEATABLE key allows a key value to appear
  216. more than once.  Each key may be ASCENDING (... ,57, 59, 67, 67, 108, ...) or
  217. DESCENDING ( ..., Zebra, Talon, Talon, Mussel, Cadillac, Abacus, ...).  
  218. A Key may have one of 5 types:  integer, floating point, single character, and
  219. two types of text: normal alphbetical order, where case is not significant
  220. ("Abacus" is equivilent to "abacus","aBaCuS","ABAcus", and so forth),
  221. and straight ascii, where case is significant.  Ascii is useful for non-text
  222. keys as well.
  223.  
  224. Each key has a location and a size.  The location is the byte offset from the
  225. beginning of the record.  A key beginning at the start of the record would 
  226. have an offset of zero.
  227.  
  228. Keys are referred to by number.  The first key listed in the Specs File (see
  229. below) is key 0, the next is key 1, and so on, up to key N-1 (if there are
  230. N keys).
  231.  
  232. Keys may overlap each other, partially or completely, and do not have to
  233. correspond to single fields in the record.  For instance, a key could span
  234. a date field and a name field for absent students.  If the key is ascending,
  235. all students absent on a particular day would be grouped together, and for
  236. that day would be grouped alphabetically (A-Z).  A second key could be just
  237. the date, in descending order, so as to order the students from the most
  238. recently absent back to those absent on the first day of school.
  239. NOTE: a key may have only ONE type.  A key that spans several fields of
  240. differing types will NOT act as if each part of the key is handled separately.
  241. An ascii type key that spans a floating point number will not order that part
  242. of the key in floating point order.
  243. Spanning multiple fields is generally only workable for text types (including
  244. single character), and unsigned integers or other groups of bytes which
  245. happen to be ordered left-to-right with the most significant byte on the left
  246. (like unsigned integers, if the above description confuses).
  247.  
  248.  
  249.                                 SPECS FILE
  250.                                 ----------
  251.  
  252. In order for ISAM to be able to manipulate records in an ISAM file correctly,
  253. it must know certain information about the file, records and keys.  This
  254. information is stored in a separate specifications file (or SPECS FILE).
  255. One specs file must exist for each ISAM file, and contains the information for
  256. one type of record.
  257.  
  258. The specs file is an ascii file (use your favorite text editor) with 4 or
  259. more lines in it:
  260.  
  261.    Line #1 : the data  file path/name,  Ex: "work:finances/checks.data"
  262.          2 : the index file path/name,  Ex: "FINANCES:checks.index"
  263.          3 : the record size,           Ex: "126"
  264.          4 : one or more key specification lines (one line per key)
  265.  
  266.  
  267. FILE PATH/NAME
  268. --------------
  269.  
  270. No particular file extension is required for either file.  ".data" and
  271. ".index" are intuitive, but ".harry" and ".sally" would work just the same.
  272. In fact, no extension at all is required.  The above files could be 
  273. "work:finances/checks0" and FINANCES:checks1" if you like.
  274. It is permissible to have the data and index files (and Specs file) on 
  275. different devices.  Say: data file on one floppy, and the index on another;
  276.                          data file on floppy, the index in RAM: (temporarily,
  277.                          of course...), etc.
  278. It is suggested that logical devices be used for paths.  (In the above 
  279. examples, we assume that "FINANCES:" has been assigned "work:finances" if
  280. the user wished to keep both the data and index file in the same directory).
  281. If a logical device is used in the Specs file to designate the files' paths,
  282. then should it become desirable to move the file to another location (say,
  283. RAM:, to speed up a lengthy report), all you need to do is re-"Assign" the
  284. logical device, and no editing of the Specs file is needed.
  285. More importantly, if a logical device is used to specify the location of
  286. the Specs file itself in the program code, should it become necessary to
  287. move the Specs file, the program need not be re-compiled and re-linked.
  288.  
  289.  
  290. RECORD SIZE
  291. -----------
  292.  
  293. The record size must be at least 4 bytes.  The first four bytes of a deleted
  294. record are used to allow ISAM to locate it so its space may be reclaimed
  295. when a subsequent record is stored.
  296.  
  297. When figuring record sizes and key offsets (see below), remember that
  298. the system aligns certain data types on even byte boundaries, and thus
  299. record fields may be offset further in the record than expected, and
  300. the record itself may be larger as a result.
  301. C programmers should use the "sizeof()" function to be sure of the record
  302. size (see example below for Key Offset).
  303.  
  304.  
  305. KEY SPECIFICATION LINE
  306. ----------------------
  307.  
  308. Each key specification line consists of 5 items, each separated by one or
  309. more spaces:
  310.  
  311.   1 : the key offset
  312.   2 : the key length
  313.   3 : the key type
  314.   4 : whether the key is ascending or descending
  315.   5 : whether the key is unique or repeatable
  316.  
  317. Key Offset
  318. ----------
  319.   When figuring offsets, remember that integers, floats, doubles and pointers
  320. are aligned on even addresses, so if, for example, an integer appears to
  321. start at offset 3 (after a 3 character string, for example), it doesn't - it
  322. starts at offset 4.
  323.  
  324.   For C programmers, Lattice/SAS C 5.02 and later revisions contain the
  325. macro "offsetof()" in the header "stddef.h".  This produces record field
  326. offsets.  A small program contining this, along with sizeof() (for figuring
  327. record sizes) and your struct definition, should fairly painlessly determine
  328. the necessary information.
  329. (for those not possessing the above-mentioned file, it contains the following
  330. lines:
  331.  
  332.      -------------------------------------------------------------
  333.         typedef unsigned int size_t;
  334.  
  335.         #define offsetof(type,memb) (size_t)&(((type *)0L)->memb)
  336.      -------------------------------------------------------------
  337.  
  338. (where 'type' is the struct type name and 'memb' the struct field the offset  
  339. of which you're trying to find).
  340.  
  341. Example:  struct Employee {
  342.               int EmpNo;
  343.               char Name[31];
  344.               float Salary;
  345.               char SSNo [11]; /* incl. '-' */
  346.           };
  347.  
  348.           ...
  349.           printf ( "The offset of Salary in the Employee struct is %u.\n",
  350.                    offsetof ( struct Employee, Salary ) );
  351.  
  352.           printf ( "The size of Employee struct is: %d.\n", 
  353.                    sizeof ( struct Employee ) );
  354.           ...
  355. See the file "offsetof.c", and try it with one of your records.
  356.  
  357. Non-C programmers may have to figure record sizes and key offsets "by hand".
  358.  
  359.  
  360. Key Length
  361. ----------
  362.   An integer key can have three lengths:     1, 2, 4.
  363.   A floating point key can have two lengths: 4, 8.
  364.   A character key can have only one length:  1.
  365.   A text/ascii key can be any length (greater than zero)
  366.  
  367.     NOTE: ISAM will know from what is specified here how long the key is;
  368.           and will only store/retrieve that length: therefore, text keys
  369.           do NOT need an extra byte on the end to store a '\0' (you may,
  370.           of course, wish to have one there for other purposes), and there
  371.           is no point in including the '\0' byte in the key length, as this
  372.           would only result in wasted file space.
  373.  
  374. Key Type
  375. --------
  376.   There are 5 types, each specified by a single letter:
  377.      I - integer
  378.      F - floating point (float or double)  (standard IEEE floating point)
  379.      A - ascii (text is case sensitive   - "B" != "b" ).
  380.      T - text  (text is case insensitive - "B" == "b" )
  381.      C - single character (equivilent to type A with length 1 )
  382.  
  383.   Type I should be prefixed by "U" if the integer is unsigned.  Do NOT insert
  384. any space between the U and the I.
  385.      
  386. Keys that are record fields of type:      should be designated as:
  387.     WORD   SHORT   LONG      int                   I
  388.    UWORD  USHORT  ULONG  unsigned int             UI
  389.     float double                                   F
  390.     char                                           C or A
  391.     char[<N>] BYTE[<N>] UBYTE[<N>]                 T or A 
  392.  
  393. Keys that are record fields of type:      may be designated:    or: or: or:    
  394.     BYTE                                           I             C   A   T
  395.    UBYTE                                          UI             C   A   T 
  396. depending on how they are to be used.
  397.  
  398. NOTE: any T or A key is considered to consist of individual UNsigned bytes
  399. (UBYTE).
  400.  
  401.  
  402. Ascending/Descending
  403. --------------------
  404.   There are two possible specification characters:
  405.      A - ascending
  406.      D - descending
  407.  
  408. Unique/Repeatable
  409. -----------------
  410.   There are two possible specification characters:
  411.      U - unique
  412.      R - repeatable
  413.  
  414.   Example:  If date is a key to a Bank Account Transaction File, it would need
  415.             to be repeatable, as otherwise there could be only one transaction
  416.             per day.
  417.             The account number in the Bank Account File, however, would have
  418.             to be a unique key, or several accounts could have the same
  419.             account number.
  420.  
  421.  
  422. Example Specs File (don't include the dashed lines in your specs files):
  423.  
  424. ----------------------------------------------------------------
  425. FINANCES:checks.data
  426. FINANCES:checks.index
  427. 126
  428. 0 8 T A R
  429.           0 10 T A U
  430. 34      4                           UI D                      R
  431. ----------------------------------------------------------------
  432. The data file is checks.data, and is on a disk (or logical device) named
  433. FINANCES.
  434.  
  435. The index file is checks.index, and is on the same disk/device as the data
  436. file.
  437.  
  438. The record length is 126 bytes.
  439.  
  440. Key #0 starts at record offset 0, is 8 bytes long, type T, is ascending,
  441. and key values may repeat.
  442.  
  443. Key #1 also starts at record offset 0, is of length 10, also is type T,
  444. also is ascending, but is unique.
  445.  
  446. Key #2 starts at record offset 34, is of length 4, is of unsigned integer
  447. type, is descending, and its key values may repeat.
  448.  
  449.  
  450. In the above example, the first key line should be your model.  The second
  451. and third key lines are included to show that the spacing may vary.
  452. The second key line doesn't start at the first character position of the line
  453. (fine) and the third key line has multiple and varied spacing (great).  Note,
  454. however that, as stated above, the U (unsigned) qualifier for the I (integer)
  455. type CANNOT be separated from the type by any spaces.
  456. Note that keys number 0 and 1 (the first and second key lines) overlap.
  457.  
  458.  
  459.  
  460. PAD BYTES:  (Note well!)
  461. ----------
  462.  
  463. If a key spans several fields in a record, there may be PAD BYTES in the
  464. record between one or more of the fields (due to data alignment, as 
  465. described above).
  466. The presence of pad bytes may be determined by finding the offset of each
  467. field included in the key (using offsetof(), as shown above), and comparing
  468. each with the offset/length of the previous field.
  469.   If there are pad bytes in the key, be sure to include them when specifying
  470. the key length.
  471.   It is possible that, by rearranging the order of the fields in the record,
  472. that pad bytes may be eliminated.  This will also reduce the size of the
  473. record, which is always a good idea.
  474. For example, the struct below, which has pad bytes where indicated, could
  475. be rearranged as shown on the right:
  476.  
  477.          struct Employee {             struct Employee{
  478.             char  Name [31];              char  Name [31];
  479.                        <-----pad byte     char  SSN [9];
  480.             float Salary;                 char  Phone [7];
  481.             char  SSN [9];                char  NickName[11];
  482.                        <-----pad byte     float Salary;
  483.             int   Age;                    int   Age;
  484.             char  Phone[7];               WORD  DaysLate; 
  485.                        <-----pad byte  }
  486.             WORD  DaysLate;
  487.             char  NickName[11];
  488.          }
  489. The pad bytes could also be eliminated by adding or subtracting 1 to the 
  490. length of each character array (making each an even number of bytes long).
  491.  
  492.   If re-arrangement is not possible, then along with specifying a longer
  493. key size, the following must also be done:
  494.  
  495.     Each pad byte must be EXPLICITLY SET to a specific value (zero, probably)
  496.     each time the key value is set or changed in the record, as otherwise
  497.     is is uncertain just WHAT value will be stored there, and if that value
  498.     varies from record to record, it will wreck the ordering.
  499.  
  500. Ex.  An ascending key composed of the following fields of a record:
  501.                ...
  502.                char[5] firstname;
  503.                int     age;
  504.                char[4] lastname;
  505.                ...
  506.      would have a pad byte between the first two fields listed.
  507.      If two key values have the same first two fields, and a differing
  508.      third, their values could look like this:
  509.  
  510.                char[5]       int  char[4]
  511.                -------       ---  -------
  512.                "Henry"  24   27   "Ford"
  513.                "Henry"   9   27   "Fork"
  514.  
  515.      Ignoring the pad byte, one would expect the first
  516.      key value to be ordered BEFORE the second ("Henry/27/Ford" coming
  517.      before "Henry/27/Fork"), but because of the pad byte values,
  518.      it will actually be stored AFTER it ("24" coming after "9").
  519.  
  520.      If the struct were changed to:
  521.                ...
  522.                char[5] firstname;
  523.                byte    pad;
  524.                int     age;
  525.                char[4] lastname;
  526.                ...
  527.      and 'pad' set to zero each time, the ordering would then be as
  528.      expected.
  529.  
  530.  
  531.  
  532. Once a specs file is created, the corresponding ISAM file (data and index
  533. files) can then be created.  An ISAM file MUST be created before it can be
  534. used.  Once the record structure has been decided upon, keys selected, and
  535. specs file edited and saved, invoke the command "CreateISAMFile", with the
  536. specs file as the only paramter (see ISAM.AutoDocs for details).
  537.  
  538.  
  539.  
  540.  
  541.                          RUNNING THE ISAM SERVER
  542.                          -----------------------
  543.  
  544.   First of all, make a backup copy of the ISAM distribution disk (or the disk
  545. onto which you copied the shareware file(s), and work with that, putting the
  546. original disk away in a safe place.
  547. NEVER use the original disk of ANY software you purchase as your working
  548. copy!
  549.  
  550.   Since ISAM is a server for the entire computer, it is run only once during
  551. each time the computer has been booted, unless it is intentionally removed.
  552. As the program occupies little memory, it will probably not need to be
  553. removed for that reason.
  554. Also, since it is designed to be run only once, storing it in RAM: prior to
  555. use, or trying to make it resident would only waste memory. 
  556.  
  557.  
  558. FROM THE CLI / SHELL:
  559. ---------------------
  560.  
  561.   The server is the file named simply "ISAM".
  562.   From any directory, type: "<path>ISAM" (where <path> is wherever you've got
  563. the server stored - even from a copy of the original floppy disk).
  564. If you put it in the sys:c directory, or if the directory where you have
  565. stored it has been added to the search path (with the AmigaDOS "Path" command),
  566. then specifying a path is unnecessary.
  567. It is also unnecessary if you have changed directories (AmigaDOS "CD" command)
  568. to the directory containing the ISAM file(s).
  569.  
  570. Ex.  "ISAM"
  571.      "work:servers/ISAM"
  572.      "COMMANDS:ISAM"  where COMMANDS: is an assigned logical device (see
  573.                       the AmigaDOS "Assign" command).
  574.      "df0:ISAM"       where the backup copy of the original disk is in df0:.
  575.  
  576.  It has been designed to run in the background, so prefacing the command
  577. with "run " is unnecessary.
  578. A large requester will appear describing ISAM, and unless there's a problem,
  579. "ISAM Installed." will appear in the message area.  The single button
  580. centered below the message area will contain the word "Continue", unless
  581. there's a problem, when the word "Abort" will appear instead.  Press the
  582. button.  That's all there is to it.
  583. The CLI/Shell prompt will re-appear (you may need to press <return>, though),
  584. and other commands may then be entered.
  585. (The requester will reappear when the server is being shut down, with the
  586. phrase "ISAM Shutting Down." in the message area.)
  587.  
  588.   If you wish to eliminate the requester that appears when ISAM is being
  589. installed or shut down, simply add a parameter to the "ISAM" command.  The 
  590. composition of this parameter is ignored.  The requester will STILL appear
  591. if an error occurs when installing ISAM.
  592.  
  593.   If the default stack of 4K (4096) should prove insufficient, see "FROM
  594. THE WORKBENCH" below for directions on how to increase it (it CANNOT be
  595. changed from the CLI/Shell).  The stack size, and the largest stack amount
  596. used so far are some of the things output from the ISAM Status Report
  597. command/function (see ISAM.AutoDocs).
  598.  
  599. To remove ISAM, type: "<path>ISAMShutDown", where, as above, <path> is 
  600. wherever the program is stored.   A small requester will appear, giving
  601. you a chance to abort the shutdown.  Click on "NO" to abort, "YES" to
  602. shut down ISAM.  To eliminate the "Are you sure..." requester, add a
  603. parameter to the above command (the composition of the parameter is ignored).
  604.  
  605.  
  606. FROM THE WORKBENCH
  607. ------------------
  608.  
  609.  Open whatever drawer in which you have the ISAM server stored (or the
  610. disk icon of a copy of the original disk).  Several icons will appear.
  611. Open the "ISAM" icon.  The same requester described in "FROM THE CLI" will
  612. appear, and the same action is required.
  613.  
  614. To remove ISAM, open the ISAM icon that has "ISAM" with a "no smoking"-type
  615. slash across it.  The same requesters described in "FROM THE CLI" will
  616. appear, and the same actions are required.
  617.  
  618. To change the stack size, it is necessary to first select the ISAM icon, and
  619. then choose the "Information" Workbench menu item.  This must be done before
  620. installing ISAM in memory.
  621.  
  622. If you wish to eliminate the requester that appears when ISAM is being
  623. installed or shut down, add "QUIET" to the tooltypes box (click on "New",
  624. type the word "QUIET", press <return>, and click on "Save"). The requester
  625. will STILL appear if an error occurs when installing ISAM.
  626.  
  627. To change the stack size, find the box next to the word "Stack", change it
  628. to the desired size, press return, and then click on the "Save" gadget.
  629. If you find (through using the ReportISAMStatus command/function) that the
  630. stack used figure is close to the stack size, then you know that you need
  631. to increase the stack size.
  632. Setting it too low can cause the machine to crash, either immediately upon
  633. installation, or later during a complicated operation.  This is true of
  634. any program, not just ISAM.
  635.  
  636.  
  637.  
  638.  
  639.                           USING THE ISAM FUNCTIONS
  640.                           ------------------------
  641.  
  642. In general, the programmer need only:
  643.  
  644.     1.* #include the prototype header file for the ISAM functions (this 
  645.         also pulls in the error #define file for the error names, and the
  646.         file of function #pragmas);
  647.     2.  Copy the Resident Library to the system LIBS: directory;
  648.     3.  Open the ISAM Resident Library prior to using any ISAM functions;
  649.     4.  use whatever ISAM functions are necessary in the program;
  650.     5.  Close the ISAM library when finished using the ISAM functions.
  651.  
  652. Any C dialect that cannot handle prototypes with variable names should use the
  653. prototype file ending in "nn.c" (NoNames).  If it cannot handle prototypes at
  654. all, just use the error-define file, and add to it the #defines for OK and
  655. ALLFILES from the prototype file.
  656.  
  657. If your language cannot handle #pragma statements, or cannot handle #pragmas
  658. for functions with more than 4 parameters, then comment out the line in the
  659. prototype header file #include'ing the #pragma file, and add the file
  660. "ISAMStub.Lib" to the list of libraries your linker scans.
  661.  
  662. The prototype file uses the Logical Device "MYLIB:" in pulling in #include
  663. files for errors and #pragmas.  Either "Assign" it where you want, or replace
  664. it with your accustomed assign.
  665.  
  666. * Non-C programmers will need to adapt these guidelines, and the instructions
  667. that follow, to the way their language handles defined names, and Resident
  668. Libraries.
  669.         
  670.  
  671.  
  672.                             FUNCTION COMMENTS
  673.                             -----------------
  674.  
  675. (See ISAM.AutoDocs for a description of the functions and their parameters.)
  676.  
  677.  
  678.     - Most functions return values of type "long".  The value 0L (#define
  679.       name "OK") is returned to indicate a successful completion, and a non-
  680.       zero result for failure.  These non-zero Error Codes are sometimes
  681.       merely Condition Codes.  For example, ReadNextISAMRecord returns
  682.       ERROR_NO_MORE_RECORDS when there are no more records in an iteration,
  683.       a condition expected to occur eventually.
  684.  
  685.       For most Non-Read functions, the following is a good template to use:
  686.  
  687.         if ( (ErrorCode = <function_name> ( <parm1>, <parm2, ...)) != OK )
  688.           {
  689.             ...error handling code...
  690.           }
  691.  
  692.       For read/store/modify/etc., where there are multiple likely condition
  693.       codes, a switch makes more sense:
  694.  
  695.         ErrorCode = <function_name> ( <parm1>, <parm2, ...);
  696.         switch ( ErrorCode )
  697.         {
  698.           case ERROR_NO_SUCH_RECORD :  ...for ReadUnique...
  699.           case ERROR_DELETED_RECORD :  ...for Modify/Delete/ReadISAMRecord
  700.  
  701.               ...etc...    
  702.  
  703.           case OK : break;
  704.  
  705.           default : ...handle unexpected errors here...
  706.         }
  707.       See FileConvert.c, test.c, and Books.c in the example directory
  708.       for sample code.
  709.  
  710.     - The ISAM Resident Library must be opened prior to any call to an
  711.       ISAM function.  Failure to do this will cause AT LEAST the program
  712.       to crash.
  713.       The Library must be closed prior to your program's termination.
  714.  
  715.       Use the following code fragments (in C):
  716.  
  717.           struct Library *ISAMBase;
  718.          ...
  719.           if ( (ISAMBase = OpenLibrary ( "isam.library", 0 )) == NULL )
  720.             {
  721.               ...handle error - library didn't open - CAN'T CALL FUNCTIONS...
  722.             }
  723.          ...
  724.           CloseLibrary ( ISAMBase );  /* ONLY if the earlier Open succeeded */
  725.  
  726.       NB: "ISAMBase" and "isam.library" are CASE-SENSITIVE, and MUST be
  727.       used as shown.
  728.  
  729.     - OpenISAMFile / CloseISAMFile.  OpenISAMFile must be called prior to
  730.       use of any other ISAM function that needs to access a particular file.
  731.       Open creates certain user-specific file memory structures that Close
  732.       later releases.  If a file being opened is not already in use (by
  733.       another user), other (non-user-specific) memory structures are created,
  734.       and if no other user has this file open when Close is called, those
  735.       structures are released as well.
  736.  
  737.     - Every function that is ISAM-file-specific (that is, operates on one
  738.       specific ISAM file), must supply an ID that distinguishes that file
  739.       from other files.
  740.       This ID is known as an ISAM Handle, and is returned to you as a 
  741.       parameter of OpenISAMFile.  The actual contents of this handle are
  742.       unimportant.  Just create a variable to hold the handle, and provide
  743.       a pointer to it when calling Open.
  744.       The ISAM Handle returned will never be zero (0L).
  745.  
  746.     - Every function that deals with a specific record refers to a record ID
  747.       known as the Record Number.  StoreISAMRecord returns this number in
  748.       a parameter (as does ReadNextISAM(Record|Key)), and the other record-
  749.       specific functions (including ReadISAMRecord) require this number to
  750.       be supplied as a parameter.
  751.       Zero (0L) is a valid record number.
  752.  
  753.     - Records may be read in several ways.  Single records may be read by
  754.       ReadISAMRecord or ReadUniqueISAMRecord.  Groups of records are read by
  755.       first calling one of three functions used to set up an ISAM ITERATION
  756.       (multiple-record retrieval).  This is then followed by repeatedly
  757.       calling the function ReadNextISAMRecord until no more records match
  758.       the desired criteria.
  759.  
  760.     - The "Record" parameter, in all Read functions, points to memory
  761.       belonging to the calling program.  It is NOT a pointer to memory that
  762.       ISAM owns.  The calling program must set aside the memory itself, either
  763.       as a simple variable declaration, or as memory the program has asked
  764.       DOS to allocate for it.  In effect, the program calling Read is saying
  765.       "HERE is where I want ISAM to put the record."
  766.  
  767.     - The function CountISAMRecords will return the number of records that
  768.       meet the criteria defined when an iteration is set up.  The iteration
  769.       remains set up ("SetUp..." does not need to be called again.).
  770.  
  771.     - The function ReadNextISAMKey will return ONLY the KEY VALUE of the
  772.       next record - not the record itself.  This is useful for those cases
  773.       when the key information alone is sufficient, and the rest of the
  774.       record is not currently needed.  Like ReadNextISAMRecord, the KeyValue
  775.       parameter is a pointer to memory belonging to the calling program.
  776.  
  777.     - Setting up an iteration for the same key where one is already set up
  778.       is NOT considered an error.  The old iteration is merely cancelled,
  779.       and the new one set up in its place.
  780.  
  781.     - Several iterations on the same file may be going on at the same time,
  782.       so long as each is iterating on a different key.  
  783.  
  784.     - When an iteration is underway, (in the middle of repeatedly calling
  785.       ReadNext...), do NOT Store/Modify/Delete any records, and do not 
  786.       ReadUnique with the same key that the iteration is using.  This
  787.       will destroy the sequence you have set up.
  788.       Creating/ReIndexing/Deleting/Closing the same file are obviously
  789.       bad ideas if you want to keep the iteration intact.
  790.       Other operations should be safe, including ReadISAMRecord.
  791.  
  792.     - The ISAM Server does the actual opening and closing of the data 
  793.       and index files when a request to Open/CloseISAMFile is made.
  794.       Therefore, Opening an ISAM file does NOT add to any "maximum files
  795.       open" limitation of the program calling ISAM.
  796.  
  797.     - A record is always stored/modified/deleted in the data file BEFORE
  798.       its keys are added/removed to/from the index file.  This is done
  799.       because, there being more operations necessary to store keys, (and thus
  800.       more time needed as well), it is more likely that if a problem occurs,
  801.       it  will happen during the key-storing phase.  Since the record is
  802.       already stored (or deleted), ReIndex'ing the file should be all that
  803.       is necessary to restore things to normal.
  804.  
  805.     - When a program ends, explicitly UnLock'ing locked records, and
  806.       UnLock'ing/Close'ing open files is NOT necessary.
  807.       Any locked records will be UnLock'ed when a file is Close'd,
  808.       and any open files will be UnLock'ed/Close'd when the program
  809.       calls CloseLibrary.  If a program may end without traversing the
  810.       section of code where CloseLibrary is situated, it is suggested that
  811.       an exit trap be set up (if one isn't already) and the CloseLibrary
  812.       call inserted there.
  813.       
  814.     - When ISAM is shut down, all Open files will be UnLock'ed and Close'd
  815.       (so if any program bombs without calling CloseLibrary, all will be
  816.       taken care of when ISAM shuts down). 
  817.       Any user functions still waiting in line to be served will return with
  818.       ERROR_ISAM_SHUTTING_DOWN.
  819.  
  820.     - CountISAMRecords, DeleteISAMRecords, and ReIndexISAMFile, unlike most
  821.       other ISAM functions, are not "instantaneous."  
  822.       It is therefore STRONGLY recommended that they be forbidden where there
  823.       are simultaneous users, as all other users will appear to "hang" while
  824.       the function executes.  Count... may be rendered safer by using 
  825.       CountMax, but even for a reasonably small file, some delay is
  826.       inevitable.
  827.  
  828.     - ReIndexISAMFile CANNOT be used to effect a change of record size or
  829.       structure (fields moved, added, or removed).  To do that, a new ISAM
  830.       file must be Created with the new specifications (make SURE the data
  831.       and index file names are DIFFERENT in the new specs file!).  Then, a
  832.       file conversion program must be written to transfer the old ISAM file's
  833.       records to the new file.  This can be easily done by the following
  834.       technique:
  835.         Open the old ISAM file and the new ISAM file;
  836.         ReadISAMRecord the old file's records sequentially; copy
  837.         the old record information to the new record, make any
  838.         changes needed to the new record, and StoreISAMRecord the
  839.         new record to the new file; Close both ISAM files;  Once ASSURED of
  840.         a successful conversion, the old file may be Deleted.
  841.  
  842.       FileConvert.c is a template file showing in more detail how
  843.       the above technique may be done.
  844.  
  845.  
  846.  
  847.  
  848.                                ISAM COMMANDS
  849.                                -------------
  850.  
  851. The following commands, except where noted, require the SpecsFileName to be
  852. entered on the command line, just as a string containing the SpecsFileName
  853. is required as a parameter for the function.
  854. Except where noted, where FUNCTIONS of the same name exist, the commands
  855. accomplish the same thing, and require the same input.
  856.  
  857. The commands may be found in the "c" directory of the distribution disk/file.
  858.  
  859. If using a version of AmigaDOS prior to 2.0x, the commands MUST be entered
  860. from the CLI/Shell.  If 2.0x (or later) is used, the commands may also be
  861. run from the Workbench:  when you Open the tool icon bearing the name of
  862. the desired command, a window will open allowing you to enter the command
  863. and parameters just as if you were entering them from a CLI/Shell.  Anything
  864. that would ordinarily be printed in the CLI/Shell, will be re-directed to
  865. an "Output Window."  If there is a lot of information to print, it may scroll
  866. off the window.  If that is the case, it is recommended that the output be
  867. redirected to a file (or printer), so that the file may be later viewed in
  868. its entirety with a text editor or wordprocessor.
  869. (To be able to view the tool icons of the c directory with Workbench 2.0x
  870. (or higher), the menu option "View By: Icon"/"Show: All Files" must be 
  871. selected for the open "c" directory (drawer).)
  872.  
  873.  
  874.  DeleteISAMFile -
  875.  
  876.  
  877.  CreateISAMFile -
  878.  
  879.  
  880.  ReIndexISAMFile
  881.                 - The presence or absence of a second parameter (one
  882.                 following the SpecsFileName) determines whether a Counter
  883.                 window will be displayed or not.  The actual composition
  884.                 of this second parameter is ignored.
  885.                 
  886.  ISAMFileReport - 
  887.                 This program looks at the Specs and Index file and reports
  888.                 on the  vital statistics of the ISAM file in question: names
  889.                 of data and index files, the record size, record count
  890.                 keycount, and the key offset/size/type/etc. for each key.
  891.                 It also reports on whether there are currently deleted
  892.                 records in the file.
  893.                 This command does not require ISAM to be installed to work.
  894.  
  895.  
  896.  ISAMWhy        - ALL | ErrNo [,ErrNo [,ErrNo [,ErrNo...]]]
  897.  
  898.                 If 'ALL' is entered on the command line, a list of all ISAM
  899.                 error numbers, along with #define strings, is typed to
  900.                 the console.  Re-direct this command to a file or printer
  901.                 for a permanent list.
  902.                 The command also accepts multiple error numbers on the
  903.                 command line, printing a descriptive line for each.
  904.                 This command does not require ISAM to be installed to work.
  905.  
  906.  
  907.  SeqToISAM      - <Sequential File Name> <record size>
  908.                 a record-sequential file (a file in which fixed-size records
  909.                 are stored one after the other, with nothing in between) 
  910.                 is modified to the ISAM data file format (a single byte is
  911.                 added prior to each record).
  912.                 Any record whose first four bytes are "FREE" will be marked
  913.                 as deleted. (ISAM will later reclaim their space as records 
  914.                 are subsequently Store'd).
  915.                 The modified file will be stored under the given name with
  916.                 ".NEWFILE" appended.  The record-sequential file will be left 
  917.                 unchanged.
  918.                 This command does not require ISAM to be installed to work.
  919.  
  920.  
  921.  ISAMPresent    - <suppress message>
  922.                 This program is designed to be used in a script file.
  923.                 Since ISAM is a background process (and would be unlikly
  924.                 to be shut down in any case), it does not have a return code.
  925.                 However, it is still necessary to know if ISAM is "out there"
  926.                 in order to run programs that require its presence.
  927.  
  928.                 Therefore, the program ISAMPresent may be used to determine
  929.                 ISAM's presence/absence.
  930.  
  931.                 The message: "ISAM is present" (or "not present") will be
  932.                 printed.  Return Code '5' will be returned if it couldn't
  933.                 find ISAM, and return code '0' if it does.
  934.  
  935.                 Ex:  ISAMPresent q
  936.                      if WARN
  937.                        echo "Uh-oh!  ISAM is not installed."
  938.                        quit
  939.                      else
  940.                        prog1
  941.                        prog2
  942.                        ...
  943.                      endif
  944.                 The message will be suppressed if there is a parameter
  945.                 present on the command line.  The actual composition of the
  946.                 parameter is ignored.
  947.                 This command does not require ISAM to be installed to work.
  948.                 Obviously.
  949.  
  950.  
  951.  ReportISAMStatus
  952.                 - 
  953.  
  954.  
  955.  
  956.  
  957.                         NOTES ON FILE/RECORD LOCKING
  958.                         ----------------------------
  959.  
  960.   ISAM files and individual records may be locked to limit or deny access to
  961. other users; a file may be locked at the time it is opened, and a record at
  962. the time it is read or stored, and either may be done at any other time as
  963. well.
  964. Locks come in two "flavors": exclusive and shared.  If a file is locked with
  965. an exclusive lock, neither it nor any of its records may be read, changed,
  966. or locked by another user.  Likewise, an individual record locked with an
  967. exclusive lock may not be accessed by another user.
  968. A file that is locked with a shared lock may be read by another user, but not
  969. changed or locked.   Records that are locked with a shared lock (and records
  970. in a file that is shared locked) likewise may only be read, not changed.
  971. For our purposes, "change" includes attempting to modify or delete an exist-
  972. ing record, or store a new one.
  973.  
  974.  
  975. DEADLOCK
  976. --------
  977.  
  978. Since files and records may be locked, the situation may occur that two differ-
  979. ent users having different files/records locked may each request something
  980. that the other has locked.  If each keeps trying until it gets what it wants,
  981. they will each wait forever.  This is known as deadlock.  There are three
  982. strategies that will help avoid deadlock.
  983. First, instead of continuously looping until the request is (or in this case, 
  984. isn't) granted, back off.  Inform the user that the record/file desired is
  985. locked and to please try again later.  The user then may wait, do something
  986. else, end the program, etc.  He isn't dead in the water.  Secondly, if several
  987. programs each use two or more of the same ISAM files, make sure that they all
  988. attempt to open them in the same order: A then B then C.  This way it is im-
  989. possible to deadlock:  Program 1 opens/locks A and B; Program 2 then tries to 
  990. get A and fails.  True, he is locked out of A, BUT he doesn't have anything
  991. locked himself - so deadlock cannot occur.  Even if he has a try-until-succeed
  992. loop, it's not deadly.  Program 1 will eventually quit and he will then succeed.
  993. Thirdly, any time you get a lock error, unlock EVERYTHING you've got locked
  994. and begin over.  This avoids deadlock, but is often difficult (not to mention 
  995. time-consuming) to code.
  996. Strategy 2 is often not practical for Record locking (different programs may
  997. use different keys to get at the same records - hence different orders).
  998. Remedy 1 or 3 would then be better bets for record-locking.
  999.  
  1000.  
  1001.  
  1002.  
  1003.                                 EXAMPLES
  1004.                                 --------
  1005. TEST
  1006. ----
  1007.  
  1008. The file "test", in the examples subdirectory, is a test program showing
  1009. the use of most of the ISAM functions in manipulating the ISAM file 
  1010. "Employee".  (Employee is found in the data subdirectory).
  1011. Test may be run from the Workbench only with AmigaDos 2.0x or higher
  1012. ("show all files" and open the tool icon "test".  You'll need to enlarge
  1013. the Output Window).  Otherwise the CLI/shell must be used.  There
  1014. are no parameters.
  1015.  
  1016. The source code for test (test.c) is included for C-language programmers, 
  1017. to show sample function calls and error/condition code handling.
  1018. Feel free to change it and/or snip bits of it for your own use.
  1019. Non-C-programmers should find it useful as well, although obviously any
  1020. code appropriated will need to be modified to fit the constraints of their
  1021. language.
  1022.  
  1023. Prior to running test, the Logical Device "DATA:" will need to be assigned
  1024. to wherever the specs/data/index files for Employee have been stored.
  1025.  
  1026. The locking/unlocking features can only be tested if test is run from more
  1027. than one CLI/shell simultaneously (since obviously the user locking the file/
  1028. records may access the files/records he/she locked).
  1029.  
  1030.  
  1031. BOOKS
  1032. -----
  1033.  
  1034. The file "Books", in the examples subdirectory, is a working application that
  1035. allows the user to keep an inventory of his books, and to list those books
  1036. in many different orders (8 actually; applications would not ordinarily have
  1037. 8 keys on the same file, but Books does!).  
  1038. Books operates on the ISAM file "Books", located in the data subdirectory.
  1039.  
  1040. Like test, Books needs to have the logical device "DATA:" assigned.
  1041.  
  1042. The source code for Books is included as well, and may be appropriated for
  1043. your own use, just like "test".
  1044.  
  1045.  
  1046.  
  1047.  
  1048. -------------------------------------------------------------------------
  1049.  
  1050. Amiga is a registered trademark of Commodore-Amiga, Incorporated.
  1051. AmigaDOS is a trademark of Commodore-Amiga, Incorporated.
  1052. Commodore is a trademark of Commodore Electronics Limited.
  1053. Lattice is a registered trademark of Lattice, Inc.
  1054. SAS/C is a registered trademark of SAS Institute Inc.
  1055.