<> <> <> <> <> <> <> <> <> DIRECTORY AlpineEnvironment USING [LockOption], BasicTime USING[GMT], Basics USING[LowHalf], DBCommon, DBDefs, Rope USING[ROPE]; DB: CEDAR DEFINITIONS IMPORTS Basics = BEGIN ROPE: TYPE = Rope.ROPE; <> <> <> <<>> TypeCode: TYPE = DBDefs.TypeCode; FieldSpec: TYPE = REF FieldSpecObject; FieldSpecObject: TYPE = RECORD[fields: SEQUENCE count: CARDINAL OF Field]; TypeSpec: TYPE = RECORD[ type: SELECT kind: * FROM direct => [code: TypeCode], indirect => [ code: PROC[] RETURNS [TypeCode] ] ENDCASE ] _ Any; <> Field: TYPE = RECORD[name: ROPE, type: TypeSpec, lengthHint: CARDINAL _ 0]; Integer: TypeSpec = [direct[code: DBDefs.intType]]; String: TypeSpec = [direct[code: DBDefs.ropeType]]; Boolean: TypeSpec = [direct[code: DBDefs.boolType]]; Time: TypeSpec = [direct[code: DBDefs.timeType]]; Any: TypeSpec = [direct[code: DBDefs.anyDomainType]]; FieldSequence: TYPE = DBDefs.FieldSequence; ValueSequence: TYPE = DBDefs.ValueSequence; Value: TYPE = DBDefs.Value; Index: TYPE = DBDefs.Index; Segment: TYPE = DBCommon.Segment; SegmentList: TYPE = DBCommon.SegmentList; SegmentIndex: TYPE = DBCommon.SegmentIndex; FirstLast: TYPE = DBCommon.FirstLast; TransactionHandle: TYPE = DBCommon.TransactionHandle; Transaction: TYPE = DBCommon.Transaction; Domain: TYPE = DBDefs.Domain; DomainSet: TYPE = DBDefs.DomainSet; Relation: TYPE = DBDefs.Relation; RelationSet: TYPE = DBDefs.RelationSet; Entity: TYPE = DBDefs.Entity; EntitySet: TYPE = DBDefs.EntitySet; Relship: TYPE = DBDefs.Relship; Constraint: TYPE = DBDefs.Constraint; ValueConstraint: TYPE = DBDefs.ValueConstraint; RelshipSet: TYPE = DBDefs.RelshipSet; <> Error: ERROR [code: ErrorCode]; <> ErrorCode: TYPE = { AlreadyExists, -- DeclareEntity, DeclareRelship: already exists, but version=NewOnly BadUserPassword, -- Could not authenticate user CannotDefaultSegment, -- Segment name not built-in to Cypress, and no segment # given DatabaseNotInitialized, -- Attempt to perform operation without calling DB.Initialize EntityOrRelshipSetsOpen, -- Excessive Domain/RelationSubsets still open (CloseTransaction). DirectoryNotFound, -- Directory specified in segment name not found on file server FileNotFound, -- No existing segment found with given file name, and version=OldOnly InvalidSchema, -- The domain, relation, or attribute object being used is out of date IllegalAttribute, -- Attribute not of the given relship's Relation or not attribute IllegalConstraint, -- Constraint specification had value of incorrect type or had wrong length IllegalDomain, -- Argument is not actually a domain IllegalFileName, -- No directory or machine given for segment, or invalid chars in name IllegalEntity, -- Argument to GetP, or etc., is not an Entity IllegalIndex, IllegalKeySpecification, -- A field appears in two or more keys for a relation IllegalProperty, -- An attempt was made to declare a property relation with a non-entity valued first field IllegalRelation, -- Argument is not a relation IllegalString, -- Nulls not allowed in ROPEs passed to the database system IllegalSuperType, -- Can't define subtype of domain that already has entities MismatchedAttributeValueType, -- Value not same type as required (SetF) MismatchedExistingRelation, -- Existing relation is different (DeclareRelation) MismatchedExistingSegment, -- Existing segment has different # or name MismatchedValueType, MultipleMatch, -- More than one relationship satisfied avl on DeclareRelship. NonUniqueEntityName, -- Entity in domain with that name already exists NonUniqueKeyValue, -- Relship already exists with same value for a key attribute NotFound, -- Version is OldOnly but no such Entity, Relation, or etc found NotImplemented, -- Action requested is not currently implemented NILArgument, -- Attempt to perform operation on NIL argument NullifiedArgument, -- Entity or relationship has been deleted, or invalidated by trans abort ProtectionViolation, -- Read or write to segment file not permitted this user. QuotaExceeded, -- Database too big for Alpine page quota of segment's directory SegmentNotDeclared, -- Attempt to open transaction on segment with no DeclareSegment ServerNotFound, -- File server does not exist or does not respond TransactionNotOpen, -- Attempt to perform operation with no transaction open TransactionAlreadyOpen, -- Attempt to open transaction on segment already associated w/one WriteNotAllowed, -- Attempt to write data but DeclareSegment specified read-only WrongNumberOfFields, -- attempt to create relship with ill-formed list of initial values Unknown -- Unknown or not yet assigned error code }; Aborted: ERROR; <> Failure: ERROR [what: ATOM, info: ROPE]; <> <> Initialize: PROC[nCachePages: NAT _ 512, cacheFileName: ROPE _ NIL]; <> <> <> <> DeclareSegment: PROC[filePath: ROPE, segment: Segment, number: SegmentIndex _ 0, lock: AlpineEnvironment.LockOption _ [intendWrite, wait], readonly: BOOL _ FALSE, createIfNotFound: BOOL _ TRUE, nPagesInitial, nPagesPerExtent: INT _ 64]; <<>> <> <> <> <> <> <> <> EraseSegment: PROC[segment: Segment, useTrans: TransactionHandle _ NIL] RETURNS[trans: TransactionHandle]; <> GetSegmentInfo: PROC[Segment] RETURNS[filePath: ROPE, readOnly: BOOL]; <> OpenTransaction: PROC[segment: Segment, useTrans: TransactionHandle _ NIL] RETURNS[trans: TransactionHandle, schemaInvalid: BOOL]; <> <> <> <> <> <> SegmentsForTransaction: PROC[trans: TransactionHandle] RETURNS[SegmentList]; <> MarkTransaction: PROC[trans: TransactionHandle]; <> AbortTransaction: PROC[trans: TransactionHandle]; <> CloseTransaction: PROC[trans: TransactionHandle]; <> <<>> <<-- The next procedure allows the database transaction to be controlled from the outside.>> MakeTransHandle: PROC[trans: DBCommon.Transaction] RETURNS[handle: TransactionHandle]; <> <> <> DeclareDomain: PROC[name: ROPE, segment: Segment] RETURNS[d: Domain]; <> LookupDomain: PROC[name: ROPE, segment: Segment] RETURNS[d: Domain]; <> DestroyDomain: PROC[d: Domain]; <> DomainInfo: PROC[d: Domain] RETURNS[name: ROPE, segment: Segment]; <> NullDomain: PROC[d: Domain] RETURNS[BOOL]; <> DomainEq: PROC[d1, d2: Domain] RETURNS[BOOL]; <> DomainsByName: PROC[segment: Segment, lowName, highName: ROPE, start: FirstLast _ First] RETURNS[ds: DomainSet]; <= lowName and <= highName. The start parameter allows the enumeration to start at the beginning or end: If start = last, the enumeration will start with the domain with the lexicographically largest name, i.e. NextDomain will return NIL and successive calls to PrevDomain will return the domains. The converse is true if start=first.>> NextDomain: PROC[ds: DomainSet] RETURNS[d: Domain]; <> PrevDomain: PROC[ds: DomainSet] RETURNS[d: Domain]; <> ReleaseDomainSet: PROC[ds: DomainSet]; <> DeclareSubType: PROC[of, is: Domain]; < entities of subtype can participate in any attribute accepting entities of the supertype. Currently, may not do this if "of" domain has any relations defined on it or any tuples in it.>> <> DestroySubType: PROC[of, is: Domain]; <> SuperType: PROC[d: Domain] RETURNS[super: Domain]; <> SubTypes: PROC[d: Domain] RETURNS[subs: DomainSet]; <> TypeForDomain: PROC[d: Domain] RETURNS[type: TypeCode]; <> RelationsOf: PROC[d: Domain] RETURNS[rs: RelationSet]; <> <> DeclareRelation: PROC[name: ROPE, segment: Segment, fields: FieldSpec] RETURNS[r: Relation]; <> DeclareProperty: PROC[name: ROPE, segment: Segment, fields: FieldSpec] RETURNS[r: Relation]; <> LookupRelation: PROC[name: ROPE, segment: Segment] RETURNS[r: Relation]; <> FieldCount: PROC[r: Relation] RETURNS[count: CARDINAL]; <> Fields: PROC[r: Relation] RETURNS[fields: FieldSpec]; <> <<>> NameToField: PROC[r: Relation, name: ROPE] RETURNS[exists: BOOL, pos: CARDINAL]; <> FieldDescription: PROC[r: Relation, pos: CARDINAL] RETURNS[field: Field]; <> RelationInfo: PROC[r: Relation] RETURNS[name: ROPE, segment: Segment]; <> DestroyRelation: PROC [r: Relation]; <> NullRelation: PROC[r: Relation] RETURNS[BOOL]; <> <<>> RelationEq: PROC[r1, r2: Relation] RETURNS[BOOL]; <> RelationsByName: PROC[segment: Segment, lowName, highName: ROPE, start: FirstLast _ First] RETURNS[rs: RelationSet]; <= lowName and <= highName. The start parameter allows the enumeration to start at the beginning or end: If start = last, the enumeration will start with the relation with the lexicographically largest name, i.e. NextRelation will return NIL and successive calls to PrevRelation will return the relations. The converse is true if start = first.>> NextRelation: PROC[rs: RelationSet] RETURNS[Relation]; <> PrevRelation: PROC[rs: RelationSet] RETURNS[Relation]; <> ReleaseRelationSet: PROC[rs: RelationSet]; <> <> DeclareKeyIndex: PROC[r: Relation, fields: FieldSequence] RETURNS[index: Index]; <> DeclareIndex: PROC[r: Relation, fields: FieldSequence] RETURNS[index: Index]; <> KeyIndices: PROC[r: Relation] RETURNS[keyIndices: LIST OF Index]; <> OtherIndices: PROC[r: Relation] RETURNS[indices: LIST OF Index]; <> DestroyIndex: PROC[r: Relation, index: Index]; <> <> DeclareEntity: PROC[d: Domain, name: ROPE, newOnly: BOOL _ FALSE] RETURNS[e: Entity]; <> <> <> <> LookupEntity: PROC[d: Domain, name: ROPE] RETURNS[e: Entity]; <> <> <> DestroyEntity: PROC[e: Entity]; <> CopyEntity: PROC[e: Entity] RETURNS[Entity]; <> EntityInfo: PROC[e: Entity] RETURNS[name: ROPE, domain: Domain]; <> ChangeName: PROC[ of: Entity, to: Rope.ROPE ]; <> ToUnderType: PROC[e: Entity]; <> EntityEq: PROC[e1: Entity, e2: Entity] RETURNS[BOOL]; <> NullEntity: PROC[e: Entity] RETURNS[BOOL]; <> <<>> CreateRelship: PROC[r: Relation, init: ValueSequence] RETURNS[relship: Relship]; <> LookupRelship: PROC[r: Relation, keyIndex: Index, key: ValueSequence] RETURNS[relship: Relship]; <> LookupWithSimpleKey: PROC[r: Relation, keyIndex: Index, key: Value] RETURNS[relship: Relship]; <> LookupProperty: PROC[r: Relation, e: Entity] RETURNS[relship: Relship]; <> FirstRelship: PROC[r: Relation] RETURNS[relship: Relship]; <> DestroyRelship: PROC[t: Relship]; <> CopyRelship: PROC[t: Relship] RETURNS[Relship]; <> GetF: PROC[t: Relship, field: CARDINAL] RETURNS[Value]; <> SetF: PROC[t: Relship, field: CARDINAL, v: Value]; <> GetP: PROC[e: Entity, r: Relation, field: CARDINAL] RETURNS[Value]; <> SetP: PROC[e: Entity, r: Relation, field: CARDINAL, v: Value]; <> RelationOf: PROC[t: Relship] RETURNS[Relation]; <> RelshipEq: PROC[r1: Relship, r2: Relship] RETURNS[BOOL]; <> NullRelship: PROC[r: Relship] RETURNS[BOOL]; <> <> RelationSubset: PROC[r: Relation, index: Index, constraint: Constraint, start: FirstLast _ First] RETURNS[RelshipSet]; <> RelshipsForEntity: PROC[e: Entity] RETURNS[rs: RelshipSet]; <> RelshipsWithEntityField: PROC[r: Relation, field: CARDINAL, val: Entity] RETURNS[rs: RelshipSet]; <> NextRelship: PROC[rs: RelshipSet] RETURNS[Relship]; <> PrevRelship: PROC[rs: RelshipSet] RETURNS[Relship]; <> ReleaseRelshipSet: PROC[rs: RelshipSet]; <> DomainSubset: PROC[d: Domain, lowName, highName: ROPE _ NIL, start: FirstLast _ First] RETURNS[EntitySet]; <= lowName and <= highName. As with RelationSubset, the start parameter allows the enumeration to start at the beginning or end: If start = last, the enumeration will start with the entity with the lexicographically largest name, i.e. NextEntity will return NIL and successive calls to PrevEntity will return the entities. The converse is true if start=first. If only highName is NIL, it defaults to lowName, i.e. we will search for the entity whose name exactly equals lowName.>> NextEntity: PROC[es: EntitySet] RETURNS[Entity]; <> PrevEntity: PROC[es: EntitySet] RETURNS[Entity]; <> ReleaseEntitySet: PROC[es: EntitySet]; <> <> <> L2VS: PROC[vals: LIST OF Value] RETURNS[seq: ValueSequence]; L2FS: PROC[vals: LIST OF Field] RETURNS[seq: FieldSpec]; L2F: PROC[vals: LIST OF CARDINAL] RETURNS[seq: FieldSequence]; L2C: PROC[vals: LIST OF ValueConstraint] RETURNS[seq: Constraint]; <> I2V: PROC[i: INT] RETURNS[Value] = INLINE BEGIN RETURN[[integer[i]]] END; B2V: PROC[b: BOOL] RETURNS[Value] = INLINE BEGIN RETURN[[boolean[b]]] END; U2V: PROC[u: UNSPECIFIED] RETURNS[Value] = <> INLINE BEGIN RETURN[[integer[LOOPHOLE[u, CARDINAL]]]] END; S2V: PROC[s: ROPE] RETURNS[Value] = INLINE BEGIN RETURN[[rope[s]]] END; E2V: PROC[e: Entity] RETURNS[Value] = INLINE BEGIN RETURN[[entity[e]]] END; T2V: PROC[t: BasicTime.GMT] RETURNS[Value] = INLINE BEGIN RETURN[[time[t]]] END; <> V2B: PROC[v: Value] RETURNS[value: BOOL] = TRUSTED INLINE { WITH v: v SELECT FROM boolean => value _ v.value; ENDCASE => ERROR Error[MismatchedValueType] }; V2I: PROC[v: Value] RETURNS[value: INT] = TRUSTED INLINE { WITH v: v SELECT FROM integer => value _ v.value; ENDCASE => ERROR Error[MismatchedValueType] }; V2S: PROC[v: Value] RETURNS[value: ROPE] = TRUSTED INLINE { WITH v: v SELECT FROM rope => value _ v.value; ENDCASE => ERROR Error[MismatchedValueType] }; V2U: PROC[v: Value] RETURNS[value: UNSPECIFIED] = TRUSTED INLINE { WITH v: v SELECT FROM integer => value _ Basics.LowHalf[LOOPHOLE[v.value]]; ENDCASE => ERROR Error[MismatchedValueType] }; V2T: PROC[v: Value] RETURNS[value: BasicTime.GMT] = TRUSTED INLINE { WITH v: v SELECT FROM time => value _ v.value; ENDCASE => ERROR Error[MismatchedValueType] }; V2E: PROC[v: Value] RETURNS[value: Entity] = TRUSTED INLINE { RETURN[WITH v: v SELECT FROM entity => v.value, null => NIL, ENDCASE => ERROR Error[MismatchedValueType] ] }; END.