DIRECTORY BasicTime USING [GMT], DB USING [Entity, Relship], RefTab USING [Ref], Rope USING [ROPE, Equal], ViewerTools USING [TiogaContents], WalnutDefs USING [ dontCareDomainVersion, dontCareMsgSetVersion, MsgSet, Segment, ServerInfo], WalnutKernelDefs USING [LogExpungePhase, MsgLogEntry]; WalnutDB: CEDAR DEFINITIONS IMPORTS Rope = BEGIN ROPE: TYPE = Rope.ROPE; GMT: TYPE = BasicTime.GMT; Entity: TYPE = DB.Entity; Relship: TYPE = DB.Relship; TiogaContents: TYPE = ViewerTools.TiogaContents; MsgSet: TYPE = WalnutDefs.MsgSet; -- [ROPE, INT] dontCareDomainVersion: INT = WalnutDefs.dontCareDomainVersion; dontCareMsgSetVersion: INT = WalnutDefs.dontCareMsgSetVersion; LogExpungePhase: TYPE = WalnutKernelDefs.LogExpungePhase; ServerInfo: TYPE = WalnutDefs.ServerInfo; LazyEnumerator: TYPE = REF LazyEnumeratorRec; LazyEnumeratorRec: TYPE; CheckReportProc: TYPE = PROC[msg1, msg2, msg3: ROPE _ NIL]; activeMsgSet: MsgSet; deletedMsgSet: MsgSet; walnutSegment: ATOM; MsgExists: PROC[msg: ROPE] RETURNS [existed: BOOL]; GetHasBeenRead: PROC[msg: ROPE] RETURNS[BOOL]; SetHasBeenRead: PROC[msg: ROPE]; AddNewMsg: PROC[msg: WalnutKernelDefs.MsgLogEntry] RETURNS[mExisted: BOOL]; GetMsgEntryPosition: PROC[msg: ROPE] RETURNS[pos: INT]; SetMsgEntryPosition: PROC[to: INT]; GetMsgDate: PROC[msg: ROPE] RETURNS[date: GMT]; GetMsgTextInfo: PROC[msg: ROPE] RETURNS[textStart, textLen, formatLen: INT]; GetMsgText: PROC[msg: ROPE] RETURNS[textStart, textLen, formatLen: INT, herald: ROPE, shortNameLen: INT]; GetDisplayProps: PROC[msg: ROPE] RETURNS [hasBeenRead: BOOL, TOCentry: ROPE, startOfSubject: INT]; GetCategories: PROC[msg: ROPE] RETURNS [ms: LIST OF ROPE]; EqMsg: PROC[msg1, msg2: ROPE] RETURNS [BOOL] = INLINE{RETURN[Rope.Equal[msg1, msg2, FALSE]] }; SizeOfDatabase: PROC RETURNS[messages, msgSets: INT]; MsgSetExists: PROC[name: ROPE, msDomainVersion: INT] RETURNS [existed: BOOL, msVersion: INT]; CreateMsgSet: PROC[name: ROPE, msDomainVersion: INT] RETURNS [existed: BOOL, msVersion: INT]; NumInMsgSet: PROC[name: ROPE] RETURNS[num: INT, msVersion: INT]; EmptyMsgSet: PROC[msgSet: MsgSet, report: CheckReportProc] RETURNS[someInDeleted: BOOL]; DestroyMsgSet: PROC[msgSet: MsgSet, msDomainVersion: INT, report: CheckReportProc] RETURNS[someInDeleted: BOOL]; VerifyMsgSet: PROC[msgSet: MsgSet] RETURNS[exists: BOOL]; VerifyDomainVersion: PROC[msDomainVersion: INT]; ExpungeMsgs: PROC[deletedVersion: INT, report: CheckReportProc]; MsgsEnumeration: PROC[alphaOrder: BOOL_ TRUE] RETURNS[mL: LIST OF ROPE]; MsgSetsNames: PROC[alphaOrder: BOOL_ TRUE] RETURNS[msL: LIST OF ROPE, msDomainVersion: INT]; MsgsInSetEnumeration: PROC[name: ROPE, fromStart: BOOL_ TRUE] RETURNS [mL: LIST OF ROPE, msVersion: INT]; EnumerateMsgSets: PROC [alphaOrder: BOOL _ TRUE, proc: PROC[msgSet: MsgSet]] RETURNS [msDomainVersion: INT]; EnumerateMsgsInSet: PROC [ name: ROPE, fromStart: BOOL _ TRUE, proc: PROC[msg, TOCentry: ROPE, hasBeenRead: BOOL, startOfSubject: INT] ] RETURNS [msVersion: INT]; EnumerateMsgsInMsgSet: PROC[msgSet: MsgSet] RETURNS [lazyEnum: LazyEnumerator]; NextMsgInMsgSet: PROC[lazyEnum: LazyEnumerator] RETURNS[msgID: ROPE, valid: BOOL]; EnumerateUnacceptedMsgs: PROC[ activeVersion: INT, proc: PROC[msg, TOCentry: ROPE, startOfSubject: INT] ]; EqMsgSets: PROC[msgSet1, msgSet2: ROPE] RETURNS [BOOL] = INLINE{ RETURN[Rope.Equal[msgSet1, msgSet2, FALSE]] }; MsgSetsInfo: PROC RETURNS[version, num: INT]; AddMsg: PROC[msg: ROPE, from, to: MsgSet] RETURNS[exists: BOOL]; RemoveMsg: PROC[msg: ROPE, from: MsgSet, deletedVersion: INT] RETURNS[deleted: BOOL]; MoveMsg: PROC[msg: ROPE, from, to: MsgSet] RETURNS [exists: BOOL]; AcceptNewMail: PROC[pos: INT, activeVersion: INT]; DeclareDB: PROC[segment: WalnutDefs.Segment, schemaInvalid: BOOL]; InitSchema: PROC[segment: WalnutDefs.Segment, schemaInvalid: BOOL _ TRUE]; IsReadOnly: PROC RETURNS[readonly: BOOL]; GetDBName: PROC RETURNS[fileName: ROPE]; GetRootInfo: PROC RETURNS[rootFileStamp: GMT, rootFileKey, mailFor: ROPE]; SetRootInfo: PROC[rootFileStamp: GMT, rootFileKey, mailFor: ROPE]; GetRootFileVersion: PROC RETURNS[rootFileStamp: GMT]; SetRootFileVersion: PROC[rootFileStamp: GMT]; GetCurrentLogFileID: PROC RETURNS[currentLogID: INT]; SetCurrentLogFileID: PROC[currentLogID: INT]; GetOpInProgressPos: PROC RETURNS[inProgressPos: INT]; SetOpInProgressPos: PROC[inProgressPos: INT]; GetParseLogInProgress: PROC RETURNS[inProgress: BOOL]; SetParseLogInProgress: PROC[inProgress: BOOL]; GetParseLogPos: PROC RETURNS[pos: INT]; SetParseLogPos: PROC[pos: INT]; GetTimeOfLastScavenge: PROC RETURNS[when: BasicTime.GMT]; SetTimeOfLastScavenge: PROC[when: BasicTime.GMT]; GetExpungeInfo: PROC RETURNS[firstDestroyedMsgPos, bytesInDestroyedMsgs: INT]; SetExpungeInfo: PROC[firstDestroyedMsgPos, bytesInDestroyedMsgs: INT]; GetLogExpungePhase: PROC RETURNS[expungePhase: LogExpungePhase]; SetLogExpungePhase: PROC[expungePhase: LogExpungePhase]; -- commits GetExpungeProgressInfo: PROC RETURNS[currentLogPos, expungeLogPos: INT]; SetExpungeProgressInfo: PROC[currentLogPos, expungeLogPos: INT]; -- commits SetExpungeFileID: PROC[expungeFileID: INT]; GetExpungeFileID: PROC RETURNS[expungeFileID: INT]; SetTimeOfLastExpunge: PROC[when: BasicTime.GMT]; GetTimeOfLastExpunge: PROC RETURNS[when: BasicTime.GMT]; SetAcceptNewMailPos: PROC[pos: INT]; GetAcceptNewMailPos: PROC RETURNS[pos: INT]; SetAddingServerMsgs: PROC[addingServerMsgs: BOOL]; GetAddingServerMsgs: PROC RETURNS[addingServerMsgs: BOOL]; GetServerInfo: PROC[server: ROPE] RETURNS[num: INT]; EnumerateServers: PROC[] RETURNS[serverList: LIST OF ServerInfo]; SetNewMailInfo: PROC[logLen: INT, when: GMT, server: ROPE, num: INT]; SetNewMailLogLength: PROC[logLen: INT]; GetNewMailLogLength: PROC[] RETURNS[logLen: INT]; GetLastNewMailTimeStamp: PROC[] RETURNS[when: GMT]; SetCopyMailLogPos: PROC[pos: INT]; GetCopyMailLogPos: PROC[] RETURNS[pos: INT]; SetReadArchivePos: PROC[pos: INT]; GetReadArchivePos: PROC[] RETURNS[pos: INT]; SetCopyReadArchivePos: PROC[pos: INT]; GetCopyReadArchivePos: PROC[] RETURNS[pos: INT]; activeMessageSet: READONLY Entity; deletedMessageSet: READONLY Entity; unacceptedEntity: READONLY Entity; msgSetsTable: RefTab.Ref; ChangeCountInMsgSet: PROC[ms: Entity, inc: INT]; ChangeCountOfMsgs: PROC[delta: INT]; CarefullyApply: PROC[proc: PROC[]]; GetMsgDisplayInfo: PROC[m: Entity] RETURNS[hasBeenRead: BOOL, tocEntry: ROPE, startOfSubject: INT]; CanonicalName: PROC[name: ROPE] RETURNS[aName: ATOM]; END. ÀWalnutDB.mesa Copyright c 1984 by Xerox Corporation. All rights reserved. Willie-Sue, September 17, 1986 11:04:00 am PDT Donahue, May 12, 1986 1:43:10 pm PDT Contents: types and procedures dealing with the Walnut message database Initiated by Donahue, 19 April 198entry in the log Last Edited by: Willie-Sue, January 4, 1985 10:38:37 am PST Last edited by Donahue, December 11, 1984 6:23:23 pm PST (Changed ShiftMsgPosition to SetMsgEntryPosition to reflect change in dealing with absolute log positions) (Added operations to set and get new mail and read archive log information -- used on restart) Types -- {idle, initializingExpungeLog, writingExpungeLog, swappingLogs}; Builtin Message Sets Operations on Messages Does a message with this name exist in the database. DestroyMsg is not allowed; this is ONLY done by the Expunge operation returns TRUE if the mHasBeenReadIs attribute for msg is TRUE sets the mHasBeenReadIs attribute for msg to TRUE (no check on old value) takes a parsed message from the log & puts it in the database -- if the message already existed in the database, then return TRUE. Note: this guy takes the LogEntry given and has the responsibility for constructing the TOCEntry and herald for the message returns the log position for the entry for this message (-1 if the message doesn't exist); used by the lazy evaluator Change the message position from what it previously was to the new position; uses a one-entry cache, set by MsgExists, which MUST be called just before SetMsgEntryPosition - this is used by the Expunge code returns the date by which the message is indexed in the database returns information needed to get the tioga text for msg from log returns information needed to get the tioga text for msg from log (also produces the herald to be used if displaying it in a viewer Return the display properties of a message (the hasbeenread flag and the table of contents entry, and where in TOCentry the subject field begins. Return the display properties of a message (the hasbeenread flag and the table of contents entry. returns the number of messages in the database Operations on Message Sets Does this message set already exist in the database. Removes any messages from msgSet. Commits periodically. Destroys the given msgSet, removing any messages from it first. If the message set is "Deleted" then does nothing. Commits periodically. Raises VersionMismatch if the version number is wrong. Raises VersionMismatch if the msgSetDomain version number is wrong. Destroys messages in the Deleted message set. Commits periodically. If msgSet is "Active", only the "accepted" messages are returned for each msg in msgSet, will call proc with the indicated information about the msg; raises WalnutDefs.Error if the enumeration fails If msgSet is "Active", then only the "accepted" messages are enumerated a lazy enumerator for the messages in the msgSet name, at the time of the call. The enumerator is valid until the next time the msgSet's version changes (by adding or deleting msgs); its use after that will cause a WalnutDefs.Error with code $InvalidEnumerator. See NextMsgInMsgSet for details. valid will be false if the msgSet versions don't match if msgID is NIL and valid is true, then the enumeration is finished; if valid is false, the msgSet version numbers don't match for each unaccepted msg, will call proc with the indicated information about the msg; raises WalnutDefs.Error if the enumeration fails changes when msgSets are created or destroyed Operations to Move Messages Among Message Sets Adds Msg to MsgSet, if it's not already in it. IF msgSet=deletedMsgSet, does nothing and returns existed=FALSE IF removing msg from msgSet would leave it in no MsgSet, then msg gets added to the distinguished MsgSet Deleted, and returns deleted = TRUE Move the message. Note that the result of a move may be that a message becomes deleted (if to was the Deleted message set) or undeleted (if from is the Deleted message set) makes new messages visible to the outside world. Commits periodically. Other operations This procedure need only be called once. Of course, if the readOnly status changes DeclareDB[] will have to be called again to establish the new values. must be called after doing an erase is the database readOnly file storing the database information from the root file that goes with this database root file that goes with this database rootFileVersion is needed more often fileID of currentLog Operations used during Expunge, NewMail and reading Archive files returns 0 if server doesn't exist sets newMailLog length to logLen; if server doesn't exist, it will be created taken from WalnutDBInternal Builtin Message Sets Useful variables Procedures changes name to all lower case, to get canonical names Ê *˜šÏn ™ Jšœ Ïmœ1™JšœŸœ$˜>J˜JšœŸœ$˜9JšœC™CJ˜Jšœ Ÿœ˜)JšœŸœŸœ˜-JšœŸœ˜J˜Jš œŸœŸœŸœŸœ˜;—š ™J˜J˜JšœŸœ˜—š ™š œŸœŸœŸœ Ÿœ˜3Jšœ4™4J˜—JšœE™EJ˜š œŸœŸœŸœŸœ˜.Jšœ<™<—J˜šœŸœŸœ˜ JšœI™I—J˜š œŸœ$Ÿœ Ÿœ˜KJšœÿ™ÿ—J˜š œŸœŸœŸœŸœ˜7J™v—J™šœŸœŸœ˜#JšœÎ™Î—J˜š œŸœŸœŸœŸœ˜/Jšœ@™@—J˜š œŸœŸœŸœ Ÿœ˜LJšœA™A—J˜š œŸœŸœŸœ Ÿœ ŸœŸœ˜iJšœƒ™ƒ—J˜šœŸœŸœŸœŸœ ŸœŸœ˜bJšœ‘™‘J˜—š œŸœŸœŸœŸœŸœŸœ˜:Jšœa™a—J˜š œŸœ ŸœŸœŸœ˜.JšŸœŸœŸœ˜/—J˜šœŸœŸœŸœ˜5J™.——š ™š œŸœŸœŸœŸœ Ÿœ Ÿœ˜]Jšœ4™4—J˜Jš œŸœŸœŸœŸœ Ÿœ Ÿœ˜]J˜Jš œŸœŸœŸœŸœ Ÿœ˜@J˜š œŸœ*ŸœŸœ˜XJšœ7™7—J˜š œŸœ"Ÿœ˜RJšœŸœŸœ˜Jšœ‰™‰—J˜š œŸœŸœ Ÿœ˜9Jšœ6™6—J™šœŸœŸœ˜0JšœC™C—J˜š œŸœŸœ˜@JšœC™C—J˜JšœŸœ ŸœŸœŸœŸœŸœŸœ˜HJ˜Jš œŸœ ŸœŸœŸœŸœŸœŸœŸœ˜\J˜šœŸœŸœ ŸœŸœŸœŸœŸœŸœ Ÿœ˜iJ™@—J˜JšœŸœŸœŸœŸœŸœŸœ˜lJ˜šœŸœ Ÿœ ŸœŸœŸœŸœŸœŸœŸœ Ÿœ˜¢J™J™TJ™0J™G—J˜šœŸœŸœ˜OJ™à—J˜š œŸœŸœŸœ Ÿœ˜RJ™~—J˜š œŸœŸœŸœŸœŸœ˜jJ™UJ™0—J™š œŸœŸœŸœŸœ˜8JšŸœŸœŸœ˜6—J˜š œŸœŸœŸœ˜-J™J™-——š .™.š œŸœŸœŸœ Ÿœ˜@J™Jšœo™o—J˜š œŸœŸœ ŸœŸœ Ÿœ˜UJ™JšœŒ™Œ——˜š œŸœŸœŸœ Ÿœ˜BJ™J™­—J™š œŸœŸœŸœ˜2J™JšœF™F—Lš ™š œŸœ-Ÿœ˜BJšœS œ<™˜—J˜š œŸœ-ŸœŸœ˜JJ™#—J˜š œŸœŸœ Ÿœ˜)J™—J˜š œŸœŸœ Ÿœ˜(J™—J˜š œŸœŸœŸœŸœ˜JJ™;—J˜š œŸœŸœŸœ˜BJ™&—J™šœŸœŸœŸœ˜5Jšœ$™$—J˜JšœŸœŸœ˜-J˜šœŸœŸœŸœ˜5J™—J˜JšœŸœŸœ˜-J˜JšœŸœŸœŸœ˜5J˜JšœŸœŸœ˜-J˜JšœŸœŸœ Ÿœ˜6J˜JšœŸœ Ÿœ˜.J˜JšœŸœŸœŸœ˜'J˜JšœŸœŸœ˜J˜JšœŸœŸœŸœ˜9J˜JšœŸœŸœ˜1L™AJšœŸœŸœ-Ÿœ˜NJ˜JšœŸœ-Ÿœ˜FJ˜JšœŸœŸœ ˜@J˜JšœŸœ"¡ ˜DJ˜JšœŸœŸœŸœ˜HJ˜JšœŸœŸœ¡ ˜LJ˜JšœŸœŸœ˜+J˜JšœŸœŸœŸœ˜3J˜JšœŸœŸœ˜0J˜JšœŸœŸœŸœ˜8J˜JšœŸœŸœ˜$J˜JšœŸœŸœŸœ˜,J˜JšœŸœŸœ˜2J˜JšœŸœŸœŸœ˜:J˜š œŸœ ŸœŸœŸœ˜4J™!—J˜Jš œŸœŸœ ŸœŸœ ˜AJ˜š œŸœ ŸœŸœ ŸœŸœ˜EJ™M—J˜JšœŸœ Ÿœ˜'J˜JšœŸœŸœ Ÿœ˜1J˜JšœŸœŸœŸœ˜3J˜JšœŸœŸœ˜"J˜JšœŸœŸœŸœ˜,J˜JšœŸœŸœ˜"J˜JšœŸœŸœŸœ˜,J˜JšœŸœŸœ˜&J˜JšœŸœŸœŸœ˜0—J˜J™šœ™š ™JšœŸœ˜"JšœŸœ˜#JšœŸœ˜"—š ™Jšœ˜—š  ™ JšœŸœŸœ˜0J˜JšœŸœŸœ˜$J˜JšœŸœŸœ˜#J˜šœŸœ ˜"JšŸœŸœ ŸœŸœ˜@—J˜š œŸœŸœŸœŸœ˜5Jšœ6™6——J˜J˜J˜—JšŸœ˜J˜—…—ˆ8r