/* person.odl */
class Person {
string name;
int age;
Person *spouse inverse Person::spouse;
Person *father;
set<Person *> children inverse Person::father;
set<Car *> cars inverse Car::owner;
index on name;
index on age;
constraint<notnull> on name;
constraint<unique> on name;
};
class Car {
string brand;
int num;
Person *owner inverse Person::cars;
index on brand;
index on num;
};
This schema describes two classes Person and Car, one 1 to 1
relationship (attribute spouse in class Person) and two 1 to many
relationships (from Person::father to Person::children
and from Car::owner to Person::cars).
eyedbodl --gencode=JAVA --package=person person.odlor :
eyedbodl --gencode=JAVA --package=person -d personThe eyedbodl tool contains a lot of command line options to control the generated code.
odlfile|-|-d dbname|-database=dbname : Input ODL file (or - for standard input) or the database nameand some optionnal options:
-package=package : Package name
-output-dir=dirname : Output directory for generated files
-output-file-prefix=prefix : Ouput file prefix (default is the package name)
-class-prefix=prefix : Prefix to be put at the begining of each runtime class
-db-class-prefix=prefix : Prefix to be put at the begining of each database class
-attr-style=implicit : Attribute methods have the attribute name
-attr-style=explicit : Attribute methods have the attribute name prefixed by get/set (default)
-schema-name=schname : Schema name (default is package)
-export : Export class instances in the .h file
-dynamic-attr : Uses a dynamic fetch for attributes in the get and set methods
-down-casting=yes : Generates the down casting methods (the default)
-down-casting=no : Does not generate the down casting methods
-attr-cache=yes : Use a second level cache for attribute value
-attr-cache=no : Does not use a second level cache for attribute value (the default)
-namespace=namespace : Define classes with the namespace namespace
-c-suffix=suffix : Use suffix as the C file suffix
-h-suffix=suffix : Use suffix as the H file suffix
-gen-class-stubs : Generates a file class_stubs.h for each class
-class-enums=yes : Generates enums within a class
-class-enums=no : Do not generate enums within a class (default)
-gencode-error-policy=status : Status oriented error policy (the default)
-gencode-error-policy=exception : Exception oriented error policy
-rootclass=rootclass : Use rootclass name for the root class instead of the package name
-no-rootclass : Does not use any root class
//
// class Person
//
// package person
//
// Automatically Generated by eyedbodl at ...
//
package person;
public class Person extends org.eyedb.Struct {
public Person(org.eyedb.Database db);
public Person(org.eyedb.Struct x, boolean share);
public Person(Person x, boolean share);
public void setName(String _name);
public void setName(int a0, char _name) throws org.eyedb.Exception;
public String getName();
public void setAge(int _age) throws org.eyedb.Exception;
public int getAge() throws org.eyedb.Exception;
public void setSpouse(Person _spouse) throws org.eyedb.Exception;
public Person getSpouse() throws org.eyedb.Exception;
public void setSpouse_oid(org.eyedb.Oid _oid) throws org.eyedb.Exception;
public org.eyedb.Oid getSpouse_oid() throws org.eyedb.Exception;
public org.eyedb.CollSet getChildrenColl() throws org.eyedb.Exception;
public int getChildrenCount() throws org.eyedb.Exception;
public Person getChildrenAt(int ind) throws org.eyedb.Exception;
public void setChildrenColl(org.eyedb.CollSet _children) throws org.eyedb.Exception;
public void addToChildrenColl(Person _children) throws org.eyedb.Exception;
public void addToChildrenColl(org.eyedb.Oid _oid) throws org.eyedb.Exception;
public void rmvFromChildrenColl(Person _children) throws org.eyedb.Exception;nn
public void rmvFromChildrenColl(org.eyedb.Oid _oid) throws org.eyedb.Exception;nn
// and so on. father and cars set and get methods.
// ...
// protected and private parts
// ...
};
eyedbodl has generated three constructors (including two copy constructors),
and get and set methods for each attributes.
export CLASSPATH=<libdir>/eyedb/java/eyedb.jar javac -depend -d. person/Database.java
//
// class TestP.java
//
import person.*;
class TestP {
public static void main(String args[]) {
// Initialize the eyedb package and parse the default eyedb options
// on the command line
String[] outargs = org.eyedb.Root.init("TestP", args);
// Check that a database name is given on the command line
int argc = outargs.length;
if (argc != 1) {
System.err.println("usage: java TestP dbname");
System.exit(1);
}
try {
// Initialize the person package
person.Database.init();
// Open the connection with the backend
org.eyedb.Connection conn = new org.eyedb.Connection();
// Open the database named outargs[0]
person.Database db = new person.Database(outargs[0]);
db.open(conn, org.eyedb.Database.DBRW);
db.transactionBegin();
// Create two persons john and mary
Person john = new Person(db);
john.setName("john");
john.setAge(32);
Person mary = new Person(db);
mary.setName("mary");
mary.setAge(30);
// Mary them :-)
john.setSpouse(mary);
// Store john and mary in the database
john.store(org.eyedb.RecMode.FullRecurs);
db.transactionCommit();
}
catch(org.eyedb.Exception e) { // Catch any eyedb exception
e.print();
System.exit(1);
}
}
}
The client contains the followin line at the beginning of all
its modules:
import person.*;This line means that you are imported the generated person package.
String[] outargs = org.eyedb.Root.init("TestP", args);
This method will take out from args all the EYEDB options
such as -host=<host>, -port=<port>
(refer to the environment chapter).
person.Database.init()
Once again, if you do not call this method, the EYEDB java binding will
not work properly.
org.eyedb.Connection conn = new org.eyedb.Connection();
The constructor org.eyedb.Connection() will try to connect to the backend
using the host and port given on the command line.
person.Database db = new person.Database(outargs[0]);
db.open(conn, org.eyedb.Database.DBRW);
The org.eyedb.Database.DBRW flag indicates that we wants to open
the database in the read/write mode.
db.transactionBegin();
This method call is necessary for any database access in read or write
mode.
Person john = new Person(db);
john.setName("john");
john.setAge(32);
Person mary = new Person(db);
mary.setName("mary");
mary.setAge(30);
john.setSpouse(mary);
Note that at this step, the persons john and mary have
not been stored in the database.
john.store(org.eyedb.RecMode.FullRecurs);
The org.eyedb.RecMode.FullRecurs argument means that all the object
references included in the john object will be stored too ; so
the mary reference which is the john spouse, will be stored too.
db.transactionCommit();
Note that all the constructors and methods previously called, may
throw an org.eyedb.Exception in case of failure.
catch(org.eyedb.Exception e) {
e.print();
System.exit(1);
}
javac -d . TestP.java
eyedbdbcreate foo user authentication : <user name> password authentication : <user passwd>To update the schema person.odl in the database foo:
eyedbodl --u -d foo person.odl Updating <unnamed> Schema in database foo... Done
eyedbjrun fooAfter the program has run, let's verify that the objects have really been created in the foo database, using the eyedboql tool:
eyedboql
Welcome to eyedboql. Type `!help' to display the command list.
? \open foo
? select Person;
47886.20.803967:oid, 47887.20.2361599:oid
? \print full
47886.20.803967:oid Person = {
name = "john";
age = 32;
*spouse 47887.20.2361599:oid Person = {
name = "mary";
age = 30;
*spouse 47886.20.803967:oid Person = {
<trace cycle>
};
*father NULL;
*children NULL;
*cars NULL;
};
*father NULL;
*children NULL;
*cars NULL;
};
47887.20.2361599:oid Person = {
name = "mary";
age = 30;
*spouse 47886.20.803967:oid Person = {
name = "john";
age = 32;
*spouse 47887.20.2361599:oid Person = {
<trace cycle>
};
*father NULL;
*children NULL;
*cars NULL;
};
*father NULL;
*children NULL;
*cars NULL;
};
? \quit
As there is a unique constraint on the Person name attribute,
if you run the program again, you will catch the following exception:
TestP.run foo org.eyedb.StoreException: unique[] constraint error : attribute `name' in the agregat class `Person'
//
// class TestPC.java
//
import person.*;
class TestPC {
public static void main(String args[]) {
// Initialize the eyedb package and parse the default eyedb options
// on the command line
String[] outargs = org.eyedb.Root.init("TestPC", args);
// Check that a database name is given on the command line
int argc = outargs.length;
if (argc != 2) {
System.err.println("usage: java TestPC dbname person-name");
System.exit(1);
}
try {
// Initialize the person package
person.Database.init();
// Open the connection with the backend
org.eyedb.Connection conn = new org.eyedb.Connection();
// Open the database named outargs[0]
person.Database db = new person.Database(outargs[0]);
db.open(conn, org.eyedb.Database.DBRW);
db.transactionBegin();
// Looks for the Person john
String pname = outargs[1];
org.eyedb.OQL q = new org.eyedb.OQL(db, "select Person.name = \"" + pname + "\"");
org.eyedb.ObjectArray obj_array = new org.eyedb.ObjectArray();
q.execute(obj_array);
if (obj_array.getCount() == 0) {
System.err.println("TestPC: cannot find person `" + pname + "'");
System.exit(1);
}
Person john = (Person)obj_array.getObjects()[0];
// Looks for Person whose age is less than 3
// and add them to the john children collection
q = new org.eyedb.OQL(db, "select Person.age < 3");
obj_array = new org.eyedb.ObjectArray();
q.execute(obj_array);
for (int i = 0; i < obj_array.getCount(); i++) {
Person child = (Person)obj_array.getObjects()[i];
child.setAge(child.getAge() + 1);
john.addToChildrenColl(child);
}
// Update john and its children in the database
john.store(org.eyedb.RecMode.FullRecurs);
db.transactionCommit();
}
catch(org.eyedb.Exception e) { // Catch any eyedb exception
e.print();
System.exit(1);
}
}
}
The following steps (and code) are identical to the previous example:
String pname = outargs[1];
org.eyedb.OQL q = new org.eyedb.OQL(db, "select Person.name = \"" + pname + "\"");
This constructor makes a EYEDB OQL query in the opened database.
public void scan(org.eyedb.ValueArray value_array)
throws org.eyedb.TransactionException;
public void scan(org.eyedb.OidArray oid_array)
throws org.eyedb.TransactionException;
public void scan(org.eyedb.ObjectArray obj_array)
throws org.eyedb.TransactionException, org.eyedb.LoadObjectException;
public void scan(org.eyedb.ObjectArray obj_array, org.eyedb.RecMode rcm)
throws org.eyedb.TransactionException, org.eyedb.LoadObjectException;
public void scan(org.eyedb.ValueArray value_array, int count, int start)
throws org.eyedb.TransactionException;
public void scan(org.eyedb.OidArray oid_array, int count, int start)
throws org.eyedb.TransactionException;
public void scan(org.eyedb.ObjectArray obj_array, int count, int start)
throws org.eyedb.TransactionException, org.eyedb.LoadObjectException;
public void scan(org.eyedb.ObjectArray obj_array, int count, int start,
org.eyedb.RecMode rcm)
throws org.eyedb.TransactionException, org.eyedb.LoadObjectException;
The scan methods which deals with a org.eyedb.ValueArray are
the most general.
org.eyedb.OQL q = new org.eyedb.OQL(db, \"list(1, 2, 3, "hello world",
3.45, 'c', (select Person.age < 3));
the returned values will be:
org.eyedb.ValueArray valarr = new org.eyedb.ValueArray();
q.execute(valarr);
for (int i = 0; i < valarr.getCount(); i++) {
org.eyedb.Value value = valarr.getValues()[i];
if (value.type == org.eyedb.Value.INT)
// ...
else if (value.type == org.eyedb.Value.FLOAT)
// ...
else if (value.type == org.eyedb.Value.OID)
// ...
else if (value.type == org.eyedb.Value.CHAR)
// ...
}
In the TestPC.java example, as we know that only objects could
be returned, a more simple scan method may be used, as follows:
org.eyedb.OQL q = new org.eyedb.OQL(db, "select Person.name = \"" + pname + "\"");
org.eyedb.ObjectArray obj_array = new org.eyedb.ObjectArray();
q.execute(obj_array);
if (obj_array.getCount() == 0) {
System.err.println("TestPC: cannot find person `" + pname + "'");
System.exit(1);
}
In the case of no objects has been found, we display an error message and
then leaves the program.
Person john = (Person)obj_array.getObjects()[0];
This cast is a reasonnable cast for several reasons:
q = new org.eyedb.OQL(db, "select Person.age < 3");
obj_array = new org.eyedb.ObjectArray();
q.execute(obj_array);
for (int i = 0; i < obj_array.getCount(); i++) {
Person child = (Person)obj_array.getObjects()[i];
child.setAge(child.getAge() + 1);
john.addToChildrenColl(child);
}
john.store(org.eyedb.RecMode.FullRecurs);
db.transactionCommit();
EyeDB manual