-- WalnutDB.mesa
-- Contents: types and procedures dealing with the Walnut message database
-- Initiated by Donahue, 19 April 1983

-- Last Edited by: Willie-Sue, May 18, 1983 3:29 pm

DIRECTORY
DB,
IO USING [STREAM],
 WalnutLog;

WalnutDB: CEDAR DEFINITIONS
IMPORTS DB, WalnutLog =

BEGIN OPEN WalnutLog;

Entity: TYPE = DB.Entity;  -- for other Walnut modules
Domain: TYPE = DB.Domain;
AttributeValueList: TYPE = DB.AttributeValueList;
Relation: TYPE = DB.Relation;
Relship: TYPE = DB.Relship;
RelshipSet: TYPE = DB.RelshipSet;
Value: TYPE = DB.Value;
Attribute: TYPE = DB.Attribute;

Msg, MsgSet: TYPE = Entity;

RelshipMsgSetPair: TYPE = RECORD[rel: Relship, msgSet: MsgSet];

Version: TYPE = DB.Version;  -- for DeclareMsg(Set) {OldOnly, NewOnly, NewOrOld}

-- ********************************************************
-- useful TYPEs needed by Walnut

ROPE: TYPE = WalnutLog.ROPE;
TiogaContents: TYPE = WalnutLog.TiogaContents;

-- ********************************************************
-- Global types
MsgDomain: Domain;
MsgSetDomain: Domain;

activeMsgSet: MsgSet;
deletedMsgSet: MsgSet;

-- Relations on Msg entities: all have one relship per Msg unless otherwise noted.

msNumInSet: PUBLIC Relation;
msNumInSetOf: PUBLIC Attribute; -- MsgSet
msNumInSetIs: PUBLIC Attribute; -- INT

mDateCode: PUBLIC Relation;
mDateCodeOf: PUBLIC Attribute; -- Msg
mDateCodeIs: PUBLIC Attribute; -- Time

mSubject: PUBLIC Relation;
mSubjectOf: PUBLIC Attribute; -- Msg
mSubjectIs: PUBLIC Attribute; -- string

mCategory: PUBLIC Relation;
mCategoryOf: PUBLIC Attribute; -- Msg
mCategoryIs: PUBLIC Attribute; -- MsgSet
mCategoryDate: PUBLIC Attribute; -- Index on Category & Date

mInReplyTo: PUBLIC Relation;
mInReplyToOf: PUBLIC Attribute; -- Msg
mInReplyToMsg: PUBLIC Attribute; -- Msg
mInReplyToIs: PUBLIC Attribute; -- the string from the msg

mTOCEntry: PUBLIC Relation;
mTOCEntryOf: PUBLIC Attribute; -- Msg
mTOCEntryIs: PUBLIC Attribute; -- string

mLogPos: PUBLIC Relation;
mLogPosOf: PUBLIC Attribute; -- Msg
mPrefixPos: PUBLIC Attribute; -- int
mHeadersPos: PUBLIC Attribute; -- int

mMsgLength: PUBLIC Relation;
mMsgLengthOf: PUBLIC Attribute; -- Msg
mMsgLengthIs: PUBLIC Attribute; -- int

mHasBeenRead: PUBLIC Relation;
mHasBeenReadOf: PUBLIC Attribute; -- Msg
mHasBeenReadIs: PUBLIC Attribute; -- bool

-- ********************************************************
-- each operation here has a parallel operation in WalnutDBLog, which writes an entry
-- on the current log

DeclareMsg
: PROC[mName: ROPE, version: Version← NewOrOld]
  RETURNS [msg: Msg, existed: BOOL];
-- Creates a new Msg entity (unless version = oldOnly), and sets its name to be mName.
-- is called when messages have been read from the log or another file.
-- If the Msg already exists, returns it and existed=TRUE

DeclareMsgSet: PROC[msName: ROPE, version: Version← NewOrOld]
  RETURNS [msgSet: MsgSet, existed: BOOL];
-- Creates a new MsgSet entity (unless version = oldOnly), and sets its name to be mName.
-- is called when user creates a message set, or a log file is read
-- If the MsgSet already exists, returns it and existed=TRUE.

-- DestroyMsg is not allowed; this is ONLY done by the Expunge operation

