LoganBerryEntry.mesa
Copyright Ó 1987, 1992 by Xerox Corporation. All rights reserved.
Doug Terry, November 14, 1989 9:40:29 am PST
Routines for manipulating LoganBerry entries.
DIRECTORY
BasicTime USING [GMT],
LoganBerry USING [AttributeType, AttributeValue, Entry],
Rope USING [ROPE];
LoganBerryEntry: CEDAR DEFINITIONS
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
Entry operations
Operations on attributes within entries:
GetAttr: PROC [entry: LoganBerry.Entry, type: LoganBerry.AttributeType] RETURNS [LoganBerry.AttributeValue];
Extracts value of particular attribute from entry. Returns NIL if entry does not contain an attribute of the specified type.
GetAllAttrs: PROC [entry: LoganBerry.Entry, type: LoganBerry.AttributeType] RETURNS [LIST OF LoganBerry.AttributeValue];
Extracts all values of the particular attribute type and returns them as a list. Returns NIL if entry does not contain an attribute of the specified type.
SetAttr: PROC [entry: LoganBerry.Entry, type: LoganBerry.AttributeType, value: LoganBerry.AttributeValue] RETURNS [];
Changes the value of a particular attribute in entry. Does nothing if entry does not contain an attribute of the specified type.
ChangeAttr: PROC [entry: LoganBerry.Entry, type: LoganBerry.AttributeType, value: LoganBerry.AttributeValue] RETURNS [found: BOOLEAN];
Like SetAttr but returns found=FALSE if entry does not contain an attribute of the specified type.
AddAttr: PROC [entry: LoganBerry.Entry, type: LoganBerry.AttributeType, value: LoganBerry.AttributeValue] RETURNS [new: LoganBerry.Entry];
Appends an attrribute to the entry. Returns the new entry.
RemoveAttr: PROC [entry: LoganBerry.Entry, type: LoganBerry.AttributeType, value: LoganBerry.AttributeValue] RETURNS [new: LoganBerry.Entry];
Removes the specified attribute from the entry. Returns the new entry, which may be NIL.
Operations on whole entries:
CopyEntry: PROC [entry: LoganBerry.Entry] RETURNS [new: LoganBerry.Entry];
Makes a copy of the given entry.
ReverseEntry: PROC [entry: LoganBerry.Entry] RETURNS [new: LoganBerry.Entry];
Destructively reverses the order of the entry's attributes.
AppendEntries: PROC [e1, e2: LoganBerry.Entry] RETURNS [new: LoganBerry.Entry];
Concatenates two entries together.
EntriesEqual: PROC [e1, e2: LoganBerry.Entry] RETURNS [BOOL];
Returns true if two entries are equal up to reordering.
Timestamps
For some databases, there may be no natural attribute to serve as a key. In this case, a unique timestamp can be used as a key.
Timestamp: TYPE ~ LoganBerry.AttributeValue;
NewTimestamp: PROC [] RETURNS [ts: Timestamp];
Generates a timestamp that is close to the current time and such that subsequent calls to NewTimestamp yield different results provided (1) the calls are performed on the same machine, and (2) the machine has not crashed and been restarted in between calls. Even if NewTimestamp is called on different machines, the results will be unique with a high probability.
Timestamps generated by calls to NewTimestamp may be used directly as keys as in the following piece of code:
LoganBerry.WriteEntry[db: db, entry: AddAttr[entry, $Key, NewTimestamp[]]];
However, this may occasionally fail since NewTimestamp is not guaranteed to provide a unique result. Hence, the following is a safer way to use NewTimestamp:
WriteWithTimestamp: PROC [db: LoganBerry.OpenDB, entry: LoganBerry.Entry] = {
timestampedEntry: LoganBerry.Entry ← AddAttr[entry, $Key, NewTimestamp[]];
LoganBerry.WriteEntry[db: db, entry: timestampedEntry
! LoganBerry.Error => IF ec=$ValueNotUnique THEN {SetAttr[entry, $Key, NewTimestamp[]]; RETRY} ];
};
Conversions
From various data types to attribute values:
I2V: PROC [i: INT] RETURNS [v: LoganBerry.AttributeValue];
From an integer to an attribute value, e.g. "101".
B2V: PROC [b: BOOL] RETURNS [v: LoganBerry.AttributeValue];
From a boolean to an attribute value, e.g. "TRUE".
S2V: PROC [s: ROPE] RETURNS [v: LoganBerry.AttributeValue];
From a rope to an attribute value (most likely a no-op).
A2V: PROC [a: ATOM] RETURNS [v: LoganBerry.AttributeValue];
From an atom to an attribute value.
T2V: PROC [t: BasicTime.GMT] RETURNS [v: LoganBerry.AttributeValue];
From a time to an attribute value, e.g. "19 Jan 87 14:27:05 PST".
T2Ts: PROC [t: BasicTime.GMT] RETURNS [ts: Timestamp];
From a time to a timestamp. A timestamp is not human-readable, e.g. "2804473302", but does have the property that BasicTime.Period[from: t1, to: t2] > 0 => T2Ts[t1] < T2Ts[t2] lexicographically.
From attribute values to various data types:
V2I: PROC [v: LoganBerry.AttributeValue] RETURNS [i: INT];
From an attribute value to an integer.
V2B: PROC [v: LoganBerry.AttributeValue] RETURNS [b: BOOL];
From an attribute value, i.e. "TRUE" or "FALSE", to a boolean.
V2S: PROC [v: LoganBerry.AttributeValue] RETURNS [s: ROPE];
From an attribute value to a rope (most likely a no-op).
V2A: PROC [v: LoganBerry.AttributeValue] RETURNS [a: ATOM];
From an attribute value to an atom.
V2T: PROC [v: LoganBerry.AttributeValue] RETURNS [t: BasicTime.GMT];
From an attribute value, e.g. "19 Jan 87 14:27:05 PST", to a time.
Ts2T: PROC [ts: Timestamp] RETURNS [t: BasicTime.GMT];
From a timestamp to a time.
Formatters
Formatters are parsers and unparsers for LoganBerry entries.
ParseError: ERROR [explanation: Rope.ROPE ¬ NIL];
EntryToRope: TYPE = PROC [entry: LoganBerry.Entry] RETURNS [rope: Rope.ROPE];
Creates the rope corresponding to an entry.
RopeToEntry: TYPE = PROC [rope: Rope.ROPE] RETURNS [entry: LoganBerry.Entry, error: BOOL];
Creates an entry corresponding to a rope; raises ParseError if the entry is in error.
Formatter: TYPE = REF FormatterRec;
FormatterRec: TYPE = RECORD [    -- The per formatter data structure
name: ATOM,          -- The name of the formatter
format: ATOM,         -- The format of the node
entryToRope: EntryToRope,     -- Convert an entry to it's corresp. rope
ropeToEntry: RopeToEntry      -- Convert a rope to it's corresp. entry
];
RegisterFormatter: PROC [name: ATOM, formatter: Formatter] RETURNS [];
Register a set of formatting procedures for a named class; if formatter is NIL then the name is unregistered.
GetFormatterByName: PROC [name: ATOM] RETURNS [formatter: Formatter];
Get the registered formatter of the specified name or NIL if there is no such formatter.
EachFormatterAction: TYPE = PROC [formatter: Formatter] RETURNS [quit: BOOL ¬ FALSE];
EnumerateFormatters: PROC [action: EachFormatterAction] RETURNS [BOOL];
Enumerates pairs currently in the formatter registry in unspecified order; applies action to each pair until action returns TRUE or no more pairs; returns TRUE if some action returns TRUE.
END.