[Oberon] Oberon XML database and webforum

Luc Bläser blaeser at lbc.ch
Tue Oct 12 19:08:51 CEST 2004


Dear Mr. Drake

The DXP-webpage facility should be documented by a short tutorial in
DynamicWebpagePlugin.Text.
The other facility, the object-oriented database is for enabling
persistence of Oberon objects, which fulfil several programmed
preconditions. This system is designed to be sufficiently powerful for
small database sizes and also features transactional atomic as well as
recoverability from unexpected system shutdowns.

Such a persistent object should be a sub-type of the type
'PrevalenceSystem.PersistentObject' and implements three
overridden procedures. The procedure 'Externalize' converts the actual
state of the object to XML and 'Internalize' does so vice-versa.
Furthermore, 'GetReferencedObjects' should return all other objects that
are directly referenced by the object and should be also
stored in the database (to enable garbage colection etc.)

Sketch of an example:

Person = OBJECT(PrevalenceSystem.PersistentObject)
  VAR name: ARRAY 40 OF CHAR;

  PROCEDURE Externalize(): XML.Content;
  BEGIN RETURN WebStd.CreateXMLText(name)
  END Externalize;

  PROCEDURE Internalize(xml: XML.Content);
  VAR s: Utilities.String;
  BEGIN s := GetXMLCharContent(XML.Container(xml))
  END Internalize;

  PROCEDURE GetReferrencedObjects*() : PersistentObjectList;
  BEGIN RETURN NIL
  END GetReferencedObjects;
END Person;

A module, that provides a new persistent object type also has to
specify a corresponding persistent type descriptor and a creator
function, to obtain a new instance of the corresponding type. The
predefined procedure 'GetPersistentObjectDescriptors' returns
a list of all offered persistent object type descriptors of a module.

MODULE MyPersonModule;
 (* implementation of the above object type Person *)
 VAR personTypeDesc: PrevalenceSystem.PersistentObjectDescriptor;

 PROCEDURE GetPersistentObjectDescriptors*(par:PTR): PTR;
 VAR descSet : PrevalenceSystem.PersistentObjectDescSet;
     descs: ARRAY 1 OF PrevalenceSystem.PersistentObjectDescriptor;
 BEGIN
    descs[0] := personTypeDesc; NEW(descSet, descs); RETURN descSet
 END GetPersistentObjectDescriptors;

 PROCEDURE CreateNewPerson(): PrevalenceSystem.PersistentObject;
 VAR obj: Person;
 BEGIN NEW(obj); RETURN obj
 END CreateNewPerson;

 BEGIN
  NEW(personTypeDesc, "MyPersonModule", "Person", CreateNewPerson)
END MyPersonModule.

In the AosCOnfig.XML, the following entry is furthermore required.

<Section name="PrevalenceSystem">
  <Section name="PersistentObjectModules">
    <Setting value="MyPersonModule"/>
  </Section>
</Section>

Persistent objects are eventually created by the folowing two procedures:

VAR p: Person;
BEGIN
 NEW(p);

 AddPersistentObjectToRootSet(p, personTypeDesc);

 (* or otherwise *)
 AddPersistentObject(p, personTypeDesc)
END;

The first procedures adds the object two the root set, i.e. it permanently
remains available, whereas for the second procedure, the object is deleted
in the database if it is not referenced by another alive persistent
object. For this simple example, the first procedure would be therefore
correct.

Once the object has been added, it gets a unique identity, reflected by
the internal instance variable 'oid', which remains valid for multiple
system runs.
The object can be henceforth requested over its 'oid'.

VAR x: PrevalenceSystem.PersistentObject; p: Person;
BEGIN
 x:= GetPersistentObject(oid); p := x(Person)

An object can be also searched via a filter function (This is especially
important,
if the oid is not yet known for an object).

PROCEDURE JohnFilter(obj: PersistentObject) : BOOLEAN;
BEGIN RETURN (obj IS Person) & (obj(Person).name = "John")
END JohnFilter;

VAR l: PersistentObjectList;
l := FindPersistentObjects(JohnFilter)

Changes to an object must be performed within a object-local transaction,
such as it is depicted below:

VAR p: Person
BEGIN
  p.BeginModification;
  COPY("John Smith", p.name);
  p.EndModification;

The objects registered as root elements are also removeable, whereas all
other
objects are automatically managed by a garbage collector in the database.

RemovePersistentRootObject(p)

I hope this gives a brief overview of the system. If there are further
question, please don't hesitate to post them to the forum.

Kind regards

Luc Bläser






More information about the Oberon mailing list