Files
sibo-playground/docs/3-03 ISAM Reference 2.10_djvu.txt
T

1862 lines
55 KiB
Plaintext
Raw Normal View History

2026-07-06 18:30:29 +01:00
ISAM REFERENCE
Version 2.10
February 3, 1995
(C) Copyright Psion PLC 1990-95
All rights reserved. This manual and the programs referred to herein are copyrighted works of Psion
PLC, London, England. Reproduction in whole or in part, including utilization in machines capable of
reproduction or retrieval, without express written permission of Psion PLC, is prohibited. Reverse
engineering is also prohibited.
The information in this document is subject to change without notice.
Psion and the Psion logo are registered trademarks, and Psion, Psion MC, Psion HC, Psion Series 3,
Psion Series 3a and Psion Workabout are trademarks of Psion PLC.
TopSpeed is a registered trademark of Clarion Software Corporation. IBM, IBM XT and IBM AT are
registered trademarks of International Business Machines Corp. Microsoft and MS-DOS are registered
trademarks of Microsoft Corporation. Apple and Macintosh are registered trademarks of Apple Computer
Inc. VAX and VMS are registered trademarks of Digital Equipment Corporation. Brief is a registered
trademark of Underware Inc. Psion PLC acknowledges that some other names referred to are registered
trademarks.
Ea Se eee
Contents
OO eee
DV TREODUCHON os. cre ciacsesdcztestsavis besksace sabteeentce ce ic thee es ca i 1
OVER VICW Pres cite ccc vapciu part tetne sacra see trt narescet em vennescattes ieitins dike one vessdaice 1
MPS TSAIM NR ALY wigiie ven tersestode Gaavaaabsiavenssniavedincy ss wersaye Secseevoearcceucokiacheeks 1
DBF IGS aed drauu gar tha nis det ane oe di dewey oenueatgtiad tenes Grateiunew ne ules honttcat Nt 2
PICS arsdeecceantd veunasarcwacmecuransoisnagteusias seve canueee paises ioc Seales: Staab ected 2
NUMBER OR FECORES oo ceca. ailoc feel awesseopeissavvapiaveréuecs taibesctbiacteesGshealdleccs 2
Bethe ee ES: 3550 sins wands cocuesuestn fa catpeiaaile Uened tamale noes davik ov caus tstdewonc wie orasc oe 2
BIOCK DUNERIMG i cnac acces anstyes cuyinassuestiea Madeausccauan innate es ded cuhaesiontiecses ee 2
ICY CES CHE OM ernst ceceatecsatovissanasdelsadendsastaccs dbversducenccesageiner foxtevente osha. 2
DIZELOMBaEG MNOS ic ascaveusdacsadeacensetarasrsuaiiooievdediduamesbestiuree eicanacaniclncs 3
Interface to the ISAM library.............sscssssscecceccssseccccessccccusessceseeceecscccesees 3
BOAO NG ION Esai neecestans avsseccnensaguatvcsewaseoss iiaceebataoaeetsvaeeickecuicenicet 3
Creating am (SAM :OB)OCE si. 5cc.iscsnssasteecisadeiWevevasevisesss aide keaseaeavedeaesiseeécck 4
Calling (ISAM MUNCLONS 4.iscissye2sedoacasuedsaseerdeweesecedansdssesesahuocdcvercecsa covers 4
Destroying the ISAM object..............sssssssccssssscceceseccccenesecsececsueecceceuces 4
UV PUG ASE: si seca lane vcuuwetded osanes des adynnsvauseuremettleauon secon Meraeloecate cic ccs 4
EXAMPIG PROGQHANTS « wosascredececslsoueiaavecadatheuade nee nckass ws aeer sea tee laieclbeccsseecaninl 5
Building a complete (dense) index.............cssssscccsssssccssssecececsesseueceneesees 5
Building a selective (sparse) index .............csssescccssecccsasscececcescccecceseeese 7
@ ISOM FUNCTIONS sve sestes seo choc 05 Secudeutce se buscdvscaudbasduvacbecvuaceacnnssd sata lice hedabeseae ek 9
GE MSN al MU MCHONS vases connec cu seiisenladeubuaycatedonsouauueedisoves ss cusSaceavlncsiea oo licetaas 9
Initialise an ISAM object (O_IS_INIT)...........ssssssecesscscccceecececccaueseccesecees 9
Destroy an ISAM object (O_IS DESTROY) ............ccccecsesessessssecececeesesees 10
Set the field definition (O_IS SET FIELDDEF) .............cccccsscccccesesseuseneees 10
Get the field definition (O_IS_GET_FIELDDEF) Sevestecdaied sida oeeRhuecdacvesieekeest 11
Set the key definition (O_IS SET _KEYDEPF) .............ccccsscsssseecccceeesecccuees 11
Get the key definition (O_IS_GET KEYDEP).............ccccsesssseccccesesessueecees 13
Put a value into a field (fom IS PUT CSRIEUD) 5 in sbavecsuedessscecdsscssevesceccetestacies 13
Get a value from a field (Oi IS GET GEIBUID). cccsisanseescecincsacoansovsseosantoeecs 13
Get the type of a field (0 _[S GET TYPE) au incnetecnrenecmestntsesetireecuoeroeieces 14
Get the address of the record buffer (0. IS GET_RBUP)..............cccccesees 14
Set the radix for number conversion (0 _| AS “SET RADIX) eiseaaiWwanstanvasettaxns 14
Set the text format for DOUBLES (O_ IS SET _ RADIX) daacaduece sbaveteveeauasaess 14
Add ancventry (O° 1S ADD) ssccs er cecccais sts Sons Cissvepwes doves sevavievec bevdeccecetovecess 14
Erase an entry (O IS ERASE).......ccsssccsssssccssscsssscsssssscersonecsececesssessens 14
Update an entry (O_IS_UPDATE)..............cccsseceeseccccsscceccercecseuececeeevecs 15
ata HIG FUMCNONS tise ssranii scp aes terebeeaiasdaxedtagd touted aleuumcvensuenteccteeccni dfs 15
Open a data file (O_IS DOPEN)..............ccccsssccssstceseconsesccenseneccessceeeesce 15
Flush data file buffers {0 IS DFELUSH) ic scctsacsckiv cesta dtsnsberscxevseovacdescs vases 15
Get sizeof data Tile (0! IS SIZE) 0. sis.ssccsstersssivacnssavenerenesassieccdeieedsc se 15
Read first data record (O_IS DFIRST)...........cccccssescsessescecstessecsccescesscs 15
Read next data record (O_ Is” DN EXT) idavedeves dense de deeocsedeeses csavadetectictis 16
Index file FUNCTIONS ...........ccccvesseccccccscccoretsnscseresstesceetaccsecesconsevscececeecceccee 16
Open: aniimdex: (OISIOREN) esl 5Ge inf Gscws toecsshasasinea sau celeeesadeneaaceeer ghee ecs 16
Close an index (O_ [SISO SEP cicaesterncaveastyt.temadlen eae basal ea, 16
Flush index file buffers (OCIS MBLUSH) 5 secs fea iee sicnadeavesseidebdeecnedeaathersoes 17
Set and get index flags (O_ Is” SIREAGS)ocacsetets cates docuisicdvsntsevese Sensesheons 17
Specify a filter method (O_ is PANELISTS estbiadt 2s coe bt os ssi hind vaneatee tocnaeannee: 17
Specify a duplicates method (om ISSIDUP) 23. oss tacdesrvceacs vavanand each catceeeivee 18
Bulle an: index: (OIS | IRONED). s.0 ies idcubeeexdssvacecanederecvesacadecaverlinetlccacesecs 18
Build an index from sorted data (OMS *IQBUIED) 2. cits seccovedecesssaciceeees ecees 18
Add an index entry (O_ ISBIA DD) Seth nett se create ante ata, «St ee 19
ISAM REFERENCE
i
Erase an index entry (O_IS_IERASE).............cssscsssscccevscorsvecesesecesscconees 19
Erase all index entries (O_ is wa IERASEALL) wok. ssscscccecatintees .cmresceterreeees 19
Get the number of index entries (OBISTIGOUNT) ciciiniressccnteecces ceStesceieees 20
Get size of an index file (O_IS | ISIZE) T Sawa case cdces salyseuieess se coe acbeascMeereeneeee 20
Find a record using an index (ORISAIFIND) 6.25.0 c.uscucsstih ce ee cee: 20
Read next indexed record (O_ is_ _INEXT) G Saline deen ve sovaatedaw asus eoeeeieteceeanete 21
Read previous indexed record (O4 ISSIBACK) & ia. cckscc codes cei acteatettectseoes 21
Read first indexed record (O_IS IFIRST) Le teet eats te cectatrauacat et ecetscaseeereones 21
Read last indexed record (O_ 1s ILAST) SCOOT TET ESTE EC CCLEER SET eee 21
Read current indexed record (O_ ISSIGURRENT) oa cs escscaseisdccccscenstesceuests« 21
CHAPTER 1
INTRODUCTION
SSS_—— SSS ee eae ee a ee ey
Overview
This manual describes the Indexed Sequential Access Method (ISAM) dynamic library for SIBO
machines (HC, $3, S3a and MC).
The ISAM library provides a powerful set of functions for rapid and efficient access of Database files
(DBF files). Such files consist of multiple records containing one or more structured fields. They can be
created, maintained and accessed from OPL programs and database applications on the HC, S3, S3a and
MC (see the Database Files chapter of the PLIB Reference manual).
The ISAM library uses B-tree index files to provide rapid and efficient indexed and sequential access to
DBF files. It is the most widely used form of index file simply because it is the most efficient general
method of accessing database files. In brief, B-tree index files minimise the number of disk accesses per
retrieval - manipulating data already in memory is much faster than accessing the disk - whilst ensuring a
well balanced index i.e. no one retrieval requires an inordinately large number of disk accesses (for
details see for example Structures, by Michael J.Folk and Bill Zoellick, published by Addison-Wesley
Publishing Company).
The ISAM library
The ISAM library functions provide the following:
= Fast record retrieval on a key. For example a DBF file can be searched for all records containing
the key "Smith".
= Very little degradation of the speed of retrieval as the number of records increases - even large
DBF files can be manipulated with relative ease.
= Sequential access to records that are ordered by the key (that is, next, back, first and last). For
example a record with key "Smalley" that precedes a current record with key "Smith" can be
rapidly found using the 0_I1s_1BACK function.
= The ability to see a selection of the records in the file (by constructing a selective or Sparse
index). For example all records containing the key "Smith" can be viewed.
= Access to record fields with automatic conversion from numbers to text (and vice-versa) if
required.
= The ability to make powerful key definitions that facilitate access ordered on combinations of up
to eight fields. For example all records with key fields "Smith" and "Slough" can be found with
"Smith" given the higher priority.
= The opening of up to 31 index files for a DBF file at any one time. For example, a DBF file
containing customer details can have two indexes, one for searching on customer occupation and
related details and the other for searching on customer location and related details.
= The adding, erasing, and updating of records with the appropriate updating of all associated
index files carried out automatically thus greatly facilitating the task of maintaining an index.
ISAM REFERENCE
SSS SS ee ee ee er Ty
DBF files
Fields
The following field types are available:
BYTE, UBYTE, WORD, UWORD, LONG, ULONG, DOUBLE, STRING.
However, if compatibility with existing OPL or PLIB DBF functions is required, the field types must be
restricted to:
WORD, LONG, DOUBLE, STRING
Number of records
The maximum number of records that can be handled by the PLIB DBF functions is 65534.
However, in ISAM the maximum is 2147483647.
SSS SSS a a a ee ea eee
B-tree index files
The ISAM library uses B-tree index files to provide much more powerful indexed and sequential access to
DBF files than would otherwise be possible.
In general B-tree index files should not be constructed or maintained on a Flash SSD. There is however
no reason not to read an index file from Flash SSD.
Block buffering
B-tree index files are block structured files having a block size of 1SAM_BLOCK_SIZE (512) bytes (in the
literature these blocks are sometimes referred to as pages - the terms are interchangeable).
Index files are read using a least-recently-used (LRU) block buffering scheme - blocks that are repeatedly
accessed are kept in memory (typically these are blocks near the root of the B-tree index). LRU block
buffering has such an impact on the performance of the B-tree algorithm that it is not reasonable to do
without it.
The ISAM library implements a fixed-size LRU block pool per process regardless of the number of open
index files. The size is fixed by calling the ISAM function o_1s_1Nn1T and specifying zero causes the
default of 20 blocks (10K bytes) to be used. If more than one ISAM object is created, the same block
pool is used; if a new size is specified in 0_!s_INIT, it is ignored if there are any index files still open.
The new size is used once all of the original index files are closed.
The LRU block pool is implemented in an external memory segment and does not, therefore, detract
from the process data segment. The segment name will be BLKSnnnn.BLK where nnnn is the process ID in
hex.
Key description
A key consists of up to eight fields with the constituent fields prioritised according to their order - the
first having the highest priority - subject to an overall maximum key size of 64 bytes. For example, keys
can be constructed from eight pous-e fields or, as a further example, the first 63 characters of a single
text field (stored as a leading byte count string).
The field types: BYTE, UBYTE, WORD, UWORD, LONG, ULONG and DOUBLE are compared numerically whereas
STRING fields are compared lexically using a given number of characters at a given offset from the start.
The comparison is subject to a programmer defined collation table.
The specification of the key is stored in the header of the B-tree index file and the structure is defined by
ISAM_KEYDEF:
1 INTRODUCTION
——___-__—————_-—j
typedef struct
WORD field; /* Field number for key */
UBYTE type; /* Type of field in key */
UBYTE flags; /* TSAM_FIELDFLAG_ASCEND or ISAM_FIELDFLAG_DESCEND */
UBYTE offset; /* Offset for start of comparison */
UBYTE len; /* Number of characters to compare */
WORD convert; /* Convert flag or collate table */
> ISAM_KEY_FIELD;
typedef struct
WORD nKeyFields; /* Number of key fields following... */
ISAM_KEY_FIELD keyField[ISAM_MAX_KEYFIELDS];
> ISAM_KEYDEF;
The convert field can take one of the following values:
ISAM_CONVERT_NOFOLD
ISAM_CONVERT_FOLD
ISAM_CONVERT_UPPER
ISAM_CONVERT_LOWER
which range from 0 - 3, or it can be the address of a user defined 256 byte collate table.
The priority for the field comparisons is the order they are specified with the first one having highest
priority.
Size of B-tree files
The size of a B-tree file depends upon the key size; therefore, it is good practice to keep the key as
compact as possible. A worst-case B-tree file is only 50% full so the maximum size of a B-tree file is
approximately:
2*(number of records)*(key length + 6)
For example, an index file with an eight byte key for a 1000 record file would require approximately
28K bytes of storage.
However, under typical use, a B-tree will be approximately 67% full and with the ISAM_MINIMISE flag set
(see the o_Is_IFLAGs function) this is increased to approximately 86%. Note also that B-trees built from
sorted data using 0_1S_1QBUILD or O_IS_IQADD are significantly more compact, typically 98% or over for
large numbers of records.
SSS SaaS Se eee eee eee eee ee
Interface to the ISAM library
The ISAM library is written using object-oriented programming (OOP). A class hierarchy has been
implemented such that OOP programmers can subclass the library to handle record files other than DBF
files and to use index files other than B-tree files.
Most of the ISAM functions can be called using conventional C (using the PLIB p_send OF p_entersend
functions) and the library is compatible with any combination of CLIB and PLIB libraries.
The rest of this section describes how to use the ISAM library from conventional C. In any program
using ISAM, the following steps will be involved:
= Load the ISAM DYL.
= Create an ISAM object
= Call the ISAM functions
= Destroy the ISAM object
Loading the DYL
The ISAM library is supplied as one file 1sam.pYL. Before any ISAM functions can be called, this must be
loaded. This will get a category handle which is needed for an ISAM object to be created. The loading
must be done in one of two ways depending on whether it has been linked into a multiple DYL file
(normally an executable) or not.
ISAM REFERENCE
® If not linked to a multiple DYL file, the PLIB function p_toad! ib must be used, for example:
HANDLE isamCat;
p_loadl ib("ISAM.DYL", &isamCat, TRUE);
will load 1sam.pyt from the current directory and write the category handle to isamCat.
= If linked to a multiple DYL, the two PLIB functions p_opent ib and p_loadfilelib must be used,
for example, if ISAM.DYL has been linked as the first DYL in an executable:
HANDLE isamCat;
VOID *chan;
chan=NULL;
if (p_openlib(&chan,DatCommandPtr)==0)
p_loadfilelib(chan,0,&isamCat, TRUE);
p_close(chan);
will load IsaM.bYL from the current executable and write the category handle to isamCat.
Creating an ISAM object
Once the ISAM library has been loaded, an ISAM object can be created. The class of the object required
is defined in isam.g as c_ptTbBF, which is an ISAM object using B-trees to access DBF files (ISAM may
be subclassed to produce objects accessing other types of file).
The PLIB functions p_newlibh or f_newl ibh can be used to create the object, for example:
VOID *pIsam;
plsam=p_newl ibh(isamCat,C_BIDBF);
Since there is always some initialisation to be carried out, it is generally more convenient to use the PLIB
function f_newlibhsend, for example:
VOID *plsam;
plsam=f_newl ibhsend( isamCat,C_BTDBF,O_IS_INIT,4096,0);
will create an ISAM object and then call the function 0_1s_INIT to initialise a record buffer of 4096 bytes
and the default index buffer (see the ISAM Functions chapter for the details of the 0_1s_1NIT function).
Calling ISAM functions
The ISAM functions are called by sending a message to an ISAM object using the PLIB functions p_send
OI p_entersend. The messages are defined in isam.g and take the form 0_1s_xxx where xxx is the name of
the function. Since all ISAM functions which can fail return zero for success or leave with a negative
error number, p_entersend can easily be used to catch the error or p_send can be used if the error handling
is done at a higher level. For example:
INT c;
if ((c=p_entersend4(plsam,O_IS_DOPEN, "TEST .DBF",P_FOPEN))<0)
p_printfC"Open data file failed with error %d",c);
catches the error whereas:
p_send4(plsam,O_1S DOPEN, "TEST .DBF",P_FOPEN);
passes any error to a higher level.
Destroying the ISAM object
The ISAM function 0_1s_DEsTROY will close the data file and all open index files and free all memory
used and does not leave or return errors. However, since data is buffered, it could fail. Carefully written
applications should therefore make sure that all data has been flushed and any error dealt with before
calling 0_I1s_DEsTROY. The functions 0_1s_DFLUSH and 0_IS_IFLUSH must be used.
Typical use
There are many ISAM functions available; here is a sample in the order that they are typically used:
= Create and initialise an ISAM object, use PLIB function f_newl ibhsend.
1 INTRODUCTION
SS eee
= Set the field definition for the data file, use 0_1S_SET_FIELDDEF.
= Open or create a data file, use 0_1S_DOPEN.
= Set the key definition for an index file, use 0_1S_SET_KEYDEF.
= Open or create one or more index files, use 0_1S_I0PEN.
= Build an index file, use 0_Is_IBUILD.
= Add or erase records, use 0_IS_ADD Or 0_IS_ERASE.
= Access ordered data with keys, use 0_IS_IFIND Or 0_IS_INEXT etc.
= Flush buffers, use o_1s_DFLUSH and 0_IS_IFLUSH.
= Destroy the ISAM object, use 0_1S_DESTROY.
Example programs
Note that the following two examples do not include complete error handling.
Building a complete (dense) index
This program creates a DBF file called ExaMPLE.oBF with one field of type Lone and appends 100 random
numbers to it. It then creates and builds an index file called Ex1.BTx of these numbers in ascending order.
Note that in the argument list for the setFieldDef and setkeyDef subroutines, the TopSpeed C compiler
understands the three dots to indicate an undefined number of arguments of undefined type.
#include <p_std.h>
#include <p_file.h>
#include <p_sys.h>
#include <epoc.h>
#include <isam.g>
GLREF_C TEXT *DatCommandPtr;
LOCAL_C HANDLE isamCat;
LOCAL_C VOID *plsam;
LOCAL_C VOID pErrCUBYTE *mess, INT err)
¢
UBYTE buf (E_MAX_ERROR_TEXT_SIZE];
p_errs(&buf [0] ,err);
P_printf("%s failed - %s",mess, &buf [0] );
p_getch();
p_exit( TRUE);
}
LOCAL_C VOID loadIsam(VOID)
INT c;
TEXT dylname[P_FNAMESIZE];
p_fparse("ISAM.DYL", &dylname[0} ,NULL);
if ((c=p_loadl ib(&dylname [0] , ,&isamCat, TRUE) )<0)
pErr("Load ISAM.DYL",c);
}
LOCAL_C VOID createlsam(VOID)
{
plsam=f_newl ibhsend(isamCat,C_BTDBF,O_IS_INIT,4096,0);
>
LOCAL_C VOID setFieldDef(INT nFields,...)
{
p_send4(plIsam,0_IS_SET_FIELDDEF,nFields,&nFields+1);
_- Oro
ISAM REFERENCE
LOCAL_C VOID setKeyDef(INT nKeyFields,...)
p_send4(pIsam,O_IS_SET_KEYDEF ,nKeyFields, &nKeyFields+1);
>
LOCAL_C VOID openData(TEXT *name,UINT mode)
INT c;
if ((c=p_entersend4(pIsam,0_IS_DOPEN,name,mode))<0)
pErr("Open data file",c);
>
LOCAL_C INT openIndex(TEXT *name,UINT mode)
{
INT ¢;
if ((c=p_entersend4(pIsam,O_IS_IOPEN,name,mode) )<0)
pErr("Open index file",c);
return(c);
>
GLDEF_C VOID main(VOID)
{
ULONG seed;
LONG lL;
INT nRecords;
INT indexid;
INT i;
loadIsam();
createlIsam();
setFieldDef(1,ISAM_FIELDTYPE_LONG);
openData( "EXAMPLE .DBF",P_FREPLACE |P_FUPDATE);
seed=0L;
nRecords=100;
p_printf("Generating %u records",nRecords);
for (i=0;i<nRecords; i++)
l=p_randl (&seed);
p_sendS(pIsam,O_IS_PUT_FIELD,0,&t, ISAM_FIELDTYPE_LONG);
p_send2(pIsam,0_IS_ADD);
>
p_printf ("Building index");
setKeyDef(1,0, 1SAM_FIELDTYPE_LONG, ISAM_FIELDFLAG_ASCEND);
index Id=open!I ndex("EX1.BTX", P_FREPLACE |P_FUPDATE);
p_send3(pIsam,O_IS_IBUILD, indexId);
p_printf("Sorted data:");
p_send3(pIsam,O_IS_IFIRST, indexId);
for (i=0;i<nRecords; i++)
p_send5(pisam,O_IS GET_FIELD,0,&L,1SAM_FIELDTYPE_LONG);
p_printf "4d", 1);
p_send3(pIsam,OQ_IS_INEXT, indexId);
>
p_send2(pIsam,O_IS_ DESTROY);
p_getch();
p_exit(0);
>
1 INTRODUCTION
SS See
Building a selective (sparse) index
The following routine opens the DBF file called ExaMPLE DBF which was created in the previous example.
It then creates and builds an index file called ex2.8Tx of those numbers which are divisible by ten in
ascending order.
LOCAL_C VOID divi0¢VOID)
{
LONG Ll;
INT indexId;
INT eof;
createlsam();
openData("EXAMPLE.DBF",P_FOPEN);
p_printf("Build index of numbers divisible by 10");
setKeyDef(1,0, ISAM_FIELDTYPE_LONG, ISAM_FIELDFLAG_ ASCEND);
indexId=openIndex("EX2.BTX", P_FREPLACE|P_FUPDATE);
eof=p_send2(pIsam,O_IS_DFIRST);
while (eof==FALSE)
p_send5(pIsam,O_IS_GET_FIELD,0,&1,1SAM_FIELDTYPE_LONG);
if (¢1%10)==0)
p_send3(pisam,O_IS_IADD, indexId);
eof=p_send2(plIsam,0_IS_DNEXT);
>
p_printf("Sorted data:");
eof=p_send3(plsam,0_IS_IFIRST, indexId);
while (eof==FALSE)
p_send5(pIsam,0_IS_GET_FIELD,0,&l,ISAM_FIELDTYPE_LONG);
p_printt¢("%ld",L);
eof=p_send3(pIsam,O_IS_INEXT, indexId);
>
p_send2(pIsam,0_IS_DESTROY);
>
CHAPTER 2
ISAM FUNCTIONS
ISAM functions are called using either p_send or p_entersend to the ISAM object created with (for
example) the PLIB function p_newlibh.
Most functions which can fail will return zero or a positive number for success or leave with a negative
error number, giving the caller the option of catching the error using p_entersend or leaving the error
handling to a higher level by calling p_send.
Functions that can generate E_FILE_EoF (for example, 0_1S_INEXT), will return this negative error rather
than leave.
All functions can be called from standard C but o_1s_IFILTER and 0_1S_IpuP are only applicable when
using object oriented programming (OOP).
There are three types of functions:
= General functions
s Data file functions
= Index file functions
SSS a a a a ae eee
General functions
This section describes functions to perform the following:
= Initialise and destroy an ISAM object.
= Define and read the field definition for a data file.
= Define and read the key definition for an index file.
= Read and write data to the record buffer.
® Set the format for conversion of numbers to text.
= Add, erase and update records in the data file with appropriate updates to all associated index
files.
SINT eee
VOID p_send4(VOID *pIsam, O_IS_INIT, INT rBufSize, INT iBufBlocks);
Initialise the ISAM object with a record buffer of length raufLen and an index buffer in an external
memory segment with isufBlocks blocks (a block is 1SAM_BLOCK_sIZE (512) bytes long). If iBufBlocks is
zero, the default number of blocks, 8L_DEFAULT BLOCKS (20) is used.
Performs the following initialisation:
= Allocates rbufLen bytes for the record buffer.
= Sets the field definition to the default of 32 string fields.
= Sets the key definition to the default of the first eight characters of the first string field.
ISAM REFERENCE
TO
= Sets the radix for number conversion to the default of 10.
= Sets the format for doubles converted to text to the default of p_pTOB_GENERAL with a width of 20
and a decimal point character of '.'.
rBufLen sets the size of the record buffer and must be in the range 1SAM_MIN_RECORD_BUFFER (512) to
ISAM_MAX_RECORD_BUFFER (16384). If it is not, p_panic will be called. The record buffer is used to read
records from the data file and must be at least as long as the longest record to be read. A length of
ISAM_MAX_RECORD_LENGTH+2 (4096) is guaranteed to be large enough for all records. When an index file is
being built, data is read from the file in blocks as large as the record buffer; the bigger the buffer, the
faster the build will be.
iBufBlocks must be less than or equal to ISAM_MAX_SEG_BLOCKS (1024). Any value greater than this will
cause p_panic to be called.
Leaves with E_GEN_NOMEMoRY if there is insufficient memory to initialise everything.
Typically, this function would be called when the object is created and can be combined into one call
using (for example) the PLIB function f_newl ibhsend:
plsam=f_newl ibhsend( isamCatNum, C_BTDBF,O_IS_INIT,4096,0);
This will create an ISAM object and initialise it with a record buffer of 4096 bytes and the default
number of index buffer blocks.
Creating an ISAM object is explained further in the Introduction chapter.
VOID p_send2(VOID *pIsam, O_IS_DESTROY);
Destroy the ISAM object. The data file and all open index files are closed and all memory is freed.
Note that if more than one ISAM object is created in the same process, the external segment memory
used for buffering the indexes is shared and will only be freed when the last ISAM object is destroyed.
O_IS_DESTROY can fail due to one or more write operations but will always succeed in destroying the
ISAM object (freeing all memory used). No error is ever returned and the function will not leave.
Carefully written applications avoid this problem by using o_1s_pFLUSH and 0_IS_IFLUSH, to flush all
buffered data (and taking appropriate action if this fails) before destroying the object without risk of
failure.
INT p_send4(VOID *pisam, O_IS_SET_FIELDDEF, INT nFields, VOID *pArgs);
Set the field definition to contain nFietds with types in the list at pargs. This field definition will be used
when a data file is created.
Alternatively pargs can point to an ISAM_FIELDDEF structure containing the field definition while nfields is
passed as zero.
The ISAM_FIELDDEF structure is defined in isam.g as:
typedef struct
WORD nFields;
UBYTE type[ISAM_MAX_DEFINED_FIELDS] ;
> ISAM_FIELDDEF
For example:
LOCAL_C VOID defineFields(VOID)
ISAM_FIELDDEF fieldDef;
fieldDef .nFields=2;
fieldDef.type[0]=ISAM_FIELDTYPE_WORD;
fieldDef.typel1]=ISAM_FIELDTYPE_LONG;
p_send4(pisam,0_IS_SET_FIELDDEF,0,&fieldDef);
>
SS ee SS ee
10
2 ISAM FUNCTIONS
—_ See
is equivalent to:
LOCAL_C VOID setFieldDef(INT nFields,...)
p_send4(pIsam,O_IS_SET_FIELDDEF ,nFields,&nFields+1));
>
LOCAL_C VOID defineFields(VOID)
setFieldDef(2,1SAM_FIELDTYPE_WORD, ISAM_FIELDTYPE_LONG);
>
and both define the field structure of the data file to be two fields, the first a woRD field, the second a
LONG.
The maximum number of fields that can be specified is 1SAM_MAX_DEFINED_FIELDS (32) and each field type
must be one of the following types:
ISAM_FIELDTYPE_BYTE for a signed Byte field.
ISAM_FIELDTYPE_UBYTE for an unsigned usyTE field.
ISAM_FIELDTYPE_WORD for a signed worp field.
ISAM_FIELDTYPE_UWORD for an unsigned uworp field.
ISAM_FIELDTYPE_LONG for a signed tone field.
ISAM_FIELDTYPE_ULONG for an unsigned uLonc field.
ISAM_FIELDTYPE_DOUBLE for a DOUBLE field.
ISAM_FIELDTYPE_STRING for a leading byte count string field.
More fields than are specified in the field definition can be accessed, but they are always assumed to be
of type ISAM_FIELDTYPE_STRING.
Note that this specifies the field types to be used in the actual data file; however, conversion to and from
I1SAM_FIELDTYPE_STRING is performed automatically by the functions 0_1S_PUT_FIELD and O_IS_GET_FIELD.
See the descriptions of these two functions for further details.
Similarly, index files may specify field types which differ from those specified for data file fields. The
field types will be converted automatically, provided the conversion is to or from ISAM_FIELDTYPE_STRING.
See the description of 0_1$_SET_KEYDEF.
Retums zero if successful or leaves with &_GEN_ARG if the given field definition is invalid.
ISAM_FIELDDEF *p_send2(VOID *pIsam, O_IS GET_FIELDDEF);
Get the current field definition, returning a pointer to an 1SAM_FIELDDEF structure.
INT p_send4(VOID *plsam, O_IS_SET_KEYDEF, INT nKeyFields, VOID *pArgs);
Set the key definition (to be used for the next created index file) to contain nkeyFields with the
parameters for each key field specified in the list at pArgs. This key definition will be used for the next
index file created.
Alternatively pArgs can point to an ISAM_KEYDEF structure containing the key definition while nFields is
passed as zero.
The 1SAM_KEYDEF structure is defined in isam.g by:
11
ISAM REFERENCE
typedef struct
WORD field; /* Field number for key */
UBYTE type; /* Type of field in key */
UBYTE flags; /* ISAM_FIELDFLAG_ASCEND or ISAM_FIELDTYPE_DESCEND */
UBYTE offset; /* Offset for string comparison */
UBYTE len: /* Length for string comparison */
WORD convert; /* Convert flag or collate table */
} ISAM_KEY_FIELD;
typedef struct
WORD nkKeyFields;
ISAM_KEY_FIELD keyField[ISAM_MAX_KEYFIELDS];
} ISAM_KEYDEF;
For example:
LOCAL_C VOID defineKey(VOID)
ISAM_KEYDEF keyDef;
keyDef .nKeyFields=2;
keyDef .keyField[0] .field=3;
keyDef .keyField[0] . type=ISAM_FIELDTYPE_STRING;
keyDef .keyField[0] . flags=1SAM_FIELDFLAG_ASCEND;
keyDef .keyField[0] .offset=0;
keyDef .keyField[0] . Len=8;
keyDef .keyField[0] .convert=1SAM_CONVERT_NOFOLD;
keyDef .keyField[1] .field=1;
keyDef.keyField[1] . type=ISAM_FIELDTYPE_LONG;
keyDef .keyField[1] .flags=1SAM_FIELDFLAG_ASCEND;
p_send4(pIsam,O_IS_SET_KEYDEF ,0,&keyDef);
3
is equivalent to:
LOCAL_C VOID setKeyDefCINT nKeyFields,...)
{€
p_send4(pIsam,0_IS_SET_KEYDEF ,nKeyFields, &nKeyFields+1);
>
LOCAL_C VOID defineKey(VOID)
setKeyDef(2,3, 1SAM_FIELOTYPE_STRING, ISAM_FIELDFLAG_ASCEND,0,8,1SAM_CONVERT_NOFOLD, 1,
TSAM_FIELDTYPE_LONG, ISAM_FIELDTYPE_ASCEND);
>
The fields: offset, len and convert must only be supplied if the type is 1SAM_FIELDTYPE_STRING.
The key definition is subject to the following validation:
The number of key fields must be in the range 1 to 1SAM_MAX_KEYFIELDS (8).
The field number for each key field must be in the range 0 to 1SAM_MAX_RECORD_FIELDS (4094).
The type of each key field (the type actually stored in the index file) must be valid and must be
either the same as the type specified in the current field definition or be a conversion from or to
an ISAM_FIELDTYPE_STRING,
The length of a key produced by this definition must be no greater than ISAM_MAX_KEY_LENGTH
(64).
Returns the length of a key resulting from this definition if successful or leaves with €_GEN_aRG if the key
definition is invalid.
12
2 ISAM FUNCTIONS
ISAM_KEYDEF “p_send3(VOID *plsam, O_IS_GET_KEYDEF, INT indexId);
Get the key definition for the index indexid, returning a pointer to an 1SAM_KEYDEF structure. The value
indexid is returned when an index is opened (see 0_1S_I10PEN below).
INT p_send5(VOID “plsam, O_IS_PUT_FIELD, INT field, VOID *pData, INT type);
Put the data at address pata into the record buffer at field number given by field. If any preceding fields
have not been set, they will be automatically set to contain zeros.
The type parameter is the type of the data pointed to by pdata. If type is ISAM_FIELDTYPE_STRING, the data
at pData must be in the form of a leading byte string.
If type is different from that specified for field number field (as reported by 0_IS_GET_FIELDDEF) and
either of these two types is ISAM_FIELDTYPE_STRING, the field data will be converted between numeric and
string types as necessary according to the current radix (as set by 0_IS_SET_RADIX).
For example, if the field definition is set to 32 strings and the current radix is decimal (the defaults), the
following code will put the value "31" into field zero in the record buffer as a leading byte count string.
WORD value;
value=31;
p_send5(pIsam,0_IS_PUT_FIELD,0,&value, ISAM_FIELDTYPE_WORD);
Returns zero if successful or leaves with one of the following negative error numbers:
E_FILE_RECORD the assignment to the field would make the total record length greater than
ISAM_MAX_RECORD_LENGTH (4094) or the size of the buffer specified in 0_1S_INIT.
E_GEN_ARG the type conversion required is not to or from ISAM_FIELDTYPE_STRING.
E_GEN_FAIL the type conversion failed because the string could not be recognised as a
number.
E_GEN_OVER the type conversion failed because the number is out of range.
INT p_sendS(VOID *pisam, O_IS_GET FIELD, INT field, VOID *pData, INT t e@);
- eT YP!
Get the data from field in the record buffer into the buffer at poata.
The type parameter is the type of the data required at ppata. If type is ISAM_FIELDTYPE_STRING, the data
will be written to poata in the form of a leading byte string.
If type is different from that specified for field number field (as reported by 0_IS_GET_FIELDDEF) and
either of these two types is 1SAM_FIELDTYPE_STRING, the field data will be converted between numeric and
string types as necessary according to the current radix (as set by 0_IS_SET_RADIX).
For example, if the field definition is set to 32 strings (the default), the following code will get the value
from field 10 in the record buffer and convert it to a LONG.
LONG lValue;
p_send5(pIsam,O_IS_GET_FIELD,10,&lValue, ISAM_FIELDTYPE_LONG);
Retums zero if successful or leaves with one of the following negative error numbers:
E_GEN_ARG the type conversion required is not to or from 1SAM_FIELDTYPE_STRING.
E_GEN_FAIL the type conversion failed because the string could not be recognised as a
number.
£_GEN_OVER the type conversion failed because the number is out of range.
13
INT p_send3(VOID *pIsam, O_IS_GET_TYPE, INT field);
Return the actual type of field in the data file.
This provides the same functionality as calling 0_1s_GET_FIELDDEF and then inspecting the required field.
It is included for convenience.
ISAM_RECORDBUF *p_send2(VOID *plsam, 0_IS_GET_RBUF);
Get the actual address of the record buffer allocated in 0_1s_1NIT, returning a pointer to an ISAM_RECORDBUF
structure. This struct is not defined in any header file - users of this method function should declare the
struct in their own code as:
typedef struct
{
WORD Len; /* Length of record */
UBYTE data[2]; /* len bytes of data... */
} ISAM_RECORDBUF;
This function is provided to allow direct access to the current record in the buffer, if needed. Typically,
it will be more convenient to use 0_IS_GET_FIELD and ©_IS_PUT_FIELD.
VOID p_send3(VOID “pIsam, C_IS_SET_RADIX, INT radix);
Set the base radix for number conversion to radix. By default this is set to 10.
VOID p_send3(VOID *pIsam, O_IS_SET_DFORMAT, P_DTOB *dFormat);
Set the format for pousLEs converted to text to be that specified by dFormat.
INT p_send2(VOID *pIsam, O_IS_ADD);
Add the record currently in the record buffer to the data file and attempt to add entries to all open index
files which do not have 1SAM_FLAG_MANUAL set (see 0_IS_IFLAGS).
One or more of the index files may refuse to actually add the entry for any of the following reasons:
= A filter method returns FALSE (see 0_1S_IFILTER).
= The entry matches an existing entry in the index and a duplicate method returns FALSE (see
O_IS_IDUP).
" The entry matches an existing entry in the index and I1SAM_FLAG_ALLOWDUP is not set (see
O_IS_IFLAGS).
but no error will be given.
Returns FALSE if successful or leaves with one of the negative errors returned by the PLIB function
p_write.
s
INT p_send2(VOID *pIsam, O_IS_ ERASE);
Erase the record currently in the record buffer from the data file and from all open index files which do
not have ISAM_FLAG_MANUAL set (see O_IS_IFLAGS).
The record buffer must contain a record read by a successful call to one of the following functions:
O_IS_DFIRST, O_1S_DNEXT, O_IS_IFIND, O_IS_INEXT, O_IS_IBACK, O_IS_IFIRST, O_IS_ILAST, O_IS_ICURRENT.
SSS SS Se ee eee
14
2 ISAM FUNCTIONS
—. EES
Retums FALSE if successful or €_FILE_EoF if the current record is end-of-file or leaves with one of the
negative errors retumed by the PLIB function p write.
INT p_send2(VOID *pisam, O_IS_ UPDATE);
Replace the record which was read by a successful call to one of the following functions: 0_1s_DFIRST,
O_IS_DNEXT, O_IS_IFIND, O_IS_INEXT, O_IS_IBACK, O_IS_IFIRST, O_IS_ILAST, O_IS_ICURRENT, by the new
contents of the record buffer in the data file and all open index files which do not have 1SAM_FLAG_MANUAL
set (see O_IS_IFLAGS).
Returns FALSE if successful or €_FILE_Eor if the current record is end-of-file or leaves with one of the
negative errors returned by the PLIB function p_write.
SS ea en ee eS]
Data file functions
This section describes functions to perform the following:
= Open or create a data file.
= Flush the buffers used for the data file.
= Get the current size of the data file.
= Sequentially read the data file.
INT p_send4(VOID *plsam, O_IS_DOPEN, TEXT *name, UINT mode);
Open a data file specified by the zero terminated file specification name.
The mode parameter is the same as for the PLIB function p_open(P_FSTREAM). If P_FCREATE OF P_FREPLACE is
specified, the data file is created with the current field definition (see 0_1S_SET_FIELDDEF). If an existing
data file is opened, the current field definition is set to that of the file opened.
Only one data file can be opened per ISAM object. If an attempt is made to open more than one, P_panic
will be called.
Retums zero if successful or leaves with one of the negative errors returned by p_open(P_FSTREAM).
INT p_send2(VOID *pisam, O_IS_DFLUSH);
Flush al! data written to the data file and write the file's modification date.
Returns zero if successful or leaves with one of the negative errors returned by the PLIB function
P_write.
See the PLIB function p_iow(P_FFLUSK) for further details on flushing.
Sra
INT p_send3(VOID *pIsam, O_IS DSIZE, LONG *size);
Write the size (in bytes) of the open data file to size.
Retums zero if successful or leaves with one of the negative errors returned by the PLIB function p_seek.
INT p_send2(VOID *plsam, O_IS_DFIRST);
Read the first record in the data file into the record buffer.
15
ISAM REFERENCE
Returns zero if successful or £_FILE_EoF if there are no records or leaves with one of the negative errors
returned by the PLIB function p_read.
Read the next record in the data file into the record buffer.
Should be used in conjunctions with o_1s_DFIRST to provide sequential access to the data file records in
the order they are stored without the need for an index file.
Returns zero if successful or E_FILE_EOF if the current record is the last record in the file or leaves with
one of the negative errors returned by the PLIB function p_read.
a a a a a a ed
Index file functions
This section describes functions to perform the following:
= Open or create an index file.
= Flush the buffers used for the index file.
® Build a complete (dense) index file from a sorted or unsorted data file.
= Build an index for a selection of records (sparse) by one of two mechanisms:
1) Specify a function which will be called during the building of the index (OOP only).
2) Add and erase entries from the index directly.
= Get the size and number of entries in an index.
= Provide fast indexed access to records in the data file from a given index and match key.
= Provide sequential access to records in the data file in the order defined by an index.
The function 0_I1S_IOPEN returns an indexId which is then passed as a parameter to other index functions.
INT p_send4(VOID *pIsam, O_IS_IOPEN, TEXT “name, UINT mode);
Open an index file specified by the zero terminated file specification name.
The mode parameter has the same meaning as for the PLIB function p_opencP_FSTREAM), except that
P_FAPPEND should not be specified. If P_FCREATE or P_FREPLACE is specified, the data file is created with the
current key definition (see 0_1S_SET_KEYDEF above). If an existing index file is opened (with a mode of
P_FOPEN, optionally ored with P_FUPDATE) its key definition can be obtaining using 0_1s_GET_KEYDEF.
Note that the key definition is stored in the index file itself and cannot be changed once the index file has
been created.
Retums an indexid from 1 to 31 if successful or leaves with one of the negative errors returned by
P_open(P_FSTREAM) Or E_GEN_FAIL if an attempt is made to open more than 31 indexes.
INT p_send3(VOID *plsam, O_IS_ICLOSE, INT indexId);
Close the index specified by indexid and return zero.
0_IS_ICLOSE can fail due to one or more write operations but will always succeed in closing the channel
(the indexid should not be used subsequently). No error is ever returned and the function will not leave.
Carefully written applications avoid this problem by using 0_!s_IFLUSH to flush all buffered data (and
taking appropriate action it this fails) before closing the channel without risk of failure.
16
2 ISAM FUNCTIONS
INT p_send3(VOID *plsam, O_IS_IFLUSH, INT indexld);
Flush all buffers used for index indextd and write the index file's modification date.
Returns zero if successful or leaves with one of the negative errors returned by the PLIB function
p_write.
See the PLIB function p_iow¢P_FFLUSH) for further details on flushing.
INT p_sendS(VOID *plsam, O_IS_IFLAGS, INT indexId, INT mask, INT value);
Modify the flag bits given by mask to the state (set or clear) given by value in index indextd.
Returns the new value of the flags; passing mask as Zero just reads the current flag settings.
The flags available are:
ISAM_FLAG_ALLOWDUP allow duplicate entries in the index. If this flag is set, duplicate entries will be
added when the index is built using 0_I1s_BUILD or 0_IS_QBUILD or when entries
are added with 0_1S_ADD or 0_IS_IADD.
1SAM_FLAG_MANUAL the index will not be automatically updated by calls to the general functions
0_1S_ADD, O_IS_ERASE or 0_IS_UPDATE. The index functions 0_1S_1ADD and
O_IS_IERASE must be used to add or erase entries explicitly; typically, it is used
to build an index to a selection of records only (a sparse index).
ISAM_FLAG_MINIMIZE Minimize the storage requirement of the index by altering the way keys are
inserted. The index is not compressed when the flag is set but any future
additions to the index are inserted using the minimize algorithm. With the flag
set, the actual insertion will be slower but the index produced will be smaller
and hence a greater portion of it can be held in internal buffers which means
finding the insertion point is faster.
Whether it is worth setting this flag is clearly application dependent and the
best way to decide is by trial and error.
The flag can be set or cleared at any stage without harming the index structure.
By default, all the above flags are not set.
Note that these settings are stored in the index file but can be modified at any time. For example, if
1SAM_FLAG_ALLOWDUP is not set, it does not necessarily mean there are no duplicate entries in the index. It
just means that the current intention is to not add duplicates.
Example
testId=p_send4(pIsam,0_IS_IOPEN, "TEST. INX", P_FREPLACE|P_FUPDATE);
p_send5(pIsam,O_IS_IFLAGS, testId, ISAM_FLAG_ALLOWDUP, ISAM_FLAG_ALLOWDUP);
creates an index file in which duplicate entries will be allowed.
_ Specify a filter method
VOID p_sendS(VOID *pIsam, O_IS_IFILTER, INT indexid, VOID *pObj, INT method);
This function is only applicable when using object oriented programming (OOP).
Specify the object at p0bj to be called with method whenever entries are added to index indextd, to
facilitate the building of an index to a selection of records (a sparse index).
The method is called with a pointer to the key that is being inserted and the address of a LoNG which is the
data file reference. The method must return FALSE if the entry should be omitted from the index or TRUE if
it should be added.
To remove the filter method, pobj must be passed as NULL.
17
ISAM REFERENCE
pil
VOID p_send5(VOID *plsam, O_IS_IDUP, INT indexId, VOID *pObj, INT method);
This function is only applicable when using object oriented programming (OOP).
Specify the object at pobj to be called with method whenever a duplicate entry is added to index indexId.
The method is called with a pointer to the key that is being inserted and the address of a Lonc which is the
data file reference. The method must return FALSE if the duplicate entry should be omitted from the index
or TRUE if it should be added anyway. There is no regard for the setting of the flag 1SAM_FLAG_ALLOWDUP in
either case, ie the method called has higher priority.
To remove the duplicates method, pobj must be passed as NULL.
INT p_send3(VOID *plsam, O_IS_IBUILD, INT indexId);
Build the index specified by indexid using its key definition to extract keys from the records in the data
file.
If the data file is already ordered by the key for this index, 0_1s_1aBuILD should be used to build the
index much faster.
The index is always built from scratch; any existing index entries are erased first.
Returns FALSE if the complete build was successful and there were no duplicate entries; returns TRUE if
successful but there were duplicates or leaves with one of the negative errors returned by the PLIB
function p_write in which case all entries made so far will be erased.
Duplicate entries
The value TRUE, returned by 0_1$_IBUILD is simply to inform the caller that one or more keys extracted
from the data during the build were identical. It does not, however, indicate whether more than one copy
of the key has been stored in the index or not. This is controlled by the following:
= Ifa duplicates method has been specified by 0_1s_1pup, its return value of TRUE or FALSE
determines whether to insert or not. (This is applicable to OOP only.)
= If there is no duplicates method, the setting of the flag 1SAM_FLAG_ALLOWDUP is used.
INT p_send3(VOID *plIsam, O_IS_IQBUILD, INT indexId);
Build the index specified by indexid using its key definition to extract keys from the records in the
(sorted) data file.
For this function to work, the records in the data file must be in the correct order defined by the key
definition for this index.
There are two advantages of this function over 0_Is_1BUILD:
1) It is much faster for a large number of records. So much faster, in fact, that it is often quicker to
sort the data file (using, for example, a quick-sort algorithm) and then call 0_1s_1aBuILb to build
an index than to call 0_1s_1BUILD with an unsorted data file.
2) The index file produced will generally be smaller (more compressed) than that produced using
O_1S_IBUILD. Note that if the flag ISAM_FLAG_MINIMIZE is set before the call to 0_IS_QBUILD, an
even smaller index file will be produced at a small cost to the time taken (see the 0_1S_IFLAGS
function, above).
The index is always built from scratch, so any existing index entries are erased first.
Returns FALSE if the complete build is successful or leaves with one of the negative errors returned by the
PLIB function p write in which case all entries made so far will be erased.
Note that there is no checking for duplicate entries as there is with the o_1s_1BUILD function.
18
2 ISAM FUNCTIONS
INT p_send3(VOID *plsam, O_IS_IADD, INT indexId);
Add an entry to the index indexid using its key definition to extract a key from the record currently in the
record buffer.
The entry is added to the given index only, unlike the function 0_1s_app which adds entries to all
appropriate indexes automatically. This provides, therefore, the mechanism for building and maintaining
a selective (sparse) index:
= Read records into the record buffer using, for example, 0_1S_DNEXT, Or O_IS_IFIND, 0_IS_INEXT
with another index.
= Selectively add entries to this index if certain conditions are met.
This method of building an index will typically be slower than building a sparse index by calling
O_IS_IBUILD Or 0_IS_IQBUILD after specifying a filter method but does not require OOP.
If the entries are to be added in key order, the function 0_1s_1aapp should be used to add the entries
faster.
Retumis FALSE if successful or TRUE if successful but the entry is a duplicate or leaves with one of the
negative errors returned by the PLIB function p_write.
The decision whether to add a duplicate entry is made in exactly the same way as with 0_IS_IBUILD.
INT p_send4(VOID *pIsam, O_IS_IQADD, INT indexId, INT finish);
Add an entry to the index indexid in order using its key definition to extract a key from the record
currently in the record buffer.
The entries must be added in the correct order given by the key for this index and the parameter finish
should be passed as FALsE for all entries except the last entry, when it should be passed as TRUE.
The index should contain no entries before the first 0_1s_1aapp is called.
The advantages of this function over 0_1s_1apD are the same as 0_IS_IQBUILD over O_IS_IBUILD.
Returms FALSE if successful or leaves with one of the negative errors returned by the PLIB function
P_write.
Note that there is no checking for duplicate entries as there is with the 0_1s_1app function.
1S_IEF
INT p_send3(VOID *pIsam, O_IS_IERASE, INT indexId);
Erase an entry from the index indexid, which corresponds to the record currently in the record buffer.
The entry is erased from the given index only, unlike the function 0_1s_ERASE which erases entries from
all appropriate indexes automatically. This provides, therefore, the mechanism for maintaining a selective
(sparse) index.
Returns FALSE if successful or TRUE if there is no entry in the index which corresponds to the record in the
record buffer or leaves with one of the negative errors returned by the PLIB function p_write.
INT p_send3(VOID *pisam, O_IS_IERASEALL, INT indexId);
Erase all entries in the index indextd.
Returns zero if successful or leaves with one of the negative errors returned by the PLIB function
p_write.
19
INT p_send4(VOID *pIsam, O_IS_ICOUNT, INT indexId, LONG *count);
Write the number of entries in the open index file indexId to count.
Returns zero if successful or leaves with one of the negative errors returned by the PLIB function p_seek.
INT p_send4(VOID *pIsam, O_IS_DSIZE, INT indexId, LONG *size);
Write the size (in bytes) of the open index file indexid to size.
Returns zero if successful or leaves with one of the negative errors returned by the PLIB function p_seek.
INT p_send4(VOID *pisam, O_IS_IFIND, INT indexId, VOID **pArgs);
Find an entry in the index indexid which matches the key generated by the arguments at pargs and read
the corresponding record from the data file into the record buffer.
pArgs is the address of an array of pointers to key fields to be matched, terminated by NULL if fewer key
fields are supplied than are specified in the key definition for this index.
Returns the following:
FALSE if a matching entry is found and the corresponding record is read into the
record buffer.
TRUE if no match is found and the record corresponding to the following index entry
is read into the buffer.
E_FILE_EOF if no match is found and there is no following index entry (no record is read
into the record buffer).
or leaves with a negative error returned from the PLIB function p_read.
For example:
LOCAL_C INT findEntryCINT indexId,...)
{
return(p_send4(pisam,O_IS_IFIND, indexId, &indexId+1));
>
LOCAL_C VOID find(VoID)
{
UBYTE str[16];
LONG lL;
L=99999L ;
str [0J=3;
str[ij="A';
str[2]="B';
str(3]='C';
if (findEntry(index1,&l,&str [0] ,NULL)==FALSE)
p_printf ("Found") ;
else
p_printf("Not found");
>
will search index for the first entry with field zero equal to 999991 and field one equal to asc. Note that
the field types passed must be the same as those specified in the key definition of the index.
If there is more than one entry in the index which matches the given fields, 0_1s_IFIND will always read
the first one. To read any others, use 0_IS_INEXT.
20
2 ISAM FUNCTIONS
INT p_send3(VOID *pIsam, O_IS_INEXT, INT indexId);
Read the record corresponding to the next entry in index indexid into the record buffer.
Returns zero if successful or £_FILE_EoF if the current index entry is the last one or leaves with one of the
negative errors returned by the PLIB function p_read.
If two or more indexes are open at the same time, this method function may return E_FILE_EOF
erroneously. If you use two or more indexes simultaneously, you should access this method via a utility
function of the following form:
GLDEF_C INT DoInext(VOID *pIsam, INT indexId)
INT ret;
ret=p_send3(pIsam,O_IS_INEXT, indexId);
if (ret==E_FILE_EOF)
{
p_send3(pIsam,0_IS_IBACK, indexId);
p_send3(pIsam,O_IS_INEXT, indexId);
ret=p_send3(pIsam,O_IS_INEXT, indexId);
>
return(ret);
>
INT p_send3(VOID *plsam, O_IS_IBACK, INT indexId);
Read the record corresponding to the next entry in index index!d into the record buffer.
Retums zero if successful or €_FILE_E0F if the current index entry is the first one or leaves with one of the
negative errors returned by the PLIB function p_read.
INT p_send3(VOID *pIsam, O_IS_IFIRST, INT indexId);
Read the record corresponding to the first entry in index indexid into the record buffer.
Returns zero if successful or €_F1L€_EOF if there are no entries in the index or leaves with one of the
negative errors returned by the PLIB function p_read.
INT p_send3(VOID *pIsam, O_IS_ILAST, INT indexId);
Read the record corresponding to the last entry in index indexid into the record buffer.
Returns zero if successful or €_F1LE_E0F if there are no entries in the index or leaves with one of the
negative errors returned by the PLIB function p_read.
INT p_send3(VOID *pIsam, O_IS_ICURRENT, INT indexId);
Read the record corresponding to the current entry in index indexid into the record buffer.
Retums zero if successful or €_F1LE€_E0F if the current index entry is set to end-of-file or leaves with one
of the negative errors returned by the PLIB function p_read.
21
INDEX
IS ADD 14
-18 DESTROY 10
DFIRST 15
“DFLUSH 15
ERASE 14
GET FIELD 13
GET_FIELDDEF 11
GET_KEYDEF 13
GET_RBUF 14
GET_TYPE 14
“IADD 19
“IBACK 21
IBUILD 18
ICLOSE 16
“ICOUNT 20
“ICURRENT 21
“IDUP 18
IERASE 19
“IERASEALL 19
TIFILTER 17
“IFIND 20
IFIRST 21
IFLAGS 17
“IFLUSH 17
ILAST 21
“INEXT 21
INIT 9
“IOPEN 16
“IQADD 19
“IOBUILD 18
“ISIZE 20
“PUT FIELD 13
"SET_DFORMAT 14
SET_FIELDDEF 10
~SET_KEYDEF 11
"SET_RADIX 14
"UPDATE 15
1111919919191 9, 92,9, 9,2,2,9,9,9,9,2,9,9,9,0,9,0.0
FIAVAIIRAA AAD ADD BADAADARARA DADO RBBB AAD D