9 /81 PRM-11 U SER'S GUIDE OMSI PASCAL INTERFACE TO RMS-11 Kenneth G. Tibesar 3M Engineering Systems and Technology Labs St. Paul, Minnesota 55144 Pascal Record Management User's Manual PAGE 2 Table Of Contents 1.0 Introduction To PRM 1.1 PRM Design 1.2 User Interface 1.3 File Operations 1.4 Record Operations 1.5 RFA 1.6 Memory Requirements 2.0 Preparing for PRM 2.1 Pre-de fined Data Structures 2.2 Control Buffers 2.2.1 RmsF ileDesc - File Description 2.2.2 RetRecord - Record Retrieval 2.2.3 StoRecord - Record Storage 2.2.4 IdxKeyDesc - I ndexed Key Description 2.3 Record Buffers 2.3.1 Non- Shared Buffers 2.3.2 Shared Buffers 2.4 Key Buffers 2.5 PRM External Calls 2.6 Rms-11 Initialization 2.7 Task Build 2.8 User Space Optimization 2.9 PRM Pit-Falls 3.0 Detailed Description of PRM Buffers 3.1 RmsFileDesc - File Description 3.2 RetRecord - Record Retrieval 3.3 StoRecord - Record Storage 3.4 IdxKeyDesc - Index ed Key Description 3.5 User Defined Record Buffers 4.0 D etailed Description of PRM Routines 4.1 General Use 4. 2 File Access and Creation 4.2.1 PRMClo 4.2.2 PRMC re 4.2.3 PRMKey 4.2.4 PRMOpe 4.3 Reco rd Retrieval and Storage 4.3.1 PRMDel 4.3.2 PRMFre 4.3.3 PRMRet 4.3.4 PRMSto Appendix A PRM program example - Access an existing RMS files Appen dix B PRM program example - Dynamic creation of an RMS indexed file Appendix C PRM example command and overlay descriptor files Appendix D PRM Error Codes Pascal Record Management User's Manual PAGE 3 Preface PREFACE Record Management Services (RMS-11) is a software package written and supported by DEC. The package is a data manag ement tool that supports sequential, relative and indexed (ISAM) file s. Pascal Record Management (PRM-11) is a non-supported interface developed by 3M Engineering and Systems Technology Labs. PRM was developed as an interum until the OMSI Pascal Co mpiler directly supports RMS-11. PRM was developed and teste d using V1.2G of OMSI Pascal and DEC RSX-11M+ operating system. K nown problems will occur when using OMSI Pascal V1.2H due to changes in initialization procedures. Version 2 of OMSI Pascal can be used only if the Version 1 switch is used. Comments and questions concerning PRM should be directed in writting to: Kenneth Tibesar 3M Center, Bldg. 518-1 St. Paul, Minnesota 55144 CHAPTER 1 Introduction to PRM PRM-11 is a set of ro utinnes written in OMSI Pascal with in-line MACRO-11 code to inter face to RMS-11. DEC supported high level languages interface to RMS- 11 by using key words supported by the language compiler. The p resent versions of OMSI Pascal for the PDP-11 does not support RMS-11 interface. PRM provides the interface via a set of external proc edures that are similiar to the key words used by DEC languages. PRM routines are called by the user code when RMS-11 operations are required. The PRM routines are linked to the user code during the task build. 1.1 PRM Design PRM routines use DEC supported MACRO-11 routines to perform RMS-11 operations. RMS-11 requires attribute blocks describing the file (FAB) and record (RAB). PRM defines fields within the attrib ute blocks. This allows Pascal to directly control the contents of the files RABs and FABs. The contents of the RABs and FABs are indir ectly controlled by the PRM user by loading pre-defined buffers and u sing one of the PRM external procedures. User buf fers required by PRM routines are allocated in the user space. The user defines only the number of buffers required for the applicat ion. The buffers are loaded by the PRM user to indicate file or record access parameters. The buffers are also used by PRM as wo rking space. By using buffers allocated globally (from the heap ), PRM can preserve variables between PRM calls. No rmally, RMS-11 requires the user to reserve POOL space. The POOL sp ace is used by RMS internal code as control structures known as BDB's (Buffer Descriptor Blocks). The POOL space has to be allocated based on the number of simultaneously opened files. T his design would wastes user space that cannot be reclaimed even t hough the file is closed. Pascal Record Management User's Manual PAGE 1-2 Introduction to PRM To avoid this loss of valuable user space, PRM dynamically allocates and deallocates the space when required by RMS-11. RMS-11 allows the MACRO-11 progra mmer to specify a GSA (Get Space) routine. The PRM GSA routine simply calls the Pascal Run-Time-System NEW and DISPOSE routines to m anage HEAP space. RMS-11 uses the declared GSA routine when it requires or releases space. Space is not used until a file is opened and returned to the Pascal heap when the file is closed. PRM was modled after syntax used by existing DEC sup ported languages that interface to RMS-11. The following is a list of PRM and high level language comparisons: 1. DEC - Compile rs support commands that perform RMS-11 file and record ope rations. PRM - External procedures linked to the Pascal program perform RMS-11 file and record operations. 2. DEC- Descriptive key words are used with RMS-11 commands to specify attributes of the file and record operations. PRM - Descriptive field names are used to load records passed to the external procedur es. The record fields specify attributes of the file or record operation. 3. DEC - A completi on code indicating the success of failure of each RMS operation is made available to the user. The completion co de is available thru the use of a reserved word. Op timize user space utilization if necessary. 4. PRM - A completion code in returned with each PRM call. The code is the standard RMS-11 completion code . In addition, PRM provides debugging completion codes for the PRM user. 1.2 User Interface The PRM interface to OMSI Pascal uses the Pascal internal record structure to pass data. Pre-defined records are included in the TYPE dec laration of the User Pascal program. The Pascal programmer determin es the operation to be performed (open, close, get record, etc.) an d loads the appropriate record buffer. Once loaded, the reocrd address is passed to the specific PRM routine that performs the fi le or record operation. The PRM routines load the RMS attribut e blocks Pascal Record Management User's Manual PAG E 1-3 Introduction to PRM (RAB and/or FAB) with the control code s necessary to satisfy the user request. If data is to be stored or retrieved, the User Pascal program is also required to pass the a ddress of a data buffer. In addition to control and data buffer addresses, an address of a status buffer is required with all PRM calls. The status buffer is loaded with a compl etion code. The code is a standard MACRO-11 RMS success/error code (refer to RMS-11 User's Manual, Appendix B). In additionn PRM wi ll return debugging error codes for the PRM user. PRM error codes are only generated due to PRM user procedural error. Refer to Appendix D of this document. The user should check t he completion code following each PRM call. If the file is no t opened properly, no record operations should be performed. If the user continues after an error in a file open or creation, PRM will catch the error. All record operations on an improperly opened or cre ated file are prohibited. 1.3 File Operations There are four file operation primitives provided. A buffer of TYPE RmsFileDesc is used with all the PRM file r outines. The PRM user must allocate a buffer of this TYPE for eac h simultaneously open file. The buffer is loaded by the PRM user to describe the file to be opened or created. Once the file is open, the contents of this buffer provides space for the file attri butes blocks (FAB and RAB). The attributes blocks are loaded by PRM routines to indicate PRM User requests to RMS-11 routines . All PRM record operations require the PRM User to pass the address of the RmsFileDesc buffer. This inidicates to PRM the file to be accessed. Since space is allocated in user space for t he file attributes blocks, file data is preserved between PRM calls. The file opeation primitives are: 1. PRMClo - Closes an open RMS file and returns used buffer space to the Pascal heap. 2. PrmCre - Creates an Rms File. If t he file to be created is an indexed (ISAM) file, the PRMK ey routine must be called a minimum of one time prior to this call. 3. PRMKey - Defines the keys o f an indexed file. This Pascal Record Management User's Manual PAGE 1-4 Introduction to PRM call is us ed prior to the PRMCre routine. Each call defines on key of the indexed file. Multiple keys must be defined in as cending order. In addition to the RMSFileDesc buffer, a buf fer of TYPE IdxKeyDesc is also used with the PRMKey routin e. 4. PRMOpe - Opens an existing RMS file PRM ensures that the user knows the file record size of the file specified for during PRMOpe. The open requires the user to specify the record size of the file. If the actual file record size an d the user specified record size to not match, any activity on the f ile is prohibited. PRM returns the standard RMS-11 Macro error codes. 1.4 Record Operations There are four record operation primitives provided by the PRM interface. An address of buffer TYPE RetRecord is passed to PRMRet. An addre ss of buffer TYPE StoRecord is passed to PRMSto for storing reco rds. The buffers contain the necessary parameters for access to the file. Before the record operations are performed, PRM w ill check to see if the file to be accessed is properly opened. Record operations performed on an improperly opened file will produce unpredictable results. Any record operation request per formed on an RMS file that has not been successfully opened by PRMOpe will be rejected by PRMRet and PRMSto. The record operation p rimitives are: 1. PRMDel - Delete the currently selected re cord from the file. The currently selected record is established with a PRMRet call. 2. P RMFre - Unlocks the bucket locked by the previous PRMRet operation. The bucket is locked only if the file is opene d with write access. 3. PRMRet - Retrieves a record from a fi le successfully opened with PRMOpe. A record is always pla ced in the RMS I/O internal buffer. If a PGET type retrieva l is executed, the User Record Buffer (address passed by the PRM user) is loaded. If a PFIND type retrieval is executed, the user record buffer is not loaded. 4. PRMSto - Store or update a record in a sucessfully Pascal Record Ma nagement User's Manual PAGE 1-5 Introduction to PRM opened file. A PPUT operation will generate a new record, a PUPDATE will update an existing record. 1.5 RFA (Record File's Address) The PRM interface prov ides access to file records via RFA's. An RFA is a unique numb er assigned to each record of RMS type files. The use of RFA provide s direct access to a record by-passing the record processing sof tware. Use of an RFA will also provide random access to RMS Sequen tial files that are stored on random access devices (disks). An example of RFA access usage would be an application that searches the file for records with specific conditions. The en tire file is searched and records with the specified conditions a re "remembered" for future reference. When the entire file h as been searched, the processing begins randomly accessing the fi le for the specified records. If during the initial search, the RFA i s stored, the RFA can be used to randomly access the record. The s toring of the RFA may be an alternative to storing the entire record (or key) in memory for rapid access to the data after the initial se arch. Storing the entire record (or key) may not be possible. The previous senario describes the use of DataTrieve when forming a "collection". NOTE The RFA used to define a record is unique and can be stored in a file for access to records for subsequent executions of an application. However, the RFA is only valid for th e life of the file. Once the file has been reorganized with a ut ility such as CNV or IFL (or an application program), the RF A for a given record is no longer valid. R FA can be used to retrieve records only. When you store a new reco rd, PRM returns the RFA generated by RMS via the StoRecord buffer. When you retrieve a record will normal access, the record RFA i s returned by PRMRet in the RetRecord. When you retrieve a record by RFA, you specify search := RFA in RetRecord buffer and load the RFA in KeyNum in RetRecord buffer. The example in the appendix shows use of RFA's to randomly retrieve records from a sequential file . Pascal Record Management User's Manual PAGE 1-6 Introduction to PRM 1.6 Memory Requirements PRM code requires approximately 1KW if all routines are used. The space used would be required by any interface to RMS-11 including MACRO-11 or any high level language. PRM is designed so only the re quired calls are included. Dynamic memory space is managed by the Pascal run-time system. PRM defines a GSA routine (refer to p aragraph 1.1) to efficiently control allocation and deallocation of P ascal heap space. RMS-11 code requires approximat ely 24KW is all file organizations with all RMS-11 file and record operations supported. At present, PRM requests the task buil der to link ALL RMS-11 code to a PRM task. If the RMS-11 Resident L ibrary is not used, the user space remaining is serverly limited. If not using RMS-11 Resident Library support, modify the RMSIni routine and/or use DEC supplied ODL (overlay descriptor language) files. Refer to paragraphs 2.5 and/or 2.6 for detail . CHAPTER 2 Preparing for PRM The PRM User Program must in clude the PRM interface structures and external procedure calls. All the structures and calls are provided as part of the PRM packag e. The data structures are located in file PrmPrefix.Pas. The PRM Procedure calls are located in file PrmCalls.Pas. The following is an abbreviated list of the steps that mus t be followed to prepare your task for interface to PRM-11. Paragraph s that follow detail each step. 1. Pre-Define Data Structur es - Pre-defined data structures must be included in y our source code. The data structure are located in file [300,47]PRMPrefix.Pas. 2. Control Buffers - Allocate space in your task by defin ing buffers of TYPES defined from the data structures file. The buffers are used to pass control data to PRM external routines. Define only the buffers required to satisfy PRM interface requirements. 3. Record Buffers - Define data structures to describe the logical record of your application. An example recor d definition is included in the data structures file. Al locate the required record buffers to satisfy task requ irements. 4. Key Buffers - Modify the KeyDef record definitio n and keysizes in CONST to describe the keys of your indexed and/or relative file(s). Use variant records to define key(s) of the RMS file(s). If your application uses RELATIVE type files, define one entry of type "TwoWord" (defined in PRMPrefix) to hold RELATIVE record numbers for retrieval and store operations . 5. External Calls - Include the contents of file PRMCalls.Pas. Delete PRM procedure call(s) that will Pa scal Record Management User's Manual PAGE 2-2 Preparin g for PRM not be used. This will avoid the addition o f code that will not be used. 6. RMS-11 Initialization - Modify RMSIni if all file organizations and/or record operations are not used. This is important if not using the RMS Resident Library. 7. Task Build - Reference object library RMSPAS during task build. 8. User Space Optimization - Share control and data buffers if space is limited. 9. PRM Pit-Falls - Check to make sure your task has speci fied the proper parameters to PRM. 2.1 Pre-defined Data Stru ctures File PRMPrefix.Pas defines all of the data struct ures that are used to pass user specified data to PRM routines. Data is transferred to external routines by passing an address reference of control buffers allocated in the main program sp ace. PRM routines expect a specific format of the buffer therefor e PRM external procedures and user programs must use formatted reco rds. The buffer descriptions used by PRM routines and PRM Users are not exactly alike. For example, PRM routines full defined the RAB and FAB in the RMSFileDesc buffers. The user RMSFileDesc buffer defines the RAB and FAB as "work space". This d ifference allows the user to ignore (and define) fields within the R AB and FAB. The complexity of the user program is reduced because po inter types in the RAB and FAB are defined externally only. Anot her difference is the record and key buffer definitions. PRM deter mines the size by using size data passed by the user. PRM ha s to depend on the user to specify the proper sizes. 2.2 Control buffers The control buffers provide the user with a means of specifying control data to PRM external routin es. PRM uses the control data loaded by the user to load the RMS- 11 RAB (record attributes block) and FAB (file attributes block) . Codes are generated by PRM to inidicate user requests passed Pascal Record Management User's Manual PAGE 2-3 Prepar ing for PRM via the control buffer fields. 2.2.1 RMSFileDesc - File Description The RMSFileDesc (RMS File Description) type buffer is allocated by the user in the main pro gram space (heap space). A buffer is allocated for each simultaneousl y open file (refer to paragraph 2.2.9). The buffer is loaded by the user before the PRMOpe (open file) procedure is called. All procedi ng PRM calls pass the address of this buffer to the PRM routine to indicate the file to be used for the record operation. The RMSFileDesc buffer provides PRM with space that is used as the file RAB and FAB. Since the buffer is allocated from the user space (versus locally), the contents of the RAB and FAB can be preserved be tween PRM calls. 2.2.2 RetRecord - Retrieval Record The RetRecord (Retrieval Record) type buffer defines the u ser retrieval parameters. PRM also uses fileds in the buffer to pass back control data to the calling program. The PRM user loads t he buffer prior to each PRMRet (record retrieval) call. 2.2.3 StoRecord - Storage Record The StoRecord (Store Record) type buffer defines the parameters used when storing a record in an open file. The buffer is used with PRMSto (store recor d) external procedure. 2.2.4 IdxKeyDesc - Indexed Key Descrip tion The IdxKeyDesc (Indexed File Key Description) type buf fer is used to define each key of a dynamically created RMS-11 indexed file. A buffer of this type is loaded prior to using the PRMKey (key definition) external procedure. Pascal Record Managemen t User's Manual PAGE 2-4 Preparing for PRM 2.3 Record buffers The PRM user defines record buffers to hold the file logical records. One record buffer can be all ocated for each file or record buffers can be shared. The address of the record buffer and size of the record buffer is passed to the PRMRet or PRMSto external procedures. The external procedures use the size and address of the buffer to load or store the data. Size of the record buffer specified by the user cannot be checked for accuracy by PRM external procedures. If care the user specifies an incorrect buffer size, FATAL results can occur. Refer t o paragraph 2.2.9 for details. 2.3.1 Non-shared record buffers If your program logic requires record data from more than one file simultaneously, serperate record buffers have to be allocated. Buffers of the same type have to be allocated to sa tisfy Pascal type checking. The type checking if enforced when pas sing the buffer to the external PRM procedures. Modify the Rec Def buffer definition in PRMPrefix.Pas to safisfy your requiremen ts. Use as many CASE entries as required to specify all rec ord buffer types. If your application does not require the f ile full record, allocate the size of the buffer required and indicat e the size of your buffer when you retrieve or store data by specify ing a RecSize before the operation. In some cases, the record buffer size differences may be significant. Using a v ariant record definition may not be desirable due to allocation of t he largest variant for each buffer. This means that the smaller record buffer will have an unused space the size of the difference i n size of the two records. If the logical records of your application vary in size and you cannot afford wasted sp ace, define a sperate record TYPE for each record. To safisfy Pascal TYPE checking when the buffer is passed to external PRM proced ures, define the PRMRet and/or PRMSto call(s) local to a user proced ure. The locally defined procedure call will be the same as the globally defined call with the exception of the record TYPE definition. The external procedure call will be linked to the same PRM external procedure by the task builder. Pascal Record Managemen t User's Manual PAGE 2-5 Preparing for PRM 2.3.2 Shared record buffers If your application does no t require data from different files simultaneously, the same reco rd buffer can be used to hold data from more than one file. A record buffer address is passed to PRM procedures that store (PRMSto) or retrieve (PRMRet) records. The record buffer used is determined by the calling program. 2.4 Key Buffers Modify the KeyDef TYPE description to define the keys of yo u file(s). A CASE of all the TYPEs can be defined. The RetRecor d type buffer uses the KeyDef description to determine the key struct ure. Since the RetRecord places the KeyDef type field at the end of the RetRecord buffer, the key can be any size. 2 .5 PRM External Calls External Procedure calls are defined in file PrmCalls.Pas. Only the calls used in your appl ication should be included in your source code. The task build er will include the PRM code form the PRM library for only the cal ls referenced in the source. Define the PRM procedures local to user procedures if different record TYPE buffers are required. Refer to paragraph 2.3.1 for details. 2.6 RMS-11 Initializat ion There is only one initialization routine, RMSIni. Thi s module must be referenced in all tasks using PRM. RMSIni defines a RMS-11 Macro that indicates to the task builder the RMS-11 code that should be linked to the task. The PRM packa ge assumes worst case and specifies that all file organizatio ns with support for all operations be included. If the user li nks to the RMS-11 Resident library, the support of one or all file organizations and operations requires the same amount of spa ce (8KW, 2 APR's) from the user task. If the RMS-11 Resident library is not supported on your system, the RMS-11 code would require appr oximately 24KW of user space. Pascal Record Management User's M anual PAGE 2-6 Preparing for PRM I f you DO NOT link to the RMS-11 Resident library, you should do th e following: 1. Make your own copy of file RMSIni.Src to be used by your task(s) with the same file access requirement s. Change the file name to make sure your task references your copy of RMSIni. 2. Modify th e entries following the $ORG MACRO. Refer to the RMS-11 Macro-11 Reference Manual, paragraph 1.1.2. Specify only the file organization(s) and file access operations requ ired by your task. 3. Compile and assemble the modified modul e. 4. Reference the module in your source code. 5. Reference the modified module during the task build. In addition to indicating the code that is to be linked to the task, RMSIni also specifies a dynamic memory management routine. The routine is defined to RMS-11 as a GSA (Get Space) routine. It is essential that RMSIni be located in the .ROOT segement of an overlayed task. The routine has to be av ailable for RMS-11 at all times. It is also essential that the RMSI ni routine be executed one time prior to any other PRM routines. 2.7 Task Building When task building, the P RMPAS.OLB must be referenced in the task builder command or overlay description file. If you are using the RMS-11 Resident library, use the DEC supplied overlay description and reference RMSRES wi th the RESLIB command file option. If you are using overlays, selec t on of the standard DEC supplied overlay description files or use t he DEC supplied command file MAKRMSODL.CMD to help tailor an ODL file to fit your specific needs. An example of an command and ODL file is provided in Appendix C. 2.8 User Space Optimizat ion If your application requires access to files that are no t opened simultaneously, file buffer of TYPE RmsfileDesc can Pascal Record Management User's Manual PAGE 2-7 Prepar ing for PRM used for more than one file. It is important that a file be closed successfully before the buffer is used for anot her file. In most cases, the RetRecord and StoRecor d TYPE buffers can be shared with no problems. Only when i t is more efficient to maintain access attributes for seperate f iles should seperate buffers be allocated. User rec ord buffers can be shared to reduce the space used. Paragraph 2 .3 details shared and non-shard user record buffers. The RMSIni routine should be modified to fit your applica tion requirements. Paragraph 2.5 describes the modifications to RMSIni. 2.9 PRM Pit-Falls PRM routines perform a certain amount of error checking to make certain that th e PRM User follows RMS-11 and PRM usage guide lines. There is howeve r certain guide lines that cannot be checked because PRM routines are serperatly compilied. PRM has to depend on the PRM user for items l isted below. If the minimum requirements listed below are not met , unpredictalbe error will result. 2.9.1 Record Siz e PRM routines depend on the PRM User to supply the record buffer. The user also has to supply PRM routines with the size of the record buffer. Since PRM routines are external, c ompiled seperately and a general set of routines supporting any RMS file, there is no way that the routines can accuratly check buffer sizes allocated in the MAIN PRM User program. PRM depends on the PRM User to inform the external routines of the size of the record t o be retrieved or stored. If the PRM User defines a record size that is larger than the record buffer actually allocated, PRM (RMS) has to assume the record size is correct. When a record is retriev ed from the file user code (or data) will be destroyed if the all ocated buffer is smaller than the PRM User supplied record size. PRM checks the user record size specified in the RMSFileDesc TYPE buffer when the file is opened. The user mus t specify the exact file record size. This is to ensure that the user knows the characteristics of the file that is Pascal Record Manageme nt User's Manual PAGE 2-8 Preparing for PRM being opened. A PRM error code will be returned if the file a nd user declared record size do not match. This however is only a check and does not ensure that user code will not be destroyed. The PRM user should define a CONSTANT to define the size of the log ical record buffer. The same CONSTANT should be loaded into the RMSFileDesc buffer before the PRMOpe. 2.9.2 RMS Initialization If the RMSIni routine is not executed fi rst in your task, unpredictable results will occur. RMS-11 assumes the the GSA routine (declared within the RMSIni module) is const antly available for use. If the GSA routine is not in the .ROOT segment of your task, RMS-11 will fail. Refer to paragraph 2.4 for detailed information concerning modification of R MSIni. 2.9.3 File Sharing If the file be a ccessed is to be used by multiple tasks simultaneously, and your tasks specifies write access to the file, the target bucket of a reco rd access will be locked. When a bucket is locked, the reco rds in the bucket are unaccessable by other users. When your application has completed the access (or timed-out if waiting for an event), the bucket should be released by executing the PRMFre rou tine. If your application specifies READ access to the file, buckets are never locked. CHAPTER 3 Detailed Description of PRM Buffers This chapter gives detailed description of all the PRM pre-de fined buffers that have to be used for the PRM interface. Brief descriptions of the fields of each buffer are provided. D etailed description of data required by the field can be located in the RMS-11 User's Guide. 3.1 RmsFileDesc - File Description The following describes the fields in the RMSFileDesc type buffer that are used to create an RMS file. 1. ORG - File Organization 1. Description : The file or ganization of an existing file to be opened or a file to be created. Use one of the key word scalar t ypes to define a Sequential (SEQ), Relative (REL) o r Indexed (IDX) file. 2. Default : None 2. FileName - File Name 1. Description : Full file specification of the file being created. The file specification is defined by t he operating system being used. 2. Default : None 3. LogChan - Logical Channel Number 1. De scription : The logical channel number for the file I/ O operations. Refer to the task builder manual options UNITS for details. Pascal Record Management User's Manual PAGE 3-2 Detailed Description of PRM Buffers 2. Default : None 4. Allow - System File Access 1. Description : What other tasks can do to this file while you have the file open. If you want exclusive access to the file specify NOSHARE. If you will allow others to open the file, specify SHARE. I f any other task has previously opened the file with NOSHARE, an error will be returned when you attempt to o pen the file. 2. Default : Share 5. Access - Program Access 1. Description : Specifies wha t the program opening the file can do while the file is open. Specify PREAD for read only, PWRITE for write only and PBOTH for both ready and write access. If PWR ITE or PBOTH is specified, target buckets are locked. The bucket remains locked until another target bucket is specified or the PRMFre call is used. If the file is shared, bucket locking for long periods of time should be avoided. 2. Default : Read Only 6. RecordSize - File Record Size 1. Description : The full size of the record of the file being created or opened. This should be defin ed as a Costant and also be used to define the size of the logical record buffer used. If an existing file is being opened, the exact file record size has to b e specified or a PRM error code will be returned. 2. Default : None 7. DeferWrite - Deferr ed Bucket Write to File 1. Description : Valid for in dexed files only. Normally storage of each logical record causes the contents of the entire RMS bucket to be stored in the file to ensure the contents of th e file contains the most up-to-date data. If deferred write is selected, the bucket will not be written to the file until the bucket is full. Pascal Record Management User's Manual PAGE 3-3 Detailed Descriptio n of PRM Buffers 2. Default : No Deferred Write 8. Unlock - Unlock the file 1. Descriptio n : The file will not be locked as a result of the im proper closing of the file due to program abort. This s hould not be used for RMS Sequential files. 2. Default : Lock the file if improperly closed 9. ObeyFill - Obey Bucket Fill Number 1. Description : Each RMS bucket may have a fill number specified wh en the file is created. Since the PRM user cannot speci fy the value of this parameter during PRMCre, thi s feature is only valid when opening an existing file c reated with RMSDEF or RMSDFN. 2. Default : Fill the bucket as much as possible. 10. MassIns ert - Mass Insert records 1. Description : Used for RMS indexed files only. Normally RMS will traverse the in dexed tree with each record insert. If this option is selected, the record is placed in the file at the pres ent pointer location. Extreme caution should be exercised when using this option. Refer to the RMS MACRO-11 Reference Manual for details. 2. Default : No mass insert 11. FileEnd - File Pointer to End-Of-File 1. Description : When opening an exist ing RMS Sequential file this option can be used. T he option will position the file pointer to the end of the file in preparation for the addition of records to the file. 2. Default : File po inter to the beginning of the file 12. RecForm - Logical Record Format 1. Description : Th e record format of fixed length, Pascal Record Management User's Manual PAGE 3-4 Detailed Description of PRM Buffers variable length or stream format records. Specify FFIX for a fixed length record, FVAR for a variable length record and FSTREAM (sequential fil e only) for stream format. 2. Default : Fixed 13. Allocation - File Block Initial Allocation 1 . Description : The number of disk blocks that sho uld be initially allocated to the file during file crea tion. 2. Default : 0 blocks 14. Buck etSize - RMS Bucket Size 1. Description : A logical uni t of storage for RMS files is known as the bucket. Spe cify the number of blocks for each bucket. 2. Default : 1 15. EXTQUA - Default File Extensio n Quatity 1. Description : If the file is dynam ically extended, this number specifies the number of blocks the file will be extended. Should always be specified to avoid file header entries and hence file access performance degradation. 2. Default : 1 block extended 16. Contiguous - Allocate the file in Contiguous Blocks 1. Description : The file siz e specified by the allocation field is allocated in contigous disk blocks. If the contigous blocks are not available, an error is returned. 2. Default : Non-contiguous 17. Temporary - Tem porary File 1. Description : The file will be deleted automatically by the operating system when th e file is closed. The file is in existence only while the file is open. Pascal Record Management User's Manual PAGE 3-5 Detailed Description of PRM Buffers 2. Default : Permanent File 3.2 Re tRecord - Record Retrieval The following gives a description of the fields in the PRM retrieval buffer RetRecord: 1. KEYNUM - Key Number 1. General : This value is usually used only for indexed files except if th e access if by RFA. The field is not used if the fuke file organization is not an indexed file or the access is not by RFA. 2. Indexed Key : If the Seach Type (defined below) is EQ, GT or GE then this entry is the Indexed key number that RMS is to use for data record retrieval. This number can be form 0 (primary key) to n-1 where n is the numb er of keys in the indexed file. 3 . RFA : If the Search Type (defined below) is RFA the n the Key Number is the RFA number. Any file organizat ion can use this type of access. Sequential fil es can use random access if using RFA access. Refer to paragraph 1.4 for details. 4. Default : None 2. SEARCH - Mode of Record Search 1. EQ, GT, G E : Search types of EQ, GT or GE are for access of I ndexed records only. These search types define the comparison criteria for retrieving records. The comparison is made between the data in the KEYDATA field of this buffer (defined below) and the conte nts of the file key data for the key specified in the KE YNUM (defined above) field. 2. RF A : The RFA search type can be for any file organiza tion. The KEYNUM field must be loaded with the RFA n umber. 3. NEX : The NEX search type can be used to acce ss the NEXt record in the file. This mode is used Pascal Record Management User's Manual PAGE 3-6 Detai led Description of PRM Buffers to sequential access records from a Relative or Indexed file. This is the only record access for RMS Sequential files. This mode is used after positioning the record stream to a fil e position using a random access search. The random ac cess search is executed using PrmRet witha GET or FIND operation. 4. REC : The REC searc h type specifies that the KEYDATA field (described below) is a record number of a Relative file type. 3. RECSIZE - Logical Record Size 1. Input : You must specify the size of the record you want retrieved prior to each PrmRet operation. Since the field is both an input and output, the reco rd size loaded will be destroyed and therefore must be reloaded. This is an effort by PRM to make sur e the user knows the record size. RMS will transfer all or part of the record fr om the file. If you specify recsize < file record s ize, only part of the record will be transferred a nd the RMS error ERRTB will be returned. If you sp ecify recsize > file record size, the record buffer w ill be partially filled with the record and PRM will lo ad RECSIZE with the size of the record transferred to your record buffer. If yo u specify a record size > than the allocated buffer , PRM will assume the record size to be correct. The record will destroy data following the record buffer . Refer to paragraph 2.9 for details. 2. Output : The size of the record retrieved from the RMS file is loaded in this field and passed bac k to the calling program. This may be useful informati on when variable length records are used. 4. RFAOut - RFA output from PRM 1. Descriptio n : The RFA (Records File Address) generated by R MS, unique for each record in the file is available to t he calling program. For details refer to paragraph 1 .4. Pascal Record Management User's Manual PAGE 3-7 Detailed Description of PRM Buffers 5. KEYSIZE - Size of the key data 1. Description : Valid for indexed file s only. If you want a generic search, specify the search type of EQ, GT or GE then specify a key size that is < the full key size of the specified key in KEYNUM. For example, if the key data is for zip codes and you want all records with zip codes that begin with 5501, load KEYDATA with 5501, search=EQ, KEYSIZE=4, execute a PRMRet and the first record in the file with 5501x will be returned. Switch to sequential access (NEX seach type) and call PR MRet to access all the records within the generic zip code range. 2. Default : None 6. KE YDATA - String or Integer key data 1. Indexed : The stri ng or integer value the PRMRet operation is seaching for in the indexed file. RMS will search the file for a key according to the search mode specified in the Search field (above). 2. Relative : The relative record number of a RMS relative file. 3.3 StoRecord - Record Storage The s torage type operations use the StoRecord type buffer. The foll owing describes the StoRecord fields: 1. RecSize - Record Siz e 1. Description : The size of the data record you want stored in the RMS file. You can specify a record size <= to full record size for files with variable record formats. If you specify a record size > the allocated record buffer, data that is no t part of the logical record (garbage following the reco rd buffer) will be assumed as part of the record. The record in the file will be corrupted. 2. Default : None Pascal Record Management User's Manual PAGE 3-8 Detailed Description of PRM Buffers 2. RFAOut - The RFA generated by RMS-11 when the record was stored in the file. The RFA can be stored internally if the record is to be accessed at a later withi n the same application. 3. KEY - RELATIVE Files only, The rel ative record number of the target cell for the record to be stored. 3.4 IdxKeyDesc - Indexed Key Description This buffer is used to define the keys of a dynamically cr eated indexed file. The buffer is loaded and PRMKey routine is calle d to describe each key of the file being created. The keys must be d efined in ascending order. The following describes the fields of the record type IdxKeyDesc: 1. KeyNum - Ind exed Key Number 1. Description : The indexed key number that the record describes. This can be any number from 0-255. 2. Default : None 2. KeyPos - Key Position in the Record 1. Description : The starting byte position (start with 0) of the key in the logical record. 2. Default : None 3. KeySiz - Size of the Key 1. Description : Size in bytes of the key defined. 2. Defau lt : None 4. KeyTyp - Key Type 1. D escription : The key can be of type string or integer . Other types of keys are available but not supported by PRM. 2. Default : String Pascal Record Managemen t User's Manual PAGE 3-9 Detailed Description of PRM B uffers 5. KEYDUP - Duplicate Key 1. Description : If the key being defined allows du plicate entries, specify a "Y" in this field. 2. Default : No Duplicates 6. KEYCHG - Key value change 1. Description : Valid for alternate keys only. If selected the value of the key may be altered on a record update. 2. Default : No Changes 7. KeyNul - Key Null value 1. Description : Vali d for alternate keys only. If a keyed field of the rec ord is not valid for all records in the file, a null k ey value can be specified. If a null key value is defined and the field if FILLED with the null key value during a record insert (PRMSto - PUT) there will be no entry in the alternate key structure. Example: Key in an employees record describing the name of the company softball ball team the employee belongs to. A null key value should be specified so unneccessary entries in the tree struc ture for the alternate key are not entered for employe es that are not on any softball team. 2. Default : No Nu ll 3.5 User Defined Record Buffers The RecDef Record TYPE has to be modified to define the fields of yo ur logical record. Multiple CASE entries can be used to define all t he logical records. Once the buffer is defined, one or more recor d buffers should be allocated in the user space. Refer to paragraph 2.3 for more detail. CHAPTER 4 Detailed Description of PRM Routines Th is chapter describes the PRM calls used to interpret the User's re quest and pass the request to RMS-11. 4.1 General Use To use any of the PRM calls, the user must properly prepare the task with the proper buffer types and external calls . The following list the coding rules to follow for PRM calls: 1. The RMSIni routine must be executed before any other PRM routine is called. 2. The calling routines mu st be OMSI Pascal V1 only. Pascal V2 main program routin es will not work for the present version of PRM. Pascal V1. 2H code has not been tested. If used, specify the con tents of all fields rather than taking the defaults. 3. Once a file has been opened, file work space is allocated in the buffer of TYPE RmsFileDesc you provide on the open. This buffer is used for all fil e operations on that file. 4. A variable of TYPE RMSStatus wo rd should be checked after ALL PRM calls. The value of + 1 will inidicate success, a negative value will indicate fai lure. The negative value can be a PRM error or an RMS type error. If an RMS error, word 1 of the status will be loaded with the RMS STS and word 2 with the RMS STV value. Definition of these errors can be found in the RMS User or RMS Macro Reference Manuals. The PRM returned error codes are defined in the CONST sectio n of [300,47]PRMPrefix.Pas and Appendix D. Pascal Record Management User's M anual PAGE 4-2 Detailed Description of PRM Routines 5. Do not perform any record operations unless the file has been properly opened and initialized. If PRM routines (PRMOpe or PRMCre) do not successfully open the RMS file all PRM record operations will be in hibited and error code PrIni will be returned in word 1 o f the status. If PRM allow record operations on a inproperl y opened file, unpredictable results could occur. 6. If the RmsFileDesc buffer is used for multiple files, care must be used. When using the buffer for multiple files, be sure to close the file before re- use then reload the buffer with the new parameters describin g the file. 4.2 File Access and Creation The following paragraphs describe the PRM routines that are used t o access or create RMS-11 files. All file types are supported for bo th the access to existing files and creation of new files. The following describes the requirements for the use of each file type external procedure and possible errors that can occur from their u se. 4.2.1 PrmClo This procedure is used t o close an open RMS file. The RMSFileDesc type buffer passed to t he procedure inidicates the file to be closed. The RMS Sts and Stv values are passed backed to the calling program. These values sh ould be checked to ensure the close was successful. 4.2.2 PrmCre This procedure is used to dynamically create a n RMS file. All file organizations can be created by simply definin g the file type you want created and loading the remaining file creation fields in the RMSFileDesc record. Before calling the PRMCre routine, the PRMKey routine must be called at least one t ime. Pascal Record Management User's Manual PAGE 4- 3 Detailed Description of PRM Routines 4.2.3 PrmKey This call is used when you desire to create an RMS in dexed file. Call PrmKey to define each key of the indexed file pri or to the PrmCre call. PrmKey can be called multiple times defining a new key with each call. The keys are defined in a buffer of type IdxKeyDesc. When defining more than one key, define the keys i n ascending order starting with the primary key (key 0). RMS will g enerate an error on the create if you do not follow this convention. 4.2.4 PrmOpe This procedure will open an exising RMS type file. The file can be previously defined with an RMS utility (RMSDef or RMSDfn) or by any other program that has cre ated the RMS-11 file. When the file is opened, P RM FATAL conditions may be detected. The error is the resul t of not following PRM conventions. The error code is returned in the PrmStatus. A description of these error codes is described in Appendix D. These type of errors should be corrected immediately. If PrmOpe does not properly initialize, ALL record operations on the file will be rejected by PRM record o perations. This feature is for the user that ignores the error c odes returned from PrmOpe. If the file is not properly opened and re cord operations are performed, the task may abort with ODD ADDRESS (or other) type fatal errors. A recordsize specified in the RmsFileD esc buffer <> file record size is considered improper initializat ion. 4.3 Record Access and Storage 4.3.1 P rmDel This procedure is used to delete a record previo usly located with a SUCCESSFUL PrmRet PGET or PFIND operation. The user should make sure that the file pointer is properly positioned before calling this procedure. That is, the user mu st check the PrmStatus code returned from the PrmRet operatio n for a success code (+1) before calling PrmDel. Pascal Record Management Us er's Manual PAGE 4-4 Detailed Description of PRM Routi nes 4.3.2 PrmFre This procedure is used to unlock a bucket so other tasks can access records in the bucekt. B uckets are locked only if the file is opened with ACCESS of PWRITE or PBOTH. The Access field default of Read only should be selec ted if your application is only going to read data. This access wi ll not lock buckets and therefore this call would never have to b e used. If you specify a write or read/write a ccess, the RMS bucket will be locked when you access records in the bucket of the file. The lock will remain on the bucket until 1) your application accesses another record not in the presently locked bucket, 2) your application closes the file or 3) your application executes the PrmFre call. If your application is updating or writing records in a shared file, this call shoul d be kept in mind. The call is especially useful when dealing with i nteractive type programs. The operator response should be timed if the application is holding a bucket locked and the continutation of the program is dependant on the operator (who may have just go ne on a coffee break). 4.3.3 PrmRet This call is used to retrieve a record from a properly opene d RMS file. Before access to the RMS file is attempted, a check is made to see if PrmOpe has been called and has properly opened the file. If the file has not been opened properly, a FATAL messa ge will be printed and the RMSRet operation will not be perform ed. Load the RetRecord buffer prior to using this call. With the call, specify a PGET or PFIND record operation. Refer to the RMS-11 User's Guide for detail concerning GET and FIND r ecord operations. 4.3.4 PrmSto This proce dure is used to store a record in a file that has been properly opened with PrmOpe or PrmCre. The PrmSto Call defines the type of op eration with the first parameter. If the PrmSto describes an PUPDAT E, the store must be preceded by a successful PRMRet operation. I f you define a PPUT Pascal Record Management User's Manual PAGE 4-5 Detailed Description of PRM Routines operat ion, the record in stored in a new location in the RMS file. Refer to the RMS-11 User's Guide for detail concerning the PUT and UPDATE record opeations. APPENDIX A PRM Program Example - Access to existing files PROGRAM PrmE xample ; CONST IdxLch = 3 ; { of the first 6 UNITS } RelLch = 4 ; { ch. 3 4 avail. by default } SeqLch = 7 ; { must spec. UNITS=n for units > 6 } ExaRecSize = 28 ; { full record size } { example labels and siz es follow - user defines buffer sizes and labels } Key0Size = 4 ; { user def ines size of largest key } Key1Size = 3 ; { user defines these labels and si zes } TYPE RecDef1 = RECORD { user defined record type 1 } Se cNum : ARRAY [1..4] OF CHAR ; { section number } SecSup : ARRAY [1..3] OF C HAR ; { sup initials } Fill : char ; SecDesc : ARRAY [1..20] OF CHAR END ; { RECORD } RecDef2 = RECORD EmpNum : ARRAY [1..6] OF CHAR ; EmpName : ARRAY [1..30] OF CHAR ; END ; { RECORD } KeyDef = R ECORD CASE integer OF { user defines keylabels and sizes, as many as req. } 1 : ( Idx0 : ARRAY [1..Key0Size] OF CHAR) ; { index file prim. key 0 } 2 : ( Idx1 : ARRAY [1..Key1Size] OF CHAR) ; { index file alt key 1 } 3 : ( RecNum : TwoWord ) ; { REL file rec. , Org=REL, Search=REC } END ; {********************************************************************** * BEGIN PRM CONST and TYPE FILE [300,47]PrmPrefix .Pas Refer to file [300,47]PrmCalls.Pas for Procedure Calls PRM Program Example - Access to existing files PAGE A-2 *********************************************************************** M aintainer: KGT Version 1.3 } CONST { * Error values returned in sta tus word 1 and word 2 with each PRM call. * All errors set Status[1] to a n egative value. *** ALL PRM CALLS SHOULD CHECK FOR A STATUS[1] RETURN VAL UE OF < 1. * All DEC Rms errors are between -1 and -2000 decimal. * All PRM errors are between -5000 and -5100 decimal. Symbolic Status[1] Status[2] Description } PrINI = -5001 ; { NA A re cord operation was attempted on a file that was not properly opened by Prm Ope or PrmKey. Check proper open or create of a file before continui ng with record ops. } PrRNE = -5002 ; { Lch An existing file was ope ned and the user program did not specify the correct file max. record size. The logical channel no. of the file attempting to open is in word 2. All record operations will be inhibited. Use rms utility RMSDSP to de termine actual record size and correct user recordsize. } PrRsz = - 5003 ; { RecSz During a PrmRet call a record size must be specified so Prm knows the size of the record to be returned. The record size field is an input and output field therefore is must be loaded before EACH PrmRet . A PrmRet rms failure will set the record size field to 0. T he record size specified by the user is returned in word 2. } PrKY0 = -5004 ; { NA During a PrmKey call the primary key must be specified fi rst. } PrKNS = -5005 ; { NA During a PrmCre call a indexed file organization was specified and no primary key defined. You must use PrmK ey to define at least a primary key for indexed files. } PrAsc = -5 006 ; { NA Keys defined to PrmKey were defined in a non-ascending key ord er. } {Erxxx STS STV Rms error sts and stv error val ues are PRM Program Example - Access to existing files PAGE A-3 returned for all rms errors. The same symbo lic values used by DEC (without $) are used to describe the errors. Not al l rms error codes are provided but may be added. Refer to index of R ms User Ref. } ErDup = -544 ; { insert duplicate rec with no dups all owed } ErEof = -592 ; { record processing reached end-of-file } ErFac = - 656 ; { record opr does not match declared access } ErFnf = -736 ; { file n ot found during open } ErRlk = -1440 ; { target record was locked by another task } ErRnf = -1472 ; { random get or find did not locate record } NameSize = 30 ; { sz of RMS input file name, do not alter } TYPE TwoWord = ARRAY [1..2] OF integer ; { record number size } { Following R ecDef and KeyDef RECORDS are EXAMPLES only - define similiar RECORDS in MAIN Program TYPE specifications RecDef = RECORD user defines field names and sizes CASE integer OF 1 : (FXDat1 : ARRAY [1..10] OF CHAR ; FXDat2 : integer ) ; 2 : (FYItem1 : ARRAY [1..30] OF CHAR ; FYItem2 : REAL ) ; END ; KeyDef = RECORD CASE integer OF " user defines keylabels and sizes, as many as req. " 1 : ( KeyX : ARRA Y [1..10] OF CHAR) ; 2 : ( KeyY : ARRAY [1..12] OF CHAR) ; 3 : ( R Num : TwoWord ) ; " use this def. of relative rec. if req. " END ; } RmsFileName = ARRAY [1..NameSize] OF CHAR ; { file name, do not alter } RmsStatus = ARRAY [1..2] OF integer ; { returned rms status codes } { T he following record holds the file being descibed with options selected by t he user. Space for this buffer is allocated in the user area. Rab and Fab for the file is allocated within this buffer. The address of this buffer is initially passed to Open then passed with all record operations (get, put, update, delete, find and close) so the routines know what file the operati on is being performed on. } OrgTypes = (SEQ,REL,IDX) ; { block i/o not sup ported } AllowTypes = (Share,NoShare) ; { what others can do } Access Types = (PRead,PWrite,PBoth) ; { what you can do to the file } FormType = (FF IX,FVAR,FSTREAM) ; { record format type } PRM Program Example - Access to ex isting files PAGE A-4 { iF FIELD NOT ALTERE D, DEFAULT WILL BE SELECTED } RmsFileDesc = RECORD { -- Use with PRMOPE -- } Org : OrgTypes ; { spec. file type, no SEQ } FileName : RmsFileN ame ; { full spec. of rms file, NO DEFAULT } LogChan : integer ; { spec. ch . n, NO DEF., n<= TKB UNITS=n } Allow : AllowTypes ; { what others may do w ith file, DEF Share } Access : AccessTypes ; { what you may do to the file, DEFAULT Read } RecordSize : INTEGER ; { MUST = max. file rec. size, NO DE FAULT } Windows : INTEGER ; { no. of ret. windows, DEFAULT usually 7 } { enable the following options with a capital "Y", ANY OTHER = DEFAULT } DeferWrite : CHAR ; { IDX, defer write, def. write each record } Unlock : CHAR ; { REL IDX, don't lock if abort, DEF. LOCK } ObeyFill : CHAR ; { obey bucket fill numbers, DEF. FILL TO MAX } MassInsert : CHAR ; { IDX, ref. rms-11 macro ref. man. rab rop } FileEnd : CHAR ; { SEQ only, place f ile stream at end of file } { file creation fields } RecForm : Form Type ; { rec. format, FSTREAM for seq., Def.= FFix } Allocation : TwoWord ; { no. blocks allocated to file, DEF. 0 BLKS } BucketSize : integer ; { da ta bucket size, DEFAULT BUCKETSIZE = 1 } ExtQua : integer ; { no. blks dyna mic extend file, DEFAULT 1} { Enable following with capital "Y", if not loa ded, default is selected } Contiguous : CHAR ; { create a contiguous file, DEF. FRAGMENTED } Temporary : char ; { delete the file when closed, DEF. NO DEL. } WorkSpace : PACKED ARRAY [1..160] OF char ; END ; { RmsFileDe sc Record } SearchTypes = (EQ,GT,GE,RFA,NEX,REC) ; { for GET use KeyData(E Q'=',GT'>', GE'>='), RFA, next seq. rec(NEX) or Rec. (org =REL) } ThreeWord = ARRAY [1..3] OF Integer ; { for RFA's, big file huh } RecOps = (PGET,PFIND,PPUT,PUPDATE) ; { PRM record operations } RetRecord = RE CORD { - USE with PRMRET, INPUT - to GET and FIND - INPUT/OUTPUT ref. to PR M } KeyNum : Threeword ; { INPUT- IDX Key or RFA, search defines } S earch : SearchTypes ; { INPUT - spec. search opr } RecSize : integer ; { IN PUT - sz rec. to GET, (sz of rec. buffer) OUT PUT- sz rec. returned to user rec. buf } RFAout : ThreeWord ; { OUTPUT- val id if search <> RFA } KeySize : integer ; { INPUT - size of key data, <= fu ll key size } KeyData : KeyDef ; { INPUT - IDX or REL, key string or rec. } END ; { RetRecord RECORD Definition } StoRecord = RECORD { US E with PRMSTO, Input to PUT and UPDATE - INPUT/OUTPUT ref. to PRM } RecSi ze : integer ; { INPUT - spec. part or all or rec. buffer data to be stored, <= full rec. sz } RFAOut : ThreeWord ; { OUTPUT - rfa where record was stored } Key : KeyDef ; { INPUT - REL ONLY , spec. rec. for store } END ; { StoRecord Record } PRM Program Examp le - Access to existing files PAGE A-5 KTyp e = (StrKey,IntKey) ; { string or unsigned integer key type } { Use with MULT IPLE calls of PRMKEY to define ALL keys of an indexed file. MUST be used a t least once prior to PrmCre of an indexed file type } IdxKeyDesc = RECORD KeyNum : Integer ; { key of ref. , def. asc. order, start 0 } KeyPo s : Integer ; { byte position of key in rec., start byte 0 } KeySiz : Int eger ; { size of the key defining, max. = 255 } KeyTyp : KType ; { string or unsigned integer, def.=string } KeyDup : char ; { 'Y' to allow duplic ate keys, def. no dup } KeyChg : char ; { 'Y' for key changes, alt. only, def no chg } KeyNul : char ; { null key value, alt. string keys only } END ; { IdxKeyDesc } {********************************************* ************************** * END PRM CONST and TYPE * ********************************************************* ************** } VAR chtfile : text ; Rlen : integer ; i : integer ; SeqRfas : ARRAY [1..4] OF ThreeWord; { used to store rfa's } IdxFile : RmsFileDesc ; { file parameters for idx file } IdxStoBuf : Sto Record ; { store buffer, shared by rel file } RelFile : RmsFileDesc ; { fi le parameters for rel file } SeqFile : RmsFileDesc ; { file parameters for seq. file } SeqStoBuf : StoRecord ; { store buffer for sequential file } RecBuf : RecDef1 ; { same record buffer for all files } RetBuf : RetRecord ; { retreival buffer, same for all file } RfaBuf : Threeword ; { returned rf a from record ops } Status : RmsStatus ; { returned rms status codes } { ********** INCLUDE ONLY PRM CALLS REQUIRED ********** } { close the file } PROCEDURE PRMClo ( VAR Filebuf : RmsFileDesc ; { ref. to file to close } VAR Status : RmsStatus ) ; { STS and STV } EXTERNAL ; { Delete a record, must be preceded with successful GET or FIND ( PRMRet) } PROCEDURE PRMDel ( VAR FileBuf : RmsFileDesc ; { ref. to file to dele te rec } VAR Status : RmsStatus ) ; { STS and STV } EXTERNAL ; PRM Program Example - Access to existing files PAGE A-6 { Open an RMS Indexed file previously def ined with RMSDEF } PROCEDURE PRMOpe ( VAR FileBuf : RmsFileDesc ; { load fiel ds before open } VAR Status : RmsStatus ) ; { status of Sts and Stv } EXTERNAL ; { Record retrieval from the specif ied file } PROCEDURE PRMRet( Operation : RecOps ; { define GET or FIND } VAR FileBuf : RmsFileDesc ; { ref. to file for access } VAR RetData : RetRecord ; { load with type of opr } VAR RecBuf : RecDef1 ; { rec. buf connected to use } VA R Status : RmsStatus ) ; { status of STS and STV } EXTERNAL ; { Store a record in the specified file } PROCEDURE PRMSto ( Operation : RecOps ; { define PUT or UPDATE } VAR FileBuf : RmsFileDes c ; { ref. to file for store } VAR StoData : StoRecord ; { s tore variables } VAR RecBuf : RecDef1 ; { rec. buf connect ed to use } VAR Status : RmsStatus); { STS and STV } EXTERNAL ; { Define a routine to GET and DISPOSE heap space, e xecute first in root seg } PROCEDURE RMSIni ; EXTERNAL ; PROCEDURE OpenF iles ; BEGIN { open an rms indexed file } WITH IdxFile DO BEGIN Or g := IDX ; { file orgainization code } FileName := '[300,47]PrmExa.Idx ' ; { file name } LogChan := IdxLch ; { file logical channel n umber } Access := PBoth ; { both read and write to the file } Record Size := ExaRecSize ; { get full record } END ; { all fields not specified w ill take their default condition } PrmOpe ( IdxFile, Status ) ; IF Status[1] < 1 THEN writeln('Idx Open error, code=',Status[1], Status[2] ) ; { open and rms relative file } WITH RelFile DO BEGIN Org := REL ; FileName := '[300,47]PrmExa.Rel ' ; LogChan := RelLch ; Access := PB oth ; { both read and write to the file } RecordSize := ExaRecSize ; E ND ; PrmOpe ( RelFile, Status ) ; IF Status[1] < 1 THEN writeln('Rel Open erro r, code=',Status[1], Status[2] ) ; PRM Program Example - Access to existing files PAGE A-7 { open an rms sequential file } WITH SeqFile DO BEGIN Org := SEQ ; FileName := '[300,47]PrmExa.S eq ' ; LogChan := SeqLch ; Access := PBoth ; { both read and write to the file } SeqFile.FileEnd := 'Y' ; { pointer to end of file for PrmSto } RecordSize := ExaRecSize ; END ; PrmOpe ( SeqFile, Status ) ; IF Status[1] < 1 THEN writeln('Seq Open error, code=',Status[1], Status[2] ) ; END ; { PROCEDURE Openfiles } PROCEDURE AddNewRec ( VAR TarFile : RmsFileDesc ; VAR TarRec : RecDef1 ; VAR TarStoBuf : StoRecord ) ; PROCEDURE StoreIt ; BEGIN TarStoBu f.RecSize := ExaRecSize ; { specify each time } PRMSto ( PUT, TarFile, TarStoBuf, RecBuf, Status ) ; writeln('store ', status[1],status[2]); EN D ; BEGIN TarStoBuf.RecSize := ExaRecSize ; { spec. record size to store } { load the record buffer } TarRec.SecNum := '86A ' ; TarRec.SecSup := 'AAC' ; TarRec.SecDesc := 'some computer nurds ' ; StoreIt ; TarRec.SecNum := '86C ' ; TarRec.SecSup := 'TMT' ; TarRec .SecDesc := 'ALL computer nurds ' ; StoreIt ; TarRec.SecNum := '86B ' ; TarRec.SecSup := 'WHO' ; TarRec.SecDesc := 'more computer nurds ' ; S toreIt ; END ; { PROCEDURE AddNewRec } PROCEDURE XferToSeq ; BEGIN { find the first record by retreiving with a search of GE and setting a key value < the first record key entry of the file } RetBuf.KeyNum[1] := 0 ; { lo ad IDX key for retreival of records } PRM Program Example - Access to exis ting files PAGE A-8 RetBuf.Search := GE ; { s et search type } RetBuf.KeySize := 1 ; { size of key data to search for } RetBuf.KeyData.Idx0 := ' ' ; { set the key to blanks } RetBuf.RecSize := ExaRecSize ; { may be destoyed, load each time } PrmRet ( FIND, IdxFile, Ret Buf, RecBuf, Status ) ; { find 1st rec. } IF Status[1] < 1 THEN writ eln('idx retreive error=',status[1], status[2]) ELSE BEGIN writeln ; writeln('begin xfer'); i := 1 ; RetBuf.Search := NEX ; { set sequential mode of retrieval } REPEAT RetBuf.RecS ize := ExaRecSize ; { may be destoyed, load each time } PrmRet( GET, IdxFile, RetBuf, RecBuf, Status ) ; { get a record } IF Status[1] < 1 THEN writeln('GET fail = ',status[1],status[2] ) ELS E BEGIN { no need to xfer buffer, seq and idx ha ve same rec. buffers } RetBuf.RecSize := ExaRecSize ; { load ea ch time } PRMSto ( PUT, SeqFile, SeqStoBuf, RecBuf, Status ) ; IF Status[1] < 1 THEN writeln('PUT fail = ' ,status[1],status[2] ) ELSE IF i < 5 TH EN { Store 4 RFA's for retreival } BEGIN SeqRfas[i,1] := SeqStoBuf.RfaOut[1] ; { save the RFA } SeqRfas[i,2] := SeqStoBuf.RfaOut[2] ; { save the RFA } SeqRfas[i,3] := SeqStoBuf.RfaOut[3] ; { save the RFA } writeln('Stored at RFA=', SeqRfas[i,1]:4, Seq Rfas[i,2]:4,SeqRfas[i,3]:4, ' data=', RecBuf.Sec Num, RecBuf.SecSup, recBuf.SecDesc ) ; i := i + 1 ; END ; END ; UNTIL Status[1] = ErEof ; { get all record, go till end-of-file } writeln('xfer from idx to seq complete') ; END ; { ELSE } END; { PROCEDURE XferToSeq } PROCEDURE RetByRfa ; PROCEDURE GetRecord ( i : integer ) ; BEGIN RetBuf.KeyNum[1] := SeqRfas[i,1] ; { load keynu m with the rfa } RetBuf.KeyNum[2] := SeqRfas[i,2] ; RetBuf.KeyNum[3] := SeqRfas[i,3] ; RetBuf.RecSize := ExaRecSize ; { load each time } PrmRet( GET, SeqFile, RetBuf, RecBuf, Status ) ; { get the record } IF Sta tus[1] >= 1 PRM Program Example - Access to existing files PAGE A-9 THEN { write the record } writeln('RFA NO.= ', SeqRfas[i,1]:4, SeqRfas[i,2]:4, SeqRfas[i,3]:3,' data=' , RecBuf.SecNum, RecBuf.SecSup, recBuf.SecDesc ) ELSE writeln('RFA access error=',status[1],status[2]) ; END ; BEGIN wr iteln; writeln('Begin random retreival from a seq. file by RFA') ; RetBuf.Rec Size := ExaRecSize ; { record size chg. by PRMRet that failed due to ErEof, must reload } RetBuf.Search := RFA ; { set search to access by RFA } GetRecord ( 4 ) ; { get record spec. in array [4] } GetRecord ( 1 ) ; GetRecord ( 3 ) ; GetRecord ( 2 ) ; END; { PROCEDURE RetByRfa } PROCEDURE RetRelative ; BEGIN RetBuf.K eyData.RecNum[1] := 1 ; { specify record number, 2 word } RetBuf.KeyData.RecN um[2] := 0 ; RetBuf.Search := REC ; { search by a rec vs. a string or RFA } RetBuf.RecSize := ExaRecSize ; PrmRet( FIND, RelFile, RetBuf, RecBuf, Sta tus ) ; IF Status[1] < 1 THEN writeln (' fail to find 1st relative reco rd, sts=',status[1] ) ; RetBuf.Search := NEX ; { switch from random to se q search } writeln; writeln('Begin Relative File data retreival') ; IF Sta tus[1] >= 1 THEN REPEAT { dump the entire file contents } PrmRet( GET, RelFile, RetBuf, RecBuf, Status ) ; IF Status[1] >= 1 THEN writeln('data = ', RecBuf.SecNum, RecBuf.SecDesc ) ELSE writeln('Get error=',status[1], status[2]); UNTIL Status[1] = ErEof ; END ; BEGIN RMSIni ; { must specify before any rms ops } Openfiles ; { open all the files } AddNewRec ( IdxFile, RecBuf, IdxStoBuf ) ; { add t o indexed file } AddNewRec ( RelFile, RecBuf, IdxStoBuf ) ; { add to relative file } AddNewRec ( SeqFile, RecBuf, SeqStoBuf ) ; { add to sequential file } XferToSeq ; { transfer records from idex to seq. file } RetByRfa ; { retrieve random from seq. by RFA } RetRelative ; { retrieve all records fro m relative file } PrmClo ( IdxFile ,status) ; { close all the files that are open } PrmClo ( RelFile ,status) ; PrmClo ( SeqFile ,status) ; PRM Pro gram Example - Access to existing files PAGE A-10 END. APPENDIX B PRM Example of Creating an RMS Indexed File PROGRAM Cre; CONST NameSize = 30 ; { sz of input file name, do not alter } { example label s and sizes follow - user defines buffer sizes and labels } KeyXSize = 2 ; { user defines size of largest key } KeyYSize = 6 ; { user defines these labe ls and sizes } TYPE RecDef1 = RECORD { user defines field names and sizes } CASE integer OF 1 : (Dat1 : ARRAY [1..10] OF CHAR ; Dat2 : integer ) ; 2 : (FYItem1 : ARRAY [1..30] OF CHAR ; FYItem2 : REAL ) ; END ; { User Defined Record } {************ *********************************************************** END PRM CONST and TYPE ***************************************************** ****************** } VAR FBuf : RmsFileDesc ; { create buffer } RBuf : RecDef1 ; { record buffer } SBuf : Storecord ; { storage desc. buffer } KBuf : IdxKeyDesc ; { describe indexed file key } PrmStatus : RmsStat us ; {******************************************************************* **** * START PRM PROCEDURE CALLS * *********************************************************************** } { close the file } PRM Example of Creating an RMS Indexed File PAGE B-2 PROCEDURE PRMClo ( VAR Filebuf : RmsFileDesc ; { ref. to file to close } VAR Status : RmsStatus ) ; { ST S and STV } EXTERNAL ; PROCEDURE PrmCre ( VAR CreBuf : R msFileDesc ; VAR Status : RmsStatus ) ; EXTERNAL ; { Define a single key of and indexed file, use in conj. with PrmC re } { Define keys in ascending order starting with key 0 definition } PROCEDU RE PRMKey (VAR Filebuf : RmsFileDesc ; VAR KeyBuf : IdxKeyDes c ; VAR Status : RmsStatus ) ; { status of Sts and Stv } EXTERNAL ; { Store a record in the specified file } PROCED URE PRMSto ( Operation : RecOps ; { define PUT or UPDATE } VAR FileBuf : RmsFileDesc ; { ref. to file for store } VAR StoData : StoRecord ; { store variables } VAR RecBuf : RecD ef1 ; { rec. buf connected to use } VAR Status : RmsStatus ); { STS and STV } EXTERNAL ; { Define a routine to GET and DISPOSE heap space, execute first in root seg } PROCEDURE RMSIni ; EXTERNAL ; {*********************************************************************** * END PRM PROCEDURE CALLS * **** ******************************************************************* } BEGIN RMSIni ; { must be the first thing } { define the primary key } WITH KBuf DO BEGIN KeyNum := 0 ; KeyPos := 0 ; K eySiz := 5 ; END ; PrmKey ( FBuf, KBuf, PrmStatus ) ; { define alt ernate key 1 } WITH KBuf DO BEGIN KeyNum := 1 ; KeyPos := 3 ; KeySiz := 5 ; END ; PrmKey ( FBuf, KBuf, PrmStatus ) ; PRM Example of Creating an RMS Indexed File PAGE B -3 { define alternate key 2 } WITH KBuf DO BEGIN KeyNum := 2 ; KeyPos := 4 ; KeySiz := 3 ; END ; PrmKey ( FBuf, K Buf, PrmStatus ) ; { define alternate key 3 } WITH KBuf DO BEGIN KeyNum := 3 ; KeyPos := 8 ; KeySiz := 2 ; END ; Prm Key ( FBuf, KBuf, PrmStatus ) ; WITH FBuf DO BEGIN Org := IDX ; FileName := 'Cretst.IDX ' ; LogChan := 4 ; RecordSize := 30 ; Allocation[1] := 10 ; Allocation[2] := 0 ; BucketSize := 2 ; Contiguous := 'Y' ; END ; { WITH FBuf } PrmCre ( FBuf, PrmStatus ) ; writeln ( 'File CreTst.Idx created, sts=',prm status[1], ' stv=',prmstatus[2] ) ; { store a record } RBuf.Dat1 := 'file data ' ; RBuf.Dat2 := 64 ; SBuf.RecSize := 30 ; PrmSto ( PUT, FBuf, SBuf, RBuf, PrmStatus ) ; writeln ( 'Store data, sts=',prmstatus[1], ' stv=',prmstatus[2] ) ; PrmClo ( FBuf, PrmStatus ) ; writeln ( 'File closed, sts=',prmstatus[1], ' stv=',prmstatus[2] ) ; END. APPENDIX C PR M Example of Command and Overlay Description Files Six logical uni t numbers are provided by default for each task. Logical channel numbers 3 and 4 are available to the PRM user. The other four are used by the system and Pascal. PRMExa requires 3 logical channel therefore UNITS=7 is specifed in the command file. File : PrmExaBld.Cmd PRMEXA/CP/FP,PRMEXA/-SP=PRMEXA /MP LIBR=RMSRES:RO:6 EXTSCT=$$HEAP:4000 UNITS=7 File : PrmExa.Od l .ROOT PRMEXA-RMS-PAS-RMSROT-RMSALL ; ; pascal interface to PRM routines RMS: .FCTR lb:[300,47]RMSPAS/LB ; ; pascal libray PAS: .FCTR lb:[300,41]PAS LIB/LB ; ; overlay structure for resident library @lb:[300,45]RMSRLX.ODL .E ND