<> <> <> <> <> <> <> <> DIRECTORY DB, MBQueue, MessageWindow, NutOps, Rope, PrincOpsUtils, ViewerClasses; NutOpsImpl: CEDAR MONITOR IMPORTS DB, Rope, PrincOpsUtils EXPORTS NutOps = BEGIN OPEN DB; Viewer: TYPE = ViewerClasses.Viewer; ROPE: TYPE = Rope.ROPE; <> IsSystemDomain: PUBLIC PROC[ name: Rope.ROPE ] RETURNS[ BOOLEAN ] = { RETURN[ SELECT TRUE FROM Rope.Equal[name, "DomainDomain"] => TRUE, Rope.Equal[name, "RelationDomain"] => TRUE, Rope.Equal[name, "DataTypeDomain"] => TRUE, Rope.Equal[name, "AttributeDomain"] => TRUE, Rope.Equal[name, "IndexDomain"] => TRUE, Rope.Equal[name, "IndexFactorDomain"] => TRUE, ENDCASE => FALSE ] }; IsSystemRelation: PUBLIC PROC[name: Rope.ROPE] RETURNS[BOOLEAN] = { RETURN[ SELECT TRUE FROM Rope.Equal[name, "dSubType"] => TRUE, Rope.Equal[name, "aRelation"] => TRUE, Rope.Equal[name, "aType"] => TRUE, Rope.Equal[name, "aUniqueness"] => TRUE, Rope.Equal[name, "aLength"] => TRUE, Rope.Equal[name, "aLink"] => TRUE, Rope.Equal[name, "ifIndex"] => TRUE, Rope.Equal[name, "ifAttribute"] => TRUE, ENDCASE => FALSE ] }; IsSystemEntity: PUBLIC PROC[name: Rope.ROPE] RETURNS[BOOLEAN] = BEGIN RETURN[ Rope.Equal[name, "Attribute"] OR Rope.Equal[name, "DataType"] OR Rope.Equal[name, "Domain"] OR Rope.Equal[name, "Relation"] ]; END; AttributesOf: PUBLIC PROC[r: Relation] RETURNS[AttributeList] = {IF Eq[r, dSubType] THEN RETURN[LIST[dSubTypeIs, dSubTypeOf]]; IF Eq[r, aRelation] THEN RETURN[LIST[aRelationOf, aRelationIs]]; IF Eq[r, aType] THEN RETURN[LIST[aTypeOf, aTypeIs]]; IF Eq[r, aUniqueness] THEN RETURN[LIST[aUniquenessOf, aUniquenessIs]]; IF Eq[r, aLength] THEN RETURN[LIST[aLengthOf, aLengthIs]]; IF Eq[r, aLink] THEN RETURN[LIST[aLinkOf, aLinkIs]]; IF Eq[r, ifIndex] THEN RETURN[LIST[ifIndexOf, ifIndexIs]]; IF Eq[r, ifAttribute] THEN RETURN[LIST[ifAttributeOf, ifAttributeIs]]; RETURN[VL2EL[GetPList[r, aRelationOf]]]}; FirstAttributeOf: PUBLIC PROC[r: Relation] RETURNS[Attribute] = BEGIN es: AttributeList_ VL2EL[GetPList[r, aRelationOf]]; IF es=NIL THEN RETURN[NIL] ELSE RETURN[es.first] END; EntityValued: PUBLIC PROC [a: Attribute] RETURNS[BOOL] = BEGIN type: Entity; IF a=NIL OR Null[a] THEN RETURN[FALSE]; type_ V2E[GetP[a, aTypeIs]]; SELECT type FROM IntType, RopeType, BoolType, RecordType, TimeType => RETURN[FALSE]; ENDCASE => RETURN[TRUE]; END; GetUniquenessString: PUBLIC PROC[a: Attribute] RETURNS[ROPE] = BEGIN u: Uniqueness; IF Eq[a, dSubTypeIs] THEN RETURN["NonKey"]; IF Eq[a, dSubTypeOf] THEN RETURN["NonKey"]; IF Eq[a, aRelationOf] THEN RETURN["Key"]; IF Eq[a, aRelationIs] THEN RETURN["NonKey"]; IF Eq[a, aTypeOf] THEN RETURN["Key"]; IF Eq[a, aTypeIs] THEN RETURN["NonKey"]; IF Eq[a, aUniquenessOf] THEN RETURN["Key"]; IF Eq[a, aUniquenessIs] THEN RETURN["NonKey"]; IF Eq[a, aLengthOf] THEN RETURN["Key"]; IF Eq[a, aLengthIs] THEN RETURN["NonKey"]; IF Eq[a, aLinkOf] THEN RETURN["Key"]; IF Eq[a, aLinkIs] THEN RETURN["NonKey"]; IF Eq[a, ifIndexOf] THEN RETURN["Key"]; IF Eq[a, ifIndexIs] THEN RETURN["NonKey"]; IF Eq[a, ifAttributeOf] THEN RETURN["Key"]; IF Eq[a, ifAttributeIs] THEN RETURN["NonKey"]; u_ V2U[GetP[a, aUniquenessIs]]; SELECT u FROM Key => RETURN["Key"]; KeyPart => RETURN["KeyPart"]; None => RETURN["NonKey"]; OptionalKey => RETURN["OptionalKey"]; ENDCASE => RETURN["???"]; END; GetTuples: PUBLIC PROC[e: Entity, a: Attribute] RETURNS [tl: LIST OF Relship] = <> {RETURN[RelshipSetToList[RelationSubset[GetRelation[a], LIST[[a, e]] ]]]}; GetRelation: PUBLIC PROC[a: Attribute] RETURNS[r: Relation] = <> {RETURN[V2E[GetP[a, aRelationIs]]]}; GetRefAttributes: PUBLIC PROC[d: Domain] RETURNS[al: LIST OF Attribute] = <> BEGIN starRelation: Relation_ DeclareRelation["*", SafeSegmentOf[d]]; starOf: Attribute; starIs: Attribute; starList: LIST OF Attribute; starOf _ DeclareAttribute[r: starRelation, name: "of", type: AnyDomainType, version: OldOnly ! DB.Error => CHECKED { starOf _ NIL; CONTINUE } ]; starIs _ DeclareAttribute[r: starRelation, name: "is", type: AnyDomainType, version: OldOnly ! DB.Error => CHECKED { starIs _ NIL; CONTINUE } ]; starList _ SELECT TRUE FROM starOf = NIL AND starIs = NIL => NIL, starIs = NIL => LIST[starOf], starOf = NIL => LIST[starIs], ENDCASE => LIST[starOf, starIs]; al_ GetDomainRefAttributes[d]; al_ AppendAttributes[al, starList]; END; RemoveAttribute: PUBLIC PROC[a: Attribute, al: AttributeList] RETURNS[AttributeList] = <> BEGIN alLast: AttributeList_ NIL; FOR alT: AttributeList_ al, alT.rest UNTIL alT=NIL DO IF Eq[alT.first, a] THEN IF alLast=NIL THEN RETURN[alT.rest] -- was first element ELSE {alLast.rest_ alT.rest; RETURN[al]}; -- was another element alLast_ alT; ENDLOOP; RETURN[al] -- not found END; AppendAttributes: PUBLIC PROC [al1, al2: AttributeList] RETURNS [al: AttributeList] = BEGIN IF al1=NIL THEN RETURN [al2]; al_ al1; UNTIL al1.rest=NIL DO al1_ al1.rest ENDLOOP; al1.rest_ al2; RETURN[al] END; RSetSize: PUBLIC PROC[rs: RelshipSet] RETURNS[INT] = BEGIN FOR size: INT IN [0..200) DO IF Null[NextRelship[rs]] THEN {ReleaseRelshipSet[rs]; RETURN[size]}; ENDLOOP; ReleaseRelshipSet[rs]; RETURN[9999]; -- just tell 'im there are lots for now END; SetUpSegment: PUBLIC PROC[ segmentFile: ROPE, seg: DB.Segment, number: NAT _ 0, makeReadOnly: BOOL _ FALSE ] RETURNS [readOnly: BOOL] = TRUSTED { <> readOnly _ FALSE; IF DB.TransactionOf[seg] # NIL THEN {readOnly_ DB.GetSegmentInfo[seg].readOnly; RETURN}; DB.DeclareSegment[filePath: segmentFile, segment: seg, number: number, readonly: makeReadOnly, createIfNotFound: NOT makeReadOnly ]; DB.OpenTransaction[seg ! DB.Error => TRUSTED { SELECT code FROM ProtectionViolation => IF NOT makeReadOnly THEN {readOnly _ TRUE; CONTINUE} ELSE REJECT; ENDCASE => REJECT } ]; IF readOnly THEN { -- Try opening it readonly now; give up on a failure DB.CloseTransaction[DB.TransactionOf[seg]]; -- DB has left the transaction open DB.DeclareSegment[segmentFile, seg, number, TRUE, FALSE]; DB.OpenTransaction[seg] } }; TryRestart: PUBLIC PROC[trans: DB.Transaction] RETURNS[success: BOOL, failureReason: ATOM] = { segment: DB.Segment = GetSegment[trans]; fileName: ROPE = DB.GetSegmentInfo[segment].filePath; { ENABLE DB.Failure => {failureReason _ what; success _ FALSE; GOTO Quit}; DB.AbortTransaction[trans]; <> success _ FALSE; FOR i: INT IN [0..5) WHILE NOT success DO DB.OpenTransaction[segment ! DB.Aborted => LOOP; DB.Error => IF code = TransactionAlreadyOpen THEN CONTINUE]; success _ TRUE ENDLOOP; EXITS Quit => NULL } }; Do: PUBLIC PROC[ proc: PROC[REF ANY], clientData: REF ANY _ NIL] RETURNS [outcome: NutOps.Outcome] = { ENABLE BEGIN DB.Error => {outcome _ error; GOTO Quit}; DB.Failure => {outcome _ failure; GOTO Quit}; DB.Aborted => {outcome _ abort; GOTO Quit}; END; outcome _ success; proc[clientData] EXITS Quit => NULL }; GetSegment: PROC [t: DB.Transaction] RETURNS [seg: DB.Segment] = { <> segs: LIST OF DB.Segment_ DB.GetSegments[]; FOR segs_ segs, segs.rest UNTIL segs=NIL DO IF DB.TransactionOf[segs.first]=t THEN RETURN[segs.first] ENDLOOP; RETURN[NIL] }; SafeNameOf: PUBLIC PROC[e: Entity] RETURNS [s: ROPE] = BEGIN IF DB.Null[e] THEN RETURN["NEW"] ELSE RETURN [ DB.NameOf[e] ] END; SafeSegmentOf: PUBLIC PROC[e: EntityOrRelship] RETURNS [s: Segment] = BEGIN IF DB.Null[e] THEN RETURN[NIL] ELSE RETURN [ DB.SegmentOf[e] ] END; SafeDomainOf: PUBLIC PROC[e: Entity] RETURNS [s: Domain] = BEGIN IF DB.Null[e] THEN RETURN[NIL] ELSE RETURN [ DB.DomainOf[e] ] END; END. Changes since October 82: Cattell October 13, 1982 9:28 am: Save and Reset buttons should Fork. Cattell December 1, 1982 4:29 pm: Should call GetRope instead of GetToken for 2nd DBShow argument. Cattell June 22, 1983 5:08 pm: Butler June 26, 1984: Updated to comply with new organization of Nut and Squirrel