<> <> <> <> <> <> <> DIRECTORY Basics USING [LowHalf], DBStorage, DBTuplesConcrete, DBEnvironment, DB, DBModel, DBModelPrivate, Rope USING [ROPE, Concat]; DBModelSystemImpl: CEDAR PROGRAM IMPORTS DBStorage, DBModel, DBModelPrivate, Basics, Rope EXPORTS DB, DBModelPrivate, DBEnvironment = BEGIN OPEN DBStorage, DB, DBModelPrivate, DBModel; ROPE: TYPE = Rope.ROPE; <> Error: PUBLIC SIGNAL[code: DBEnvironment.ErrorCode] = CODE; Aborted: PUBLIC ERROR [trans: REF ANY] = CODE; InternalError: PUBLIC SIGNAL = CODE; Failure: PUBLIC ERROR[trans: REF ANY, what: ATOM, info: Rope.ROPE] = CODE; <> TupleObject: PUBLIC TYPE = DBTuplesConcrete.TupleObject; EntityObject: PUBLIC TYPE = TupleObject; RelshipObject: PUBLIC TYPE = TupleObject; EntitySetObject: PUBLIC TYPE = DBTuplesConcrete.EntitySetObject; RelshipSetObject: PUBLIC TYPE = DBTuplesConcrete.RelshipSetObject; <> Tuple, TupleSet, Index, IndexFactor: TYPE = REF TupleObject; Domain, Relation, Entity, Attribute, Property, DataType: PUBLIC TYPE = REF EntityObject; Relship: PUBLIC TYPE = REF RelshipObject; EntitySet: PUBLIC TYPE = REF EntitySetObject; RelshipSet: PUBLIC TYPE = REF RelshipSetObject; SystemATuple: TYPE = REF attribute TupleObject; SystemTSTuple: TYPE = REF tupleSet TupleObject; SystemETuple: TYPE = REF entity TupleObject; T2SAT: PROC[t: TupleHandle] RETURNS [SystemATuple] = BEGIN RETURN [NARROW[t]] END; T2STT: PROC[t: TupleHandle] RETURNS [SystemTSTuple] = INLINE BEGIN RETURN [NARROW[t]] END; T2SET: PROC[t: TupleHandle] RETURNS [SystemETuple] = INLINE BEGIN RETURN [NARROW[t]] END; <> AnyDomainType, BoolType, IntType, RecordType, TimeType, RopeType: PUBLIC DataType; <> systemTupleVec: PUBLIC REF STSVecType _ NEW[STSVecType_ ALL[NIL]]; attributeIDCount: LONG CARDINAL_ 0; <> <> <> <> <> <> DomainDomain: PUBLIC Domain; -- one element per client-defined domain dHandleProp: PUBLIC Property; -- the storage level tupleset handle dIndexProp: PUBLIC Property; -- the storage level index handle for this domain dSubType: PUBLIC Relation; -- one element per direct sub-super type relationship dSubTypeOf: PUBLIC Attribute; -- domain: the super-type dSubTypeIs: PUBLIC Attribute; -- domain: the sub-type RelationDomain: PUBLIC Domain; -- one element per client-defined relation rHandleProp: PUBLIC Property; -- the storage level tupleset handle r1to1Prop: PUBLIC Property; -- TRUE iff this relation is a surrogate relation AttributeDomain: PUBLIC Domain; -- one element per client-defined attribute aHandleProp: PUBLIC Property; -- the storage level handle for this field aTypeCodeProp: PUBLIC Property; -- tid of the type entity, or zero if domain-valued aTypeEntityProp: PUBLIC Property; -- the domain this attribute refs, or NIL if datum-valued aRelation: PUBLIC Relation; -- one element per client-defined attribute aRelationOf: PUBLIC Attribute; -- the attribute aRelationIs: PUBLIC Attribute; -- relation of the attribute aType: PUBLIC Relation; -- one element per client-defined attribute aTypeOf: PUBLIC Attribute; -- the attribute aTypeIs: PUBLIC Attribute; -- domain or datatype of the attribute aUniqueness: PUBLIC Relation; -- one element per client-defined attribute aUniquenessOf: PUBLIC Attribute; -- the attribute aUniquenessIs: PUBLIC Attribute; -- INT corresponding to its uniqueness aLength: PUBLIC Relation; -- one element per client-defined attribute aLengthOf: PUBLIC Attribute; -- the attribute aLengthIs: PUBLIC Attribute; -- INT corresponding to attribute's length aLink: PUBLIC Relation; -- one element per client-defined attribute aLinkOf: PUBLIC Attribute; -- the attribute aLinkIs: PUBLIC Attribute; -- INT corresponding to its LinkType. aDomain: PUBLIC Relation; -- exported to DBModelPrivate: one elt per client-defined attribute aDomainOf: PUBLIC Attribute; -- the attribute aDomainIs: PUBLIC Attribute; -- non-NIL only if this is the first (targetted) attribute of <> <> aUnlinked: PUBLIC Relation; -- exported to DBModelPrivate: one elt per client-defined attribute aUnlinkedOf: PUBLIC Attribute; -- the attribute aUnlinkedIs: PUBLIC Attribute; -- non-NIL only if this attribute is NOT linked, in which <> DataTypeDomain: PUBLIC Domain; -- RopeType, BoolType, etc. are of this domain IndexDomain: PUBLIC Domain; -- one element per client-defined index iHandleProp: PUBLIC Property; -- index handle, set by storage level IndexFactorDomain: PUBLIC Domain; -- one element per attribute in an index ifIndex: PUBLIC Relation; -- one element per attribute in an index (an "index factor") ifIndexOf: PUBLIC Attribute; -- the index factor ifIndexIs: PUBLIC Attribute; -- the index this index factor belongs to ifOrdinalPosition: PUBLIC Relation; -- one element per index factor ifOrdinalPositionOf: PUBLIC Attribute; -- the index factor ifOrdinalPositionIs: PUBLIC Attribute; -- the position of this index factor in the ordering ifAttribute: PUBLIC Relation; -- one element per index factor ifAttributeOf: PUBLIC Attribute; -- the index factor ifAttributeIs: PUBLIC Attribute; -- the attribute this index factor indexes <> defaultDomainIndex, defaultRelationIndex: PUBLIC DBStorage.IndexHandle; defaultNameHandle, attributeNameHandle, tupleSetNameHandle: PUBLIC DBStorage.FieldHandle; defaultNameAttribute: PUBLIC Attribute; DefaultNameSize: CARDINAL = 20; <> minfString: PUBLIC ROPE _ ""; -- less than any other string infString: PUBLIC ROPE _ "\177"; -- greater than any other string InitializeSystemTuples: PUBLIC PROC = TRUSTED BEGIN dNameProp, rNameProp, aNameProp: Domain; -- only need temporarily DBStorage.SetSystemTupleTable[systemTupleVec]; <> DomainDomain_ DefineSystemDomain[DomainTSID, "Domain"]; RelationDomain_ DefineSystemDomain[RelationTSID, "Relation"]; AttributeDomain_ DefineSystemDomain[AttributeTSID, "Attribute"]; DataTypeDomain_ DefineSystemDomain[DataTypeTSID, "DataType"]; IndexDomain_ DefineSystemDomain[IndexTSID, "Index"]; IndexFactorDomain_ DefineSystemDomain[IndexFactorTSID, "IndexFactor"]; <> RopeType_ DefineSystemEntity[RopeTypeID, DataTypeDomain, "RopeType"]; IntType_ DefineSystemEntity[IntTypeID, DataTypeDomain, "IntType"]; TimeType_ DefineSystemEntity[TimeTypeID, DataTypeDomain, "TimeType"]; BoolType_ DefineSystemEntity[BoolTypeID, DataTypeDomain, "BoolType"]; RecordType_ DefineSystemEntity[RecordTypeID, DataTypeDomain, "RecordType"]; AnyDomainType_ DefineSystemEntity[AnyDomainTypeID, DataTypeDomain, "AnyDomainType"]; FakeTheNameHandle[]; -- must call after RopeType defined but before any real entities <> dHandleProp_ DefinePrivateProperty[ DomainDomain, "dHandleProp", RecordType, DBStorage.TuplesetObjectSize]; <> dNameProp_ DefinePrivateProperty[DomainDomain, "dName", RopeType, DefaultNameSize]; tupleSetNameHandle_ T2SAT[dNameProp].vHandle; dIndexProp_ DefinePrivateProperty[DomainDomain, "dIndexProp", IndexDomain]; rHandleProp_ DefinePrivateProperty[ RelationDomain, "rHandleProp", RecordType, DBStorage.TuplesetObjectSize]; <> rNameProp_ DefinePrivateProperty[ RelationDomain, "rNameProp", RopeType, DefaultNameSize]; <> r1to1Prop_ DefinePrivateProperty[RelationDomain, "r1to1", BoolType]; aHandleProp_ DefinePrivateProperty[ AttributeDomain, "aHandleProp", RecordType, DBStorage.FieldObjectSize]; <> aNameProp_ DefinePrivateProperty[AttributeDomain, "aName", RopeType]; attributeNameHandle_ T2SAT[aNameProp].vHandle; aTypeCodeProp_ DefinePrivateProperty[ AttributeDomain, "aTypeCodeProp", IntType]; aTypeEntityProp_ DefinePrivateProperty[ AttributeDomain, "aTypeEntityProp", DomainDomain]; iHandleProp_ DefinePrivateProperty[ IndexDomain, "iHandleProp", RecordType, DBStorage.IndexObjectSize]; <> <> FakeTheTypeAndLinkRelations[]; [aRelation, aRelationOf, aRelationIs]_ DefineSystemBinary[ id: aRelationTSID, name: "aRelation", of: AttributeDomain, is: RelationDomain]; [aUniqueness, aUniquenessOf, aUniquenessIs]_ DefineSystemBinary[ id: aUniquenessTSID, name: "aUniqueness", of: AttributeDomain, is: IntType]; [aLength, aLengthOf, aLengthIs]_ DefineSystemBinary[ id: aLengthTSID, name: "aLength", of: AttributeDomain, is: IntType]; [aDomain, aDomainOf, aDomainIs]_ DefineSystemBinary[ id: aDomainTSID, name: "aDomain", of: AttributeDomain, is: DomainDomain]; [aUnlinked, aUnlinkedOf, aUnlinkedIs]_ DefineSystemBinary[ id: aUnlinkedTSID, name: "aUnlinked", of: AttributeDomain, is: DomainDomain]; [ifIndex, ifIndexOf, ifIndexIs]_ DefineSystemBinary[ id: ifIndexTSID, name: "ifIndex", of: IndexFactorDomain, is: IndexDomain]; [ifOrdinalPosition, ifOrdinalPositionOf, ifOrdinalPositionIs]_ DefineSystemBinary[ id: ifOrdinalPositionTSID, name: "ifOrdinalPosition", of: IndexFactorDomain, is: IntType]; [ifAttribute, ifAttributeOf, ifAttributeIs]_ DefineSystemBinary[ id: ifAttributeTSID, name: "ifAttribute", of: IndexFactorDomain, is: AttributeDomain]; [dSubType, dSubTypeOf, dSubTypeIs]_ DefineSystemBinary[ id: dSubTypeTSID, name: "dSubType", of: DomainDomain, is: DomainDomain, is1to1: FALSE]; END; FakeTheNameHandle: PROC = <> <> BEGIN fakeReln: TupleSet_ DefineSystemTupleSet[DummyID, "fakeReln", FALSE, FALSE]; defaultNameAttribute_ DefineSystemField[fakeReln, "defaultNameAttribute", RopeType]; defaultNameHandle_ T2SAT[defaultNameAttribute].vHandle; END; FakeTheTypeAndLinkRelations: PROC = <> <> <> <> <> <<(1) If aTypeEntityProp=NIL, then we have a non-entity-valued attribute, and the>> <> <<(2) If aTypeEntityProp#NIL, then it references the domain that is the type of the>> <> <> <> <> <> <> <> BEGIN aType_ DefineSystemTupleSet[ id: aTypeTSID, name: "aType", isDomain: FALSE, is1to1: TRUE]; aTypeOf_ DefineSystemFieldObject[aType, "aTypeOf", AttributeDomain]; aTypeIs_ DefineSystemField[aType, "aTypeIs", DataTypeDomain]; T2SAT[aTypeIs].vHandle_ T2SAT[aTypeEntityProp].vHandle; -- so group scans work on type T2SAT[aTypeOf].vRelation_ T2SAT[aTypeIs].vRelation_ aType; T2STT[aType].vAttributes_ LIST[aTypeOf, aTypeIs]; aLink_ DefineSystemTupleSet[ id: aLinkTSID, name: "aLink", isDomain: FALSE, is1to1: TRUE]; aLinkOf_ DefineSystemFieldObject[aLink, "aLinkOf", AttributeDomain]; aLinkIs_ DefineSystemField[aLink, "aLinkIs", IntType]; T2STT[aLink].vAttributes_ LIST[aLinkOf, aLinkIs]; T2SAT[aLinkOf].vRelation_ T2SAT[aLinkIs].vRelation_ aLink; END; DefineSystemDomain: PROC [id: LONG CARDINAL, name: ROPE] RETURNS [Domain] = INLINE {RETURN[DefineSystemTupleSet[id, name, TRUE, FALSE]]}; DefineSystemBinary: PROC [ id: LONG CARDINAL, name: ROPE, of: DataType, is: DataType, is1to1: BOOL_ TRUE] RETURNS [r: Relation, rOf, rIs: Attribute] = <> <> <> <> <> <> BEGIN r_ DefineSystemTupleSet[id, name, FALSE, is1to1]; IF is1to1 THEN <> BEGIN rOf_ DefineSystemFieldObject[of, Rope.Concat[name, "Of"], of]; rIs_ DefineSystemField[of, Rope.Concat[name, "Is"], is, DefaultNameLength]; END ELSE <> BEGIN rOf_ DefineSystemField[r, Rope.Concat[name, "Of"], of]; rIs_ DefineSystemField[r, Rope.Concat[name, "Is"], is, DefaultNameLength]; END; T2STT[r].vAttributes_ LIST[rOf, rIs]; T2SAT[rOf].vRelation_ T2SAT[rIs].vRelation_ r; END; DefineSystemTupleSet: PROC[id: LONG CARDINAL, name: ROPE, isDomain: BOOL, is1to1: BOOL] RETURNS[TupleSet] = TRUSTED <> BEGIN t: SystemTSTuple; IF id>MaxVTID THEN ERROR InternalError; t_ T2STT[DBStorage.ConsSystemTupleObject[tupleSet]]; t.tid_ id; t.vTuple_ DBStorage.CreateSystemTupleset[id]; -- SLevel tuple representing this abstraction t.vName_ name; -- name of this tupleset. t.vR1to1_ is1to1; t.vIsDomain_ isDomain; systemTupleVec[Basics.LowHalf[id]]_ t; RETURN[t] END; DefineSystemField: PROC[ ts: TupleSet, name: ROPE, type: DataType, length: CARDINAL_ 0] RETURNS[Attribute] = TRUSTED <> <> BEGIN f: Attribute_ DefineSystemFieldObject[ts, name, type]; <> T2SAT[f].vHandle_ DBStorage.AddSystemField[T2STT[ts].vTuple, MakeFD[type, length,, f]]; RETURN[f] END; DefineSystemFieldObject: PROC[ ts: TupleSet, name: ROPE, type: DataType] RETURNS[Attribute] = TRUSTED <> <> BEGIN t: SystemATuple_ T2SAT[DBStorage.ConsSystemTupleObject[attribute]]; t.tid_ FirstAttributeID + attributeIDCount; t.vType_ type; -- what type this attribute can point to t.vName_ name; -- attribute name attributeIDCount_ attributeIDCount+1; IF FirstAttributeID+attributeIDCount>MaxVTID THEN SIGNAL InternalError; systemTupleVec[Basics.LowHalf[attributeIDCount+FirstAttributeID-1]]_ t; RETURN[t] END; DefineSystemEntity: PROC[ id: LONG CARDINAL, d: Domain, name: ROPE] RETURNS [Entity] = TRUSTED <> BEGIN e: SystemETuple_ T2SET[DBStorage.ConsSystemTupleObject[entity]]; e.tid_ id; e.vName_ name; e.vParent_ d; systemTupleVec[Basics.LowHalf[id]]_ e; RETURN[e] END; DefinePrivateProperty: PROC [ d: Domain, name: ROPE, type: DataType, length: INT_ 0] RETURNS [Property] = <> <> <> <> <> <> <> <> BEGIN fakeAttribute: Attribute; fakeAttribute_ DefineSystemField[d, name, type, length]; T2STT[d].vAttributes_ CONS[fakeAttribute, T2STT[d].vAttributes]; T2SAT[fakeAttribute].vRelation_ d; RETURN[fakeAttribute] END; <> SystemDomainSubset: PUBLIC PROC[ d: Domain, lowName, highName: ROPE, segment: Segment] RETURNS [es: EntitySet] = TRUSTED <> <> <> <> <> <> <> <> BEGIN MakeIndexScan: PROC[indexToScan: DBStorage.IndexHandle] RETURNS[EntitySet] = TRUSTED BEGIN tsScan: DBStorage.IndexScanHandle; [lowName, highName]_ NCodeAndDefaultLimits[lowName, highName]; tsScan_ DBStorage.OpenScanIndex[indexToScan, [lowName, highName, TRUE, TRUE], First ]; RETURN[NEW[EntitySetObject[index] _ [index[tsScan]]]]; END; IF segment=NIL THEN es_ NEW[EntitySetObject[segment] _ [segment[ remainingSegments: DBModel.QGetSegments[], domain: d, lowName: lowName, highName: highName, start: First, currentEntitySet: NIL]]] ELSE SELECT d FROM DomainDomain => es_ MakeIndexScan[GetDomainIndex[segment]]; RelationDomain => es_ MakeIndexScan[GetRelationIndex[segment]]; ENDCASE => {SIGNAL Error[NotImplemented]; RETURN[NIL]}; END; SystemGetP: PUBLIC PROC [e: Entity, aIs: Attribute] RETURNS [v: Value] = TRUSTED <> <> <> <> BEGIN WITH e^ SELECT FROM e1: TupleObject[tupleSet] => -- e is one of the five system domains SELECT aIs FROM r1to1Prop => v_ NEW[BOOL_ e1.vR1to1]; ENDCASE => SIGNAL Error[NotImplemented]; e1: TupleObject[attribute] => -- e is one of the system attributes SELECT aIs FROM aHandleProp => v_ e1.vHandle; aTypeIs => v_ e1.vType; aRelationIs => v_ e1.vRelation; aLinkIs => v_ NEW[BOOL_ TRUE]; ENDCASE => SIGNAL Error[NotImplemented]; ENDCASE => SIGNAL Error[NotImplemented]; -- No other kinds implemented RETURN[v] END; SystemGetName: PUBLIC PROC [e: Entity] RETURNS [ROPE] = BEGIN WITH e^ SELECT FROM e1: TupleObject[tupleSet] => RETURN[e1.vName]; e1: TupleObject[attribute] => RETURN[e1.vName]; e1: TupleObject[entity] => RETURN[e1.vName]; ENDCASE => SIGNAL Error[NotImplemented]; RETURN[NIL] END; NCodeAndDefaultLimits: PROC [low, high: ROPE] RETURNS [newLow, newHigh: ROPE] = TRUSTED <> <> <<(2) if just the high limit is NIL, it defaults to the low limit, (3) any any case, we>> <> BEGIN IF high=NIL THEN IF low=NIL THEN {low_ minfString; high_ infString} ELSE {low_ NCode[low]; high_ low} ELSE {low_ NCode[low]; high_ NCode[high]}; RETURN[low, high] END; END. Last edited by: Cattell on 19-Dec-81 9:31:31: Changed iTupleSetProp and ifXXXProps to have underlying attributes. Bug had arisen when attempted to do GroupScan on iTupleSetProp, because there was no underlying attribute and therefore no unique fieldID to do the groupscan upon (a random memory location had been used). Decided to disallow entity-reffing fields without explicit underlying attributes so this won't happen (so DefineSystemProperty only works with simple-valued attributes). Cattell on 19-Dec-81 9:31:31: Changed aType* stuff around; may have to do more on this. Cattell on 29-Dec-81 16:09:49: Almost completely rewrote SystemDomainSubset: handle more special cases and do so correctly. Cattell on April 28, 1982 9:42 am: Added call to NCode in SystemDomainSubset and DesiredPropValue, so upper-case-only works. Cattell on August 2, 1982 11:16 pm: SubType relation attributes should be DomainDomain type, not AnyDomainType. Cattell on November 4, 1982 11:24 am: Conversion to new property scheme. This involves complete rework of system relations and domains, and the procedures used to initialize them. SystemRelationSubset and SystemGetP also rewritten. Cattell on December 17, 1982 5:18 pm: Converstion to new segment scheme, new Error scheme. Changed by Willie-Sue on February 15, 1985 <>