-- File: DBShow.mesa
-- Contents: Procs to print out entities and tuples
-- Last edited by:
-- Rick Cattell on March 25, 1983 1:55 pm
-- Willie-Sue on January 20, 1983 4:57 pm


DIRECTORY IO, ConvertUnsafe, DB, DBModel, DBTuplesConcrete, DBEnvironment, Heap, Rope, AMTypes;

DBShow: PROGRAM
IMPORTS IO, ConvertUnsafe, DB, DBModel, Heap, Rope, AMTypes =

BEGIN OPEN DB, DBModel, IO;

fh: IO.Handle;
MaxBuffer: CARDINAL← 500;
buffer: LONG STRING←
Heap.systemZone.NEW[StringBody[MaxBuffer]← [maxlength: MaxBuffer, text: ]];

word: PROC [u: UNSPECIFIED] RETURNS [IO.Value] =
-- temporary kluge for output of UNSPECIFIED to IO
INLINE {RETURN[[integer[LOOPHOLE[u, INTEGER]]]]};

Show: PUBLIC PROC [huh: REF ANY --Entity or Relship--] RETURNS [LONG STRING] =
-- displays an entity, relship, domain, or relation
BEGIN ENABLE DB.InternalError => TRUSTED {GOTO GiveUp};
d: Domain; r: Relation; flag: BOOL; t: Entity;
t← V2E[huh ! AMTypes.Error => IF reason=typeFault THEN {t← NIL; CONTINUE}];
IF t=NIL THEN RETURN["* not a relship or entity *"];
flag← FALSE;
d← QDomainOf[t !
DB.Error => TRUSTED {IF code=IllegalEntity THEN {flag← TRUE; CONTINUE}}];
IF flag THEN
BEGIN
flag← FALSE; r← QRelationOf[t
! DB.Error => TRUSTED {IF code=NullifiedArgument THEN {flag← TRUE; CONTINUE}}];
IF flag THEN RETURN["* deleted *"];
RETURN[ShowRelship[t]];
END;
SELECT d FROM
DomainDomain => RETURN[ShowDomain[t]];
RelationDomain => RETURN[ShowRelation[t]];
AttributeDomain => RETURN[ShowAttribute[t]]
ENDCASE => RETURN[ShowEntity[t]];
EXITS
GiveUp => RETURN["**Internal error, cannot display**"]
END;

ShowEntity: PUBLIC PROC [e: Entity] RETURNS [LONG STRING] =
-- displays the domain and name of an entity
BEGIN
fh← IO.CreateOutputStreamToRope[];
WriteEntity[e];
FinishOutput[];
RETURN[buffer]
END;

ShowRelship: PUBLIC PROC [r: Relship] RETURNS [LONG STRING] =
-- displays a relship and its fields
BEGIN
fh← IO.CreateOutputStreamToRope[];
WriteRelship[r];
FinishOutput[];
RETURN[buffer]
END;

ShowDomain: PUBLIC PROC [d: Domain] RETURNS [LONG STRING] =
-- displays all elements of a domain
BEGIN es: EntitySet; e: Entity;
fh← IO.CreateOutputStreamToRope[];
WriteSystemEntity[d]; fh.Put[rope[" ... domain elements are:\n"]];
es← QDomainSubset[d];
UNTIL Null[e← QNextEntity[es]] DO
WriteEntity[e]; fh.PutF["\n"];
IF buffer.length>300 THEN {fh.PutF["...more\n"]; EXIT};
ENDLOOP;
QReleaseEntitySet[es];
fh.PutF[".................."];
FinishOutput[];
RETURN[buffer]
END;

ShowRelation: PUBLIC PROC [r: Relation] RETURNS [LONG STRING] =
-- displays all elements of a relation
BEGIN t: Relship; rs: RelshipSet; count: INT← 0;
fh← IO.CreateOutputStreamToRope[];
WriteSystemEntity[r]; fh.Put[rope[" ... relation elements are:\n"]];
rs← QRelationSubset[r];
UNTIL Null[t← QNextRelship[rs]] DO
WriteRelship[t]; fh.PutF["\n"];
IF buffer.length>300 THEN {fh.PutF["...more\n"]; EXIT};
ENDLOOP;
QReleaseRelshipSet[rs];
fh.PutF[".................."];
FinishOutput[];
RETURN[buffer]
END;