DestroyMsgSet: PROC[msgSet: MsgSet] RETURNS[newRelList: LIST OF Relship];
-- Destroys the given msgSet, removing any messages from it first (uses equivalalent of
-- RemoveMsgFromMsgSet below)


AddMsgToMsgSet: PROC[msg: Msg, msgSet: MsgSet] RETURNS[rel: Relship, existed: BOOL];
-- Adds Msg to MsgSet, if it's not already in it
-- IF msgSet=deletedMsgSet, does nothing & returns rel=NIL, existed=FALSE

RemoveMsgFromMsgSet: PROC[msg: Msg, msgSet: MsgSet, rel: Relship← NIL]
  RETURNS[newRel: Relship];
-- rel can be NIL, in which case it is found from the database
-- IF removing msg from msgSet would leave it in no MsgSet, then msg gets added to
-- the distinguished MsgSet Deleted, and returns that new Relship
-- does nothing if this Relship doesn't exist (no ERROR generated)

SetMsgHasBeenRead: PROC[msg: Msg];
-- sets the mHasBeenReadIs attribute for msg to TRUE (no check on old value)

-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

-- other database access

InitializeDBVars: PROC;

MsgRecToMsg: PROC[mr: WalnutLog.MsgRec]
RETURNS[msg: Msg, mExisted: BOOL,
    newMsgSetList: LIST OF MsgSet, newRelList: LIST OF RelshipMsgSetPair];
-- takes a parsed message in record form & puts it in the database

TiogaMsgFromLog: PROC[msg: Msg] RETURNS[contents: TiogaContents, startPos, length: INT];
-- reads tioga text for msg from log

NumInMsgSet: PROC[msgSet: MsgSet] RETURNS[INT];

ArchiveMsgSet: PROC[msgSet: MsgSet, strm: IO.STREAM, doDelete: BOOL]
  RETURNS[newRelList: LIST OF Relship];
-- needs to be entirely inside the DB monitor
-- if doDelete is TRUE, relturns list of newRels for msgs added to Deleted

NameToEntity: PROC[d: Domain, name: ROPE, version: Version] RETURNS[e: Entity];

GetEntitiesInDomain: PROC[d: Domain, alphaOrder: BOOL] RETURNS[eL: LIST OF Entity];

RelationSubsetList: PROC[r: Relation, constraint: AttributeValueList← NIL]
  RETURNS[relList: LIST OF Relship];

GetFE: PROC[rel: Relship, a: Attribute] RETURNS [Entity];

GetName: PROC[e: Entity] RETURNS [ROPE];

Null: PROC[e: Entity] RETURNS [BOOL];

EqEntities: PROC[e1, e2: Entity] RETURNS [BOOL] = INLINE {RETURN[DB.Eq[e1, e2]]};

V2E
: PROC [ra: REF ANY] RETURNS [Entity] = INLINE {RETURN[DB.V2E[ra]]};

V2S: PROC [ra: REF ANY] RETURNS [ROPE] = INLINE {RETURN[DB.V2S[ra]]};

I2V: PROC [i: INT] RETURNS[REF INT] = INLINE {RETURN[DB.I2V[i]]};

V2B: PROC[ra: REF ANY] RETURNS [BOOL] = INLINE {RETURN[DB.V2B[ra]]};

B2V: PROC[b: BOOL] RETURNS [REF BOOL] = INLINE {RETURN[DB.B2V[b]]};

MGetP: PROC[m: Msg, prop: Attribute] RETURNS [Value];
-- Finds the one unique value for prop for m or NIL if none.
-- SIGNALs NonUniquePropertyValue if more than one value.

MSetPList: PROC[m: Msg, prop: Attribute, vl: LIST OF Value];
-- Sets the values of prop for m to be those in vl.
-- Erases any previous property values.

MSetP: PROC[m: Msg, prop: Attribute, v: Value] RETURNS [Relship];
-- Sets the value of prop for m to be v.
-- Erases any previous property value(s).
-- Returns the relship used by the prop.

AcquireDBLock: PROC[procToCall: PROC];
-- to allow extended use of lock on database

-- ********************************************************
-- so that the newVersion bit in the Walnut Control window can be kept current

RegisterUpdatesPendingProc: PROC[proc: PROC[BOOL]];

UnRegisterUpdatesPendingProc: PROC[proc: PROC[BOOL]];

END.