prmupd.pas/-au=
{
DATE : 

AUTHOR : 
     Kenneth G. Tibesar
     3M Engineering Systems and Technology Labs
     3M Center, Bldg 518-1
     St. Paul, Minn. 55144

REVISION HISTORY :

DESCRIPTION :

ENVIROMENT :          
     DEC PDP-11 
     RSX-11M or RSX-11M+

}

PROGRAM PrmUpd ;
CONST
 CalFullRec	= 326 ;

@[315,304]Calrecs.pas

{***********************************************************************
                     BEGIN PRM CONST and TYPE
        FILE [300,47]PrmPrefix.Pas
          Refer to file [300,47]PrmCalls.Pas for Procedure Calls 
 *********************************************************************** }
  
CONST
  { * Error values returned in status word 1 and word 2 with each PRM call.
    * All errors set Status[1] to a negative value.

    *** ALL PRM CALLS SHOULD CHECK FOR A STATUS[1] RETURN VALUE 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 record operation was attempted on a file
 				that was not properly opened by PrmOpe or
				PrmKey.  Check proper open or create of
 				a file before continuing with record ops. 
				}
  PrRNE	= -5002 ;  { Lch  	An existing file was opened 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 determine 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.  
				The record size specified by the user is
				returned in word 2.
				}
  PrKY0	= -5004 ;   { NA	During a PrmKey call the primary key must
				be specified first.  
				}
  PrKNS	= -5005 ;   { NA	During a PrmCre call a indexed file 
				organization was specified and no primary key
				defined.  You must use PrmKey to define at
				least a primary key for indexed files.
				}
  PrAsc	= -5006 ;   { NA	Keys defined to PrmKey were defined in a
				non-ascending key order.  
				}

  {Erxxx    STS        STV      Rms error sts and stv error values are 
  				returned for all rms errors.  The same 
   				symbolic values used by DEC (without $)
				are used to describe the errors.  Not all
				rms error codes are provided but may be
 				added.  Refer to index of Rms User Ref.  
				}
  ErDup	= -544 ;		{ insert duplicate rec with no dups allowed }
  ErEof = -592 ;		{ record processing reached end-of-file }
  ErFac = -656 ;		{ record opr does not match declared access }
  ErFnf = -736 ;		{ file not 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 input file name, do not alter }

  { example labels and sizes follow - user defines buffer sizes and labels }
  KeyXSize	= 2 ;		{ user defines size of largest key }
  KeyYSize	= 6 ;		{ user defines these labels and sizes }  
  
TYPE

  { following record is for example only }
  RecDef = CalREcord ;


  TwoWord	= ARRAY [1..2] OF integer ;	{ record number size }
  KeyDef	= RECORD
    CASE integer OF	{ user defines keylabels and sizes, as many as req. }
      1 : ( 
          Bur : char ;
          stack : char ;
          position : char 
          ) ;
      2 : ( RNum : 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 }

  {    The following record holds the file being descibed with options
   selected by the 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 operation is being performed on.
  }
  OrgTypes	= (SEQ,REL,IDX) ;	{ block i/o not supported }
  AllowTypes	= (Share,NoShare) ;      { what others can do }
  AccessTypes	= (PRead,PWrite,PBoth) ; { what you can do to the file }
  FormType = (FFIX,FVAR,FSTREAM) ;	{ record format type }

  { specify file options, if field not altered, default will be selected }
  RmsFileDesc	= RECORD
    { -- Use with PRMOPE -- }
    Org		: OrgTypes ;	{ spec. file type, no default }
    FileName	: RmsFileName ;	{ full spec. of rms file, no default }
    LogChan	: integer ;	{ spec. ch. n, no def., n<= TKB UNITS=n }
    Allow	: AllowTypes ;	{ what others may do with file, def Share }
    Access	: AccessTypes ;	{ what you may do to the file, default Read }
    RecordSize  : INTEGER ;	{ spec. max. file rec. sz, user rec. buf can 
      be < full, spec. bytes to xfer with recsize in Ret & StoRecord buffers }
    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. "L" }
    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 file stream at end of file }

    { file creation fields }
    RecForm	: FormType ;	{ rec. format, FSTREAM for seq., Def.= FFix }
    Allocation  : TwoWord ;	{ no. blocks allocated to file, def. 0 blks }
    BucketSize	: integer ;	{ data bucket size, default size 1 bucket }
    ExtQua	: integer ;	{ no. blks dynamic extend file, default 1}
    { Enable following with capital "Y", if not loaded, 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 ;	{ RmsFileDesc Record }


  SearchTypes	= (EQ,GT,GE,RFA,NEX,REC) ; { for GET use KeyData(EQ'=',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 = RECORD
    { - USE with PRMRET, INPUT - to GET and FIND - INPUT/OUTPUT ref. to PRM }
    KeyNum	: Threeword ;	{ INPUT- IDX Key # or RFA, search defines }
    Search	: SearchTypes ;	{ INPUT - spec. search opr }
    RecSize	: integer ;	{ INPUT - sz rec. to GET, (sz of rec. buffer)
                                  OUTPUT- sz rec. returned to user rec. buf }
    RFAout	: ThreeWord ;	{ OUTPUT- valid if search <> RFA }
    KeySize	: integer ;	{ INPUT - size of key data, <= full key size }
    KeyData	: KeyDef ;	{ INPUT - IDX or REL, key string or rec. # }
  END ;	{ RetRecord RECORD Definition }

  StoRecord = RECORD
      { USE with PRMSTO, Input to PUT and UPDATE - INPUT/OUTPUT ref. to PRM }
      RecSize	: 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 }

  KType = (StrKey,IntKey) ;	{ string or unsigned integer key type }
  IdxKeyDesc = RECORD	{ Use with MULTIPLE calls of PRMKEY to define ALL
       keys of an indexed file. Use prior to PrmCre of an indexed file type }
      KeyNum	: Integer ;	{ key of ref. #, def. asc. order, start 0 }
      KeyPos	: Integer ;	{ byte position of key in rec., start byte 0 }
      KeySiz	: Integer ;	{ size of the key defining, max. = 255 }
      KeyTyp	: KType ;	{ string or unsigned integer, def.=string }
      KeyDup	: char ;	{ 'Y' to allow duplicate 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

  CalDesc	: rmsfiledesc ;
  RmsStat	: RmsStatus ;
  RecBuf	: RecDef ;
  RetBuf	: RetRecord ;
  StoBuf	: StoRecord ;




{***********************************************************************
 *                 START PRM PROCEDURE CALLS                           *
 *********************************************************************** }
  
  
{ close the file }
PROCEDURE PRMClo ( VAR Filebuf : RmsFileDesc ;	{ ref. to file to close }
                   VAR Status  : RmsStatus ) ;	{ STS and STV }
                   EXTERNAL ;

{ Open an RMS Indexed file previously defined with RMSDEF or another prg. }
PROCEDURE PRMOpe ( VAR FileBuf : RmsFileDesc ;   { load fields before open }
                   VAR Status  : RmsStatus ) ;	{ status of Sts and Stv }
                   EXTERNAL ;

{ Record retrieval from the specified file }
PROCEDURE PRMRet ( Operation : RecOps ;		{ define PGET or PFIND }
                   VAR FileBuf : RmsFileDesc ;	{ ref. to file for access }
                   VAR RetData : RetRecord ;	{ load with type of opr }
                   VAR RecBuf  : RecDef  ;	{ rec. buf connected to use }
                   VAR Status  : RmsStatus ) ;	{ status of STS and STV }
                   EXTERNAL ;

{ Store a record in the specified file }
PROCEDURE PRMSto ( Operation   : RecOps ;	{ define PPUT or PUPDATE }
                   VAR FileBuf : RmsFileDesc ;	{ ref. to file for store }
                   VAR StoData : StoRecord ;	{ store variables }
                   VAR RecBuf  : RecDef  ;	{ 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 ;
WITH CalDesc DO
BEGIN
  ORG := IDX ;
  FileName := 'cal.dat                       ' ;
  LogChan := 4 ;
  Allow := SHARE ;
  Access := PBOTH ;
  RecordSize := CalFullRec ;
  Unlock := 'Y' ;
END ;
PrmOpe ( CalDesc, RmsStat ) ;
writeln (' open sts=', Rmsstat[1], Rmsstat[2] ) ;

WITH RetBuf DO
BEGIN
  KeyNum[1] := 0 ;
  Search := EQ ;
  RecSize := CalFullRec ;
  KeySize := 3 ;
  KeyData.Bur := 'A' ;
  KeyData.Stack := 'A' ;
  KeyData.Position := 'D' ;
END ;

PrmRet ( PGET, CalDesc, RetBuf, RecBuf, RmsStat ) ;

writeln (' ret record sts=', Rmsstat[1], Rmsstat[2] ) ;
writeln ( ' returned record size = ' , retbuf.recsize ) ;
writeln ( 'record data ' ) ;
writeln ( ' recbuf.bur = ', recbuf.bur, 
	'  recbuf.stack = ', recbuf.stack, 
	'  recbuf.position = ',  recbuf.position ) ;

RecBuf.NumCal := RecBuf.NumCal + 1 ;
ReCBuf.Cal[RecBuf.NumCal].EngCal := 'ML' ;
RecBuf.Cal[RecBuf.NumCal].datecal := '81998877' ;
StoBuf.RecSize := RetBuf.RecSize + 24 ;

PRMSto ( PUPDATE, CalDesc, StoBuf, RecBuf, RmsStat ) ;

writeln ;
writeln (' update record sts=', Rmsstat[1], Rmsstat[2] ) ;

prmclo ( CalDesc, RmsStat ) ;
writeln ;
writeln (' close sts=', Rmsstat[1], Rmsstat[2] ) ;

END.
/
