Edit Rename Changes History Upload Download Back to Top

Glorp

This is the O-R persistance layer used in the OpenSkills MMS system.

All the text and example assumes that you are using Glorp with VisualWorks. The text was tested out against VW 7.3 on Debian sarge with PostgreSQL 7.4.

The example schema

The examples here relate to the OpenSkills membership management system (the MMS).

First, you need a schema design. The MMS schema is small, and can be explained in just a few words:

Firstly, there are Contacts. Contacts represent people who are getting in touch with OpenSkills via the SkillsBase to start the membership application process. Contacts have an email address and a may have an OpenPGP key. They key and email address are checked for validity, and once they are in order, a Member record is created. Contacts are implemented members who have not been granted membership yet (they have no membership date). Members have one or more email addresses, only one of which may be the current contact email address. Members have one of more OpenPGP keys, only one of which may be the current key. Every email address must be associated with one or more keys (and the email address must be an UID on each key). The current email address must be a UID on the registered key. Each member will have a current password, though this may be changed over time.

So, we have Contacts, Members, EmailAddresses, Keys and Passwords.

Starting a Glorp Session

Reading and writing objects through Glorp requires that you start a Glorp session.

Getting a Glorp session going for a system for the first time requires that several pieces of information be specfied. Glorp needs to know:

In Glorp terminology these are: Then, to start the Glorp session we need to create: All these are described below.

The Descriptor System

Glorp understands the schema, and how the schema maps to classes using Descriptors. All of the descriptors together for a given schema form a DescriptorSystem. The DescriptorSystem takes the form of a class which has methods coded to return descriptor information. There are three kinds of method:

There are also two methods which list the tables and classes respectively: For the MMS we create a class called OSkMMSDescriptorSystem. This is, remarkably enough, our DescriptorSystem.

Now, we write the descriptors for our schema, and in so doing demonstrate some of the things that can be expressed with desciptors. To see more examples, make sure the GlorpTest parcel is loaded and look for senders of newMapping:. All the implementors will be in DescriptorSystems. Just poke through the methods of the DescriptorSystems for ideas.

The Platform

Glorp supports a number of DBMSs. For each supported DBMS there is a subclass of DatabasePlatform. Each specific platform class carries information about the DBMS specifcs such as the data type names and query formatting rules.

The MMS uses PostgreSQL only, and so always uses the PostgreSQLPlatform which is created as follows:

platform := PostgreSQLPlatform new.

A descriptor system instance works with a platform to determine the DDL and SQL to generate. For example, the descriptor system may say that a field is of type serial, but what does that mean in practice? It depends on the DBMS. As an example, an MMS descriptor system instance is created as follows (the platform varaible is as assigned above):

descriptorSystem := OSkMMSDescriptorSystem forPlatform: platform.

The Login

An instance of class login represents the collection of parameters needed to log in to a DBMS.

Here is an example of how to create a Login (using the platform variable from above):

login := (Login new)
   database: platform;
   username: 'ausername';
   password: 'apassword';
   connectString: 'database.host.net_mms';
   yourself.

The Accessor

A Glorp DatabaseAccessor represents a connection to a DBMS. The Login only represents the parameters. A single Login instance can be used to create any number of DatabaseAccessor instances.

Here is an example of creating a DatabaseAccessor and having it to login to a database (login variable as assigned above).

accessor := DatabaseAccessor forLogin: login.
accessor login.

When a DatabaseAccessor is no longer needed it must be explicilyly logged out using >>logout. For example:

accessor logout.

The Session

Now, at last, we get to create a GlorpSession. Using a GlorpSession to read and write to/from the DBMS will be covered later. For now, we just want to create one.

Here is an example using the descriptorSystem and accessor variables as assigned above:

session := (GlorpSession new)
               system: descriptorSystem;
               accessor: accessor;
               yourself.

MMS Session

For a given system, many of the Glorp objects described above can be defaulted. For the MMS system, there is a OSkMMSDatabaseSession class whose instances represent a logged in Glorp session.

To create a new OSkMMSDatabaseSession which is equivalent to all the above, use:

session := OSkMMSDatabaseSession
               connectTo: 'database.host.net_mms'
               asUser: 'ausername'
               withPassword: 'apassword'.

All the other information can be defaulted because the MMS system will only use the PostgreSQL platform, and will only use the OSkMMSDescriptorSystem. The underlying Glorp objects can be obtained from an OSkMMSDatabaseSession as follows:

The OSkMMSDatabaseSession can be explicitly logged out with session logout, but each instance will log itself out if garbage collected (via object finalization).

All the subsequent examples will use a OSkMMSDatabaseSession.

DDL

Data Definition Language is the subset of SQL which allows the creation and removal of schema elements such as tables, views and indexes.

A valid descriptor system contains a complete description of the target schema. Glorp can use this information to generate and execute DDL to create all the schema elements.

This example shows how to create all the tables needed by the MMS system in a newly created database called "mmstest":

mmsSession := OSkMMSDatabaseSession 
    connectTo: 'mmstest'
    asUser: 'ausername'
    withPassword: 'apassword'.
errorBlock := [:ex | Transcript show: ex description; cr. ex return].
  mmsSession glorpDescriptorSystem  allTables do: [:aDatabaseTable | 
    mmsSession glorpAccessor dropTable: aDatabaseTable ifAbsent: errorBlock].
  mmsSession glorpDescriptorSystem allTables do: [:aDatabaseTable | 
    mmsSession glorpAccessor createTable: aDatabaseTable ifError: errorBlock].
mmsSession logout

The message allTables returns a collection of DatabaseTable instances. The createTable:ifError message generates and executes the DDL for a table. If there is a problem the errorBlock notes it in the Transcript and ignores it.

The effect of the above script is to remove every table defined by OSkMMSDatabaseSession and then create them again. The script does not fail if the tables are not there in the first place: errors are logged to the Transcript, but the script continues to run.

DML

Data Manipulation Language is the parts of SQL which insert, update, delete and read information in (or to, or from) the database. DML includes the most commonly use bits of the SQL syntax.

Insert

Creating new data in the database using Glorp is a matter of creating the object that represents the data, and then having Glorp generate and execute the SQL (and INSERT statement) that will write the data to the database.

Working With Model Objects

Glorp uses proxies to stand in for objects. If the proxy is sent a message, it will use it's own implementation of >>messageNotUnderstood to pass the message on to the real object after faulting it in from the database if necessary.

One of the side effects of using proxies is that identity checks do not always work because the proxy of an object is not the same object as the object itself, i.e. (<object x> == <proxy of object x>) == false.

This means that it is not safe to check for identity using == when dealing with object that are being managed by Glorp.


Edit Rename Changes History Upload Download Back to Top