/* 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; }; ? \quitAs 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