ShowAttribute: PROC [a: Attribute] RETURNS [LONG STRING] =
BEGIN
fh← IO.CreateOutputStreamToRope[];
WriteSystemEntity[a];
FinishOutput[];
RETURN[buffer]
END;

ShowAll: PUBLIC PROC [huh: REF ANY] RETURNS [LONG STRING] =
-- Displays an entity and its referencing relships
BEGIN
e: Entity;
t: Relship;
r: Relation;
rs: RelshipSet;
al: AttributeList;
e← V2E[huh ! AMTypes.Error =>
   TRUSTED {IF reason=typeFault THEN {e← NIL; CONTINUE}}];
IF e=NIL THEN RETURN["* not an entity *"];
al← QGetAllRefAttributes[e];
fh← IO.CreateOutputStreamToRope[];
WriteEntity[e];
fh.PutF[" ... tuples referencing:\n"];
FOR alT: AttributeList← al, alT.rest UNTIL alT=NIL DO
r← V2E[QGetP[alT.first, aRelationIs]];
rs← QRelationSubset[r, LIST[[alT.first, e]]];
UNTIL Null[t← QNextRelship[rs]] DO
IF buffer.length>300 THEN {fh.PutF["...more\n"]; EXIT};
WriteRelship[t]; fh.Put[char[CR]] ENDLOOP;
QReleaseRelshipSet[rs];
ENDLOOP;
fh.PutF["....................."];
FinishOutput[];
RETURN[buffer]
END;

FinishOutput: PROC =
BEGIN output: ROPE← IO.GetOutputStreamRope[fh];
IF output.Length[]>MaxBuffer THEN output← output.Substr[0, MaxBuffer-2];
buffer.length← 0;
ConvertUnsafe.AppendRope[buffer, output];
fh.Close[];
END;

-- The following procedures stolen from DBDump:

WriteEntity: PROC[e: Entity] =
-- Prints an entity in ascii dump form: /domain\name\
BEGIN
d: Domain← QDomainOf[e];
fh.Put[char['/], rope[QNameOf[d]], char['\\]];
fh.Put[rope[QNameOf[e]], char['\\]];
END;

WriteRelship: PROC[t: Relship] =
-- Prints a relship in ascii dump form: \relation\a1:v1\...\aN:vN\
BEGIN
ts: Relation← QRelationOf[t];
attributeList: EntitySet;
fh.Put[char['\\], rope[QNameOf[ts]]];
fh.Put[char['\\]];
FOR al: AttributeList← VL2EL[QGetPList[ts, aRelationOf]], al.rest UNTIL al=NIL DO
field: Attribute← al.first;
fh.Put[rope[QNameOf[field]], char[':]];
fh.Put[rope[QGetFS[t, field]], char['\\] ];
ENDLOOP;
QReleaseEntitySet[attributeList];
END;

WriteSystemEntity: PROC [e: Entity] =
-- Will print a domain, relation, or attribute and any
-- associated properties that are needed to recreate it.
BEGIN type: Domain← QDomainOf[e];
SELECT type FROM
DomainDomain =>
fh.Put[rope["/Domain\\"], rope[QNameOf[e]], char['\\]];
RelationDomain => fh.Put[
rope["/Relation\\"], rope[QNameOf[e]], char['\\] ];
AttributeDomain => {
fh.Put[rope["/Attribute\\"], rope[QNameOf[V2E[QGetP[e, aRelationIs]]]], char['\\]];
fh.Put[rope[QNameOf[e]], char['\\]];
fh.Put[rope[QNameOf[V2E[QGetP[e, aTypeIs]]]], char['\\]];
fh.Put[word[V2U[QGetP[e, aUniquenessIs]]], char['\\]];
fh.Put[int[V2I[QGetP[e, aLengthIs]]], char['\\]] };
ENDCASE;
fh.Put[char[CR]];
END;


END.

Changes since June 24, 1982 12:08 pm:

Rick on June 24, 1982 12:08 pm: Catch internal error in Show. Change name of ShowTuple to Show.

Rick on October 29, 1982 10:54 am: New view level: properties, etc.

Rick on December 17, 1982 7:28 pm: new segments, Errors.