4ODS User"s Guide



1. Introduction
2. ODL datatypes
3. Unimplemented portions of the ODMG specification
4. 4ODS tools
4.1. How to change the storage adapter
5. How to use the system (a very basic walk through)

4ODS User's Guide 4ODS Userguide ODMG User's Guide for 4ODS.

Introduction

4ODS is am implementation of the ODMG Object Data Standard v 3.0 in python. 4ODS currently implements a beta version of its own file storage, however it is not transactional, nor is it concurrent. 4ODS does support backends that are transactional and concurrent through SQL database for. 4ODS generates persistent stub classes from an ODL file. These classes are used as any other python class is used, except when commit is called on the current transaction, changes are persisted into the database. Objects can be fetched from the database using the ODS binding mechanisim, the ODS extent mechanisim, or simple OQL queries. 4ODS supports OIF for both input and output, for all meta data types supported by the backends.

ODL datatypes

The following list is of supported datatypes defined by the ODMG

The following list is of unsupported datatypes defined by the ODMG

The following list is of extended datatypes not defined by the ODMG but included in 4ODS

Unimplemented portions of the ODMG specification

Besides the above mentioned datatypes that are not supported, the following is a list of unsupported features defined by the ODMG specification.

4ODS tools

Please see the 4ODB command line documentation for command line help.

How to change the storage adapter

4ODS, except for the beta Dbm Adapter, relies on a SQL backend for the actual storage of objects. By default, 4ODS uses the Postgres adapter. In order to use the Postgres adapter, PyGreSQL must be installed on the machine, and the user of 4ODS must have access to a PostgreSQL database. Other adapters include an Oracle Adapter (DCORacle and access to an Oracle Database required) and the Dbm adapter (no additional modules needed. One note on the Dmb adapter, it is in beta stage with no support for proper transaction or concurrency. If used in a muti-threaded or multi-process application, the application must take care of concurrency and transaction sysmantics.

How to use the system (a very basic walk through)

First create a ODL file that represents what you want to store in test.odl

module simple {
  class person {
    attribute string name;
    attribute double weight;
    relationship Person spouse inverse Person ::spouse_of;
    relationship Person spouse_of inverse Person ::spouse;
    relationship list<Person> children  inverse Person ::child_of;
    relationship Person child_of inverse Person ::children;
  };
  class employee (extends person) {
    attribute string id;
  };
};

Now create a new database and initialize

 #OdlParse -ifp test test.odl

Now write some python code to do stuff with these people

#!/usr/bin/python

#Every thing that is persisten must be done inside a transaction and open database
from Ft.Ods import Database
db = Database.Database()
db.open('test')

tx = db.new()
tx.begin()

#Create a new instance of some objects
import person
import employee
dad = employee.new(db)
mom = person.new(db)
son1 = person.new(db)
son2 = person.new(db)
daughter = person.new(db)

#Set some attributes
dad.name = "Pops"
mom.name = "Ma"
son1.name = "Joey"
son2.name = "Bobby"
daughter.name = "Betty"
dad.weight = 240.50

#We can set attributes not defined in the ODL but they will not persist
mom.address = "1234 Error Way"


#Set some relationships

#First set a one to one relationship
dad.spouse = mom

#Or we could have done it via the ODMG spec
#dad.form_spouse(mom)

#Add some children to the dad (our data model does not let mom have children.  We'd need a family struct (left up to the reader)

dad.add_children(son1)
#We can create relationships both ways
son2.form_child_of(dad)

#Shortcut for adding
dad.children = daughter

#Now root the family to some top level object.
db.bind(dad,"The Fam")

#Make it so
tx.commit()

#Out side of a transaction we can still access the objects.
#However, any changes we make will not persist.
#NOTE, because 4ODS caches relationships, any relationships that were not traversed during the
#transaction, cannot be traversed now because an object cannot be loaded from the db outside
#of a transaction.
print dad.name

#Start a new tx to fetch

tx = db.new()
tx.begin()

newDad = db.lookup("The Fam")

print newDad.name
print newDad.children[0].name
print newDad.spouse

#Discard this transaction
tx.abort()

Ft/Ods/test_suite and Ft/Ods/demo are good places to look for more examples