The Put service usually adds records to the logical end of a sequential
file. For relative files, it may add records to the logical end of the
file or it may insert new records in cells formerly occupied by deleted
records. RMS directs the Put service where to insert the record using
the contents of the record's primary key field.
Inserting Records into Sequential Files
When using sequential record access mode to process sequential files,
you usually insert records at the end of the file only. The records to
be inserted cannot be larger than the maximum length that was specified
when the file was created.
You can use random access by relative record number mode and the
update-if record-processing option (RAB$V_UIF) to insert fixed-length
records into a sequential file residing on a disk device.
RMS also provides for establishing the logical end of the file when two
or more processes are doing shared write operations. For example,
assume that processes A and B are sharing a sequential file and each
process is putting data into the file. Process A puts a record at the
end of the file and intends to put another record at the new
end-of-file location. However, before process A can put the next record
in the file, process B gains access to the file and puts a record at
the end of the file. In order to ensure that the next record from
process A does not overwrite the record just inserted by process B, RMS
updates process A's write pointer to the new end-of-file position; that
is, the location immediately following the location of process B's
record.
The truncate-on-put option (RAB$V_TPT) can be used with sequential
files. This option lets you add records at locations other than the
logical end of the file. When you add a record using the
truncate-on-put option, the file is automatically truncated,
effectively deleting all data between the new record (logical end of
the file) and the physical end of the file. If you try to use this
option without having truncate access, RMS rejects the operation and
issues a file access error (RMS$_FAC).
For stream format files, RMS writes the contents of the user's buffer
into the file beginning at the current entry position. If the last byte
in the buffer is not a terminator, RMS adds the appropriate terminator.
For stream format, the terminator is CRLF (carriage return character
followed immediately by a line feed character).
Mailboxes may be used to synchronize activity between processes.
Usually, a Put service to a mailbox does not conclude until another
accessor reads the record. If you select the timeout option (RAB$V_TMO)
and specify a timeout period of 0, the Put service does not wait for
another accessor to read the record.
At the conclusion of the Put service, the RAB$L_STV field contains the
process identification (PID) of the process that read the record.
Inserting Records into Relative Files
When processing relative files, you can use either sequential or random
access by key mode. Records cannot be larger than the size specified at
file creation time, and the record's relative record number must not
exceed the maximum record number established for the file. Usually, if
the target record cell for a Put service contains a record, a
record-already-exists error (RMS$_REX) is returned as the completion
status (RAB$L_STS). If you specify the update-if (RAB$V_UIF) record
option, RMS overwrites the existing record instead of returning an
error message. If you try to use the update-if option but do not have
update access, RMS rejects the operation and issues a file access error
(RMS$_FAC).
Inserting Records into Indexed Files
In an indexed file, you can use sequential access or random access by
key mode. When sequential access is used to insert records, the primary
key value of the record to be inserted must be consistent with the
specified sort order of the
file. That is, the key must be greater than or equal to the primary
value of the previous record if ascending sort order is specified. If
descending sort order is specified, the key must be less than or equal
to the primary key value of the previous record.
The records cannot be larger than the size established when the file
was created if a maximum length was specified. Each record written must
contain a primary key, but the records do not have to contain alternate
keys. If alternate keys are partially or completely missing because of
the record length limitation, RMS does not make an entry for the record
in the associated alternate index. Put services to an indexed file do
not require a separate key value or key of reference. By examining the
contents of the primary key in the record, RMS determines where to
insert the record.
When inserting a record into an indexed file, RMS compares the key
values in the record with the key values of records previously inserted
into the file to determine whether the new record's key value
duplicates any existing key values. If the record duplicates a key
value in an index where duplication is not allowed, RMS rejects the
operation with an RMS$_DUP error code. Where duplicate keys are
allowed, RMS inserts the record.
Records with duplicate keys are inserted in chronological order; that
is, RMS inserts each record having duplicate keys at the end of a
"chain" of identically keyed records so that newer records
are stored closer to the end of the file regardless of sort order.
If you specify the update-if (RAB$V_UIF) option when duplicates are not
allowed on the primary key, RMS overwrites the existing record with the
same primary key value, rather than returning a duplicate record error
(RMS$_DUP). This gives the appearance of an Update service being
performed on the existing record. Alternate key values are modified to
reflect the newly inserted record.
To use the RAB$V_UIF option, you must have update access to the file.
If update access to the file is not permitted, the Put service (which
becomes an Update service when this option is selected) fails, and RMS
returns a file access error (RMS$_FAC).
Be careful when invoking the Put service with the RAB$V_UIF option and
automatic record locking for a shared file. The Put service, unlike the
Update service, momentarily releases record locks previously applied by
a Get or Find service, until the Put service is converted into an
Update service. This could allow another record stream to delete or
update the record between the invocation of the Put service and the
conversion to an Update service. To avoid this complication, you should
use the Update service instead of the Put service with the update-if
option to update an existing record in a file-sharing situation.
The record address field and the record size field are required inputs
to the Put service. Some Put service options may require additional
fields. The traditional address and size fields are RAB$L_RBF and
RAB$W_RSZ. However, OpenVMS Alpha users have the option to code -1 in
the RAB64$L_RBF field to direct the Put service to use the values in
the alternative fields, RAB64$PQ_RBF and RAB64$Q_RSZ. The RAB64$PQ_RBF
field can hold either a 64-bit address or a 32-bit address
sign-extended to 64 bits.
A successful Put service returns the record file address (RFA) in the
RAB$W_RFA field.
RAB Control Block Fields
Table RMS-61 lists the control block fields read as input by the Put
service. For additional information on the fields accessed by this
service, see Part 2.
Table RMS-61 Put Service RAB Input Fields
Field Name |
Option or XAB Type |
Description |
RAB$W_ISI
|
|
Internal stream identifier (required).
|
RAB$L_KBF
|
|
Key buffer address (used as input only with random access by relative
record number mode).
|
RAB$B_KSZ
|
|
Key size (used only if RAB$B_RAC is KEY and the file is a relative
file).
|
RAB$B_RAC
|
|
Record access mode (SEQ, KEY)
1.
|
RAB$L_RBF
|
|
Record buffer address.
|
RAB$L_RHB
|
|
Record header buffer (for variable with fixed control records only).
|
RAB$W_RSZ
|
|
Record size.
|
RAB$L_ROP
|
|
Record-processing options.
|
|
RAB$V_ASY
|
Asynchronous: performs Put services asynchronously.
|
|
RAB$V_CCO
2
|
Cancel Ctrl/O: guarantees that terminal output is not discarded if the
operator enters Ctrl/O.
|
|
RAB$V_LOA
|
Load: specifies that buckets are to be loaded according to the fill
size established at file creation time.
|
|
RAB$V_REA
3
|
Lock for read: allows other users read access to the record. This is
not valid for relative files.
|
|
RAB$V_RLK
3
|
Read of locked record allowed: specifies that a record locked for
modification can be read by other users.
|
|
RAB$V_TMO
2
|
Timeout: indicates that the content of the timeout period field
(RAB$B_TMO) is to be used.
|
|
RAB$V_TPT
|
Truncate-on-put: specifies that a Put service with a
sequentially-accessed record can occur at any point in the file,
truncating the file at that point.
|
|
RAB$V_UIF
|
Update-if: converts a Put service to a record that already exists to an
Update service.
|
|
RAB$V_ULK
|
Manual unlocking: specifies that records cannot be unlocked
automatically.
|
|
RAB$V_WBH
|
Write behind: two buffers are allocated to allow multibuffering.
|
|
RAB$V_WAT
|
Wait: if the record is locked, wait until it is available (for relative
files only).
|
RAB$B_TMO
2
|
|
Timeout period: a value of 0 indicates that RMS should not wait to
complete a Put service (for mailbox devices only).
|