-- Hickory.mesa: the interface for the event data base
-- Last Edited by: Binding, August 16, 1984 2:28:57 pm PDT
DIRECTORY
BasicTime USING [ GMT, nullGMT],
Rope USING [ ROPE],
RopeSets USING [ RopeSet]
;
Hickory: CEDAR DEFINITIONS
= BEGIN OPEN BasicTime, Rope;
Basic type definitions
Event: TYPE = ROPE; -- this is in fact the name of an event entity in event domain
EventSet: TYPE = RopeSets.RopeSet;
RepetitionType: TYPE = { None, Hourly, Daily, Weekdays, Weekly, Monthly, Yearly, Complicated };
ProtectionType: TYPE = { Private, Public}; -- for multiple user calendar system
EventTuple: TYPE = RECORD [
Key: Event ← nullEvent,
EventTime: GMT ← nullGMT, -- absolute time
Duration: CARDINAL ← 0, -- minutes, constrained to terminate on same day
RepeatType: RepetitionType ← None, -- is is a repeated event
RepeatTime: ROPENIL, -- in case of RepeatParam = Complicated
RepeatUntil: GMT ← nullGMT, -- until when to schedule the event ( defaulted to latestGMT)
LeadTime: INTEGER ← 0, -- how long ahead of EventTime to post reminder
NagTime: INTEGER ← 0, -- for how long to keep reminder posted
KeepUntil: GMT ← nullGMT, -- until when is event kept in data base ( defaulted to latestGMT)
Text: ROPENIL,
Message: ROPENIL, -- the walnut mesg. id.
Place: ROPENIL, -- where is event happening
IconFlavor: ROPENIL, -- the icon to be displayed
IconLabel: ROPENIL,
Protection: ProtectionType ← Private,
Remind: BOOLEANTRUE, -- Is event to be seen by reminder
Forgotten: BOOLEANFALSE
];
EventList: TYPE = LIST OF EventTuple;
nullEvent: Event = NIL;
Query options
Options: TYPE = ARRAY [0..15] OF BOOLEAN;
NoOptions: Options = ALL[ FALSE]; -- non forgotten events, no expansion
All: CARDINAL = 0; -- return all events stored in data base, including 'forgotten' events
ExpandRepetitions: CARDINAL = 1; -- repetitions are expanded
Reminders: CARDINAL = 2; -- return the events to be reminded only
General utilities
SameEvent: PROCEDURE [ ev1, ev2: Event] RETURNS [ BOOLEAN];
compares two data base events on equality
SameEventTuple: PROCEDURE [ ev1, ev2: EventTuple] RETURNS [ BOOLEAN] ;
to test on equality of tuples, not including the key.
AppendEventLists: PROCEDURE [ evl1, evl2: EventList] RETURNS [ evl: EventList];
appens two EventLists that we assume to be ordered on EventTime
MergeLists: PROCEDURE [ evl1, evl2: EventList] RETURNS [ evl: EventList];
merging two ordered EventLists
OrderEventList: PROCEDURE [ evl: EventList] RETURNS [ orderedList: EventList];
to order two EventList on EventTime field
Querying the data base
RestoreEvents: PROCEDURE [ from, to: GMT, options: Options ← NoOptions, group: Group ← NIL, key: Event ← NIL] RETURNS [ evList: EventList];
returns the event tuples falling in the given time interval [ from..to].
This includes the repeated occurrences of a repeated event that fall into the interval
if 'options' include 'ExpandRepetition'. Otherwise, only the first occurrence of a
repeated event which falls into the given time interval is returned.
If 'All' is set in 'options', also return the events that have been "forgotten".
If group # NIL and key = NIL, return only events that are in the specified group.
If key # NIL, then return a list that either includes only one element
or the expanded repetions if options are set properly. The 'group' argument is
ignored if key # NIL. If 'Reminders' is set, returns only the events that have
the reminder attribute TRUE.
If it is not the owner of the data base who is accessing it, some fields of the
returned tuples are blanked out...( Text, Message, Place)
raises Error[ NullInterval], Error[ BadInterval], Error[ NoSuchEvent]
Storing events
EnterEvent: PROCEDURE [ ev: EventTuple, groups: GroupSet ← [NIL, NIL]] RETURNS [ updatedEv: EventTuple];
if event key null, enter it into data base and return the event tuple with updated
key. If group non empty, also enter event into specified group.
raises Error[ NotOwner], Error[ NotStored], Error[ TooLong]
notification: NewEvent, InsertionToGroup
ForgetEvent: PROCEDURE [ ev: Event, on: BOOLEAN];
To 'forget' an event, i.e. queries will not take the forgotten events into account,
except when 'All' included in 'options'. To unforget, 'on' = FALSE!
raises Error[ NotOwner], Error[ NoSuchEvent]
notification: Forget, UnForget
ChangeEvent: PROCEDURE [ oldEv, newEv: EventTuple];
If event key is non null and the event exists, the attributes in data base are updated
according to the supplied new tuple. oldEv.Key = newEv.Key is mandatory...!
raises Error[ NotOwner], Error[ NotStored], Error[ NoSuchEvent], Error[ NotSameKey]
notification: Edit
Destroying elements of data base
DestroyEvent: PROCEDURE [ ev: Event];
destroys an event in data base
raises Error[ NotOwner], Error[ NoSuchEvent]
notification: Destroy
DestroyDataBase: PROCEDURE;
closes any outstanding transaction and deletes the segment. Not very
recommendable to be used
raises Error[ NotOwner]
notification: DestroyDB
Grouping events and manipulating groups
Group: TYPE = Rope.ROPE;
GroupSet: TYPE = RopeSets.RopeSet;
InsertToGroup: PROCEDURE [ ev: Event, groups: GroupSet];
Inserts the event into the group, creating a group if necessary.
raises Error[ NotOwner], Error[ NoSuchEvent]
notification: InsertionToGroup
RemoveFromGroup: PROCEDURE [ ev: Event, groups: GroupSet];
Removes the event from the group. Event is NOT
destroyed, simply removed from group.
raises Error[ NotOwner], Error[ NoSuchGroup], Error[ NoSuchEvent]
notification: RemoveFromGroup
ListGroups: PROCEDURE [ ev: Event ← NIL] RETURNS [ gSet: GroupSet];
Enumerates all existing groups in lexicographic increasingly ordered list.
If ev non NIL, then return the groups in which ev was entered.
raises Error[ NoSuchEvent]
RemoveGroup: PROCEDURE [ group: Group];
Destroys all entries in that group. Note that events are not destroyed,
simply removed from group.
raises Error[ NotOwner], Error[ NoSuchGroup]
notification: GroupDestroy
Declaring properties and querying them
Property: TYPE = Rope.ROPE;
PropertySet: TYPE = RopeSets.RopeSet;
SetProperty: PROCEDURE [ ev: Event, name: Property, value: REF ANY];
sets the named property of the given event to the supplied value.
value can be a reference to BOOLEAN, INTEGER, Rope.ROPE or
BasicTime.GMT.
raises Error[ NowOwner], Error[ BadValueType], Error[ BadValue], Error[ MismatchedPropertyType]
notificaton: AddProperty
GetProperty: PROCEDURE [ ev: Event, name: Property] RETURNS [ value: REF ANY];
retrieves the property value for the given event. If no value of that property
was set, a NIL ref is returned.
raises Error[ NoSuchEvent], Error[ NoSuchProperty]
ListProperties: PROCEDURE [ ev: Event ← NIL] RETURNS [ pSet: PropertySet];
Enumerates all existing properties in lexicographic increasingly ordered list.
If ev non NIL, then return the properties of it.
raises Error[ NoSuchEvent]
RemoveProperty: PROCEDURE [ property: Property];
Destroys the named property on all events that have such a property. Events
are not destroyed.
raises Error[ NotOwner], Error[ NoSuchProperty]
notification: PropertyDestroy
Client Notification
NotifyProc: TYPE = PROCEDURE [ reason: Reason, ev: Event, data: RopeSets.RopeSet];
to notify a client when data base is written.
Reason: TYPE = {
NewEvent, -- ev, group
Forget, -- ev, NIL
UnForget, -- ev, NIL
Edit, -- ev, NIL
Destroy, -- ev, NIL
DestroyDB, -- NIL, NIL
NewGroup, -- NIL, group
InsertionToGroup, -- ev, groups
RemoveFromGroup, --ev, groups
GroupDestroy, -- NIL, group
NewProperty, -- NIL, property
AddProperty, -- ev, property
PropertyDestroy -- NIL, property
};
RegisterNotifyProc: PROCEDURE [ proc: NotifyProc];
RemoveNotifyProc: PROCEDURE [ proc: NotifyProc];
NoOp if not previously registered
Error conditions
Error: PUBLIC SIGNAL [ errCode: ErrorCode, arg: ROPE];
ErrorCode: TYPE = {
NullInterval, -- query with fromWhen = upTo
BadInterval, -- query with upTo > fromWhen
NoSuchEvent, -- supplied event does not exist
NoSuchGroup, -- supplied group does not exist
NoSuchProperty, -- supplied property does not exist
MismatchedPropertyType, -- supplied property value mismatches existing property type
BadValueType, -- supplied property value is of wrong type
BadValue, -- NIL value given for a property
NotOwner, -- only owner of Hickory can write it...
NotStored, -- if KeepUntil < EventTime
NotSameKey, -- if oldEv.Key # newEv.Key
TooLong -- event must start and end on same calendar day, i.e. can not be longer than 24 hours
};
END.