LoganQueryClass.mesa
Copyright Ó 1985, 1992 by Xerox Corporation. All rights reserved.
Doug Terry, July 16, 1992 11:16 am PDT
LoganQuery allows more complicated queries to be performed on a LoganBerry database than the simple retrievals provided by the LoganBerry interface. Database queries of various classes can be registered; retrieval operations are class-specific. For instance, the $Filter class returns database entries that match a particular pattern, while the $Merger class merges the entries returned by two independent queries. The predefined $Simple class permits operations identical to those provided by LoganBerry. Clients are free to create their own class of queries.
The individual classes are the basic building blocks for constructing complex queries. The results of such queries are obtained by retrieving entries one at a time from a cursor. Cursor creation is a class-specific operation. Most class constructors, e.g. FilterEntries, takes one or more cursors as input and produces one or more cursors as output. This permits classes to be composed in various ways. For example, filters can be cascaded to perform multiple-attribute queries.
Rather than using this interface directly, most clients should use the LoganQuery.mesa interface for complex queries.
DIRECTORY
PatternMatch USING [MatchProc],
Rope USING [ROPE],
LoganBerry;
LoganQueryClass: CEDAR DEFINITIONS
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
Query classes
QueryClass: TYPE = REF QueryClassRec;
QueryClassRec: TYPE = RECORD [
flavor: ATOM ¬ NIL, -- name of cursor's class
retrieve: RetrieveProc ¬ NIL, -- get next database entry
destroy: DestroyProc ¬ NIL -- end the query (and destroy the cursor)
];
RetrieveProc: TYPE = PROC [cursor: Cursor, dir: CursorDirection ¬ increasing] RETURNS [entry: LoganBerry.Entry];
Retrieves the next database entry in a manner particular to the class of query.
DestroyProc: TYPE = PROC [cursor: Cursor] RETURNS [];
Destroys the given cursor and any embedded cursors.
Cursor type
Cursor: TYPE = RECORD [
class: QueryClass ¬ NIL, -- cursor's class
data: REF -- data slot for cursor class implementor
];
CursorDirection: TYPE = LoganBerry.CursorDirection;
Predefined basic query classes
$Simple
GenerateEntries: PROC [db: LoganBerry.OpenDB, key: LoganBerry.AttributeType, start: LoganBerry.AttributeValue ¬ NIL, end: LoganBerry.AttributeValue ¬ NIL] RETURNS [cursor: Cursor];
Identical to the GenerateEntries operation provided by LoganBerry but returns a cursor with class=$Simple and data=LoganBerry.Cursor.
Errors: LoganBerry.NoIndex
$Filter
MatchProc: TYPE = PatternMatch.MatchProc;
FilterEntries: PROC [input: Cursor, pattern: ROPE, filter: MatchProc, atype: LoganBerry.AttributeType, stopIfNothingGreater: BOOLEAN ¬ FALSE] RETURNS [output: Cursor];
Returns a cursor of class $Filter. Retrievals using this new cursor apply the given pattern-matching filter to the appropriate attribute of entries identified by the input cursor. A retrieval returns NIL if the input is exhausted or stopIfNothingGreater=TRUE and the filter procedure returns nothingGreater=TRUE.
$Merger
MergeEntries: PROC [input1, input2: Cursor, atype: LoganBerry.AttributeType] RETURNS [output: Cursor];
Returns a cursor of class $Merger. Retrievals using this new cursor merge the two input streams. The input streams should be ordered by the given attribute type. A retrieval returns NIL only when both inputs are exhausted.
Additional query classes
$AntiFilter
AntiFilterEntries: PROC [input: Cursor, pattern: ROPE, filter: MatchProc, atype: LoganBerry.AttributeType] RETURNS [output: Cursor];
Returns a cursor of class $AntiFilter. Retrievals using this new cursor apply the given pattern-matching filter to the appropriate attribute of entries identified by the input cursor and return those entries that do NOT match the pattern. In other words, the resulting cursor returns exactly the opposite of what would be returned by a $Filter cursor. A retrieval returns NIL if the input is exhausted.
$Duplicator
DuplicateEntries: PROC [input: Cursor] RETURNS [output1, output2: Cursor];
Returns a pair of cursors of class $Duplicator. Retrievals using either new cursor return the same entries as the input cursor. That is, each entry from the input cursor is copied to both output cursors.
$UnDuplicator
UnDuplicateEntries: PROC [input: Cursor, atype: LoganBerry.AttributeType] RETURNS [output: Cursor];
Returns a cursor of class $UnDuplicator. Retrievals using the new cursor will suppress, i.e. not return, successive entries with the same value for the given attribute type. Typically, this is used in conjunction with LoganQuery.MergeEntries to combine two cursors and filter out duplicates; for instance UnDuplicateEntries[MergeEntries[DuplicateEntries[c]]] should produce a cursor whose output is equivalent to the orginal one. The input stream should be ordered by the given attribute type and this attribute should be the primary key.
$Subtracter
SubtractEntries: PROC [input, except: Cursor, ptype, atype: LoganBerry.AttributeType] RETURNS [output: Cursor];
Returns a cursor of class $Subtracter. Retrievals using the new cursor will return all entries from the input cursor except for those returned by the except cursor. The input and except cursors should both be ordered by the atype attribute; ptype should indicate the primary key, which is used to determine the equivalence of two entries.
$Feeder
FeedEntries: PROC [] RETURNS [output: Cursor];
Returns a cursor of class $Feeder. Such a cursor simply maps its input to its output. The utility is that its input cursor can be supplied later and changed at will.
SetFeederInput: PROC [feeder, input: Cursor];
Sets (or changes) the input cursor for the feeder.
Aborting queries
$Aborter
EnableAborts: PROC [input: Cursor] RETURNS [output: Cursor];
Returns a cursor of class $Aborter. Operations on cursors of this class behave exactly like those on the input cursor except that they can be aborted using the AbortQuery operation defined below.
AbortQuery: PROC [cursor: Cursor];
If a process is currently executing a NextEntry operation on the given cursor, the process is aborted and the operation returns NIL; any subsequent calls to NextEntry will also return NIL (i.e. the cursor is no longer useable). This operation can only be used for cursors of class $Aborter.
END.
Doug Terry November 6, 1985 9:55:44 am PST
created
Doug Terry, November 6, 1985 5:15:27 pm PST
changes to: DIRECTORY, ILQuery, ~, Cursor, CursorDirection, CursorClass, CursorClassRec, RetrieveProc, DestroyProc, NextEntry, EndGenerate, GenerateEntries, FilterEntries, MatchResult, FilterProc, MergeEntries
Doug Terry, November 7, 1985 2:59:51 pm PST
changes to: ~, QueryClass, QueryClassRec, Cursor, RetrieveProc, DestroyProc, FilterEntries, FilterProc, MergeEntries, Equal, Prefix, Wildcard, RegularExpression, Soundex, DIRECTORY, NextEntry
Doug Terry, November 26, 1985 4:12:52 pm PST
changes to: DIRECTORY, LoganQuery, RetrieveProc, CursorDirection, NextEntry, GenerateEntries, FilterEntries, MergeEntries
Doug Terry, April 14, 1987 3:36:36 pm PDT
Moved FilterProcs to PatternMatch; added $Query class from LoganBerryBrowser.
changes to: FilterEntries, MergeEntries, SyntaxError, QueryWarning, QueryPlan, QueryPlanRec, QueryEntries, END
Doug Terry, April 17, 1987 10:39:35 am PDT
Added $Aborter class and AbortQuery for halting operations in mid-execution.
changes to: Cursor, EndGenerate, QueryEntries, EnableAborts, AbortQuery
Doug Terry, July 16, 1992 10:07:10 am PDT
Split off from LoganQuery; added several new query classes.