API Tutorial

Home > Object Persistency API > API Tutorial

The API Tutorial is made up of twelve demo lessons. The corresponding source code is part of the project Persistency Demo (org.oomega.demo.persistency).

Please note that these lessons are equal to the console output of the Persistency Demo project – so you can try to execute these examples by yourself.

==============================================================
==  LESSON 1 - create database, first inserts and queries   ==
==============================================================
>
We start with creating a new memory db and set the producer id to 100 (see lession 4) ...
> EOContainerSession eocSession = MemoryEOC.createEOC(100).getSession();
>
To show query results, we use a pretty printer on System.out ...
> PrettyPrinter pp = new PrettyPrinter(eocSession, System.out);
>
Then we define the list of fields, we want to see ...
> displayedDataClassFields = List(                          
>     DataClass.F.oid(),                                      
>     DataClass.F.name(),                                     
>     DataClass.F.parentAbstractSyntax().parentMetapackage(), 
>     DataClass.F.superClass()                                
> );                                                          
>
In the beginning only the meta model is available ...
> pp.printAsTable(eocSession.execute(Query(from(EntityClass.CID))),displayedDataClassFields);
P:oid   | P:name                               | (P:parentAbstractSyntax.P:parentMetapackage) | P:superClass                
----------------------------------------------------------------------------------------------------------------------------
1:409:0 | BendpointConnectionSyntaxInformation | org.oomega.syntax.diagrammatical             | GraphicalSyntaxInformation  
1:68:0  | NamedEntityObject                    | org.oomega.base                              | EntityObject                
1:205:0 | AttributeClass                       | org.oomega.meta                              | DataClass                   
1:411:0 | Folder                               | org.oomega.base                              | FolderItem                  
1:136:0 | TreeSyntaxDef                        | org.oomega.syntax.tree                       | ConcreteSyntaxDef           
1:415:0 | JavaMapping                          | org.oomega.meta                              | EntityObject                
1:349:0 | DCField                              | org.oomega.meta                              | DCElement                   
1:129:0 | Parameter                            | org.oomega.meta                              | EntityObject                
1:405:0 | GraphicalSyntaxInformation           | org.oomega.syntax.diagrammatical             | ConcreteSyntaxInformation   
1:284:0 | Metapackage                          | org.oomega.meta                              | EntityObject                
1:346:0 | ConcreteSyntaxInformation            | org.oomega.syntax                            | EntityObject                
1:220:0 | Metamodel                            | org.oomega.meta                              | FolderItem                  
1:320:0 | DCConstant                           | org.oomega.meta                              | DCElement                   
1:399:0 | DCMethod                             | org.oomega.meta                              | DCElement                   
1:80:0  | ModelFolder                          | org.oomega.meta                              | Folder                      
1:94:0  | Group                                | org.oomega.base                              | Subject                     
1:26:0  | NodeSyntaxInformation                | org.oomega.syntax.diagrammatical             | GraphicalSyntaxInformation  
1:328:0 | DCInferredField                      | org.oomega.meta                              | DCField                     
1:210:0 | EntityClass                          | org.oomega.meta                              | DataClass                   
1:30:0  | ConcreteSyntax                       | org.oomega.syntax                            | CommentableNamedEntityObject
1:270:0 | Subject                              | org.oomega.base                              | NamedEntityObject           
1:271:0 | EntityObject                         | org.oomega.base                              | {  }                        
1:35:0  | Tasklist                             | org.oomega.process                           | EntityObject                
1:445:0 | DCAttribute                          | org.oomega.meta                              | DCField                     
1:161:0 | DataClass                            | org.oomega.meta                              | EntityObject                
1:432:0 | EOCSessionStatus                     | org.oomega.persistence                       | EntityObject                
1:380:0 | User                                 | org.oomega.base                              | Subject                     
1:43:0  | CommentableNamedEntityObject         | org.oomega.base                              | NamedEntityObject           
1:104:0 | BlobPacket                           | org.oomega.base                              | EntityObject                
1:377:0 | ConcreteSyntaxDef                    | org.oomega.syntax                            | EntityObject                
1:376:0 | MetamodelFolder                      | org.oomega.meta                              | Folder                      
1:47:0  | EOCStatus                            | org.oomega.persistence                       | EntityObject                
1:49:0  | Task                                 | org.oomega.process                           | EntityObject                
1:184:0 | AbstractSyntax                       | org.oomega.meta                              | EntityObject                
1:426:0 | CommentableEntityObject              | org.oomega.base                              | EntityObject                
1:359:0 | ResizeableNodeSyntaxInformation      | org.oomega.syntax.diagrammatical             | NodeSyntaxInformation       
1:187:0 | FolderItem                           | org.oomega.base                              | CommentableNamedEntityObject
1:255:0 | DCAssociation                        | org.oomega.meta                              | DCField                     
1:429:0 | File                                 | org.oomega.base                              | FolderItem                  
1:57:0  | TextualSyntaxDef                     | org.oomega.syntax.textual                    | ConcreteSyntaxDef           
1:298:0 | DCElement                            | org.oomega.meta                              | EntityObject                
1:241:0 | DataType                             | org.oomega.meta                              | EntityObject                
>
In order to be able to work with our demo model we load this model ...
> new Gateway(eocSession).loadSDFResource("persistency-demo.metamodel.sdf");
> eocSession.commit();
>
Let's have a look, if it is in now ...
> pp.printAsTable(eocSession.execute(Query(from(DataClass.CID), where(eq(nav(P(DataClass.P.parentAbstractSyntax),P(AbstractSyntax.P.parentMetapackage),P(Metapackage.P.name)),V("org.oomega.demo.pedigree"))))),displayedDataClassFields);
P:oid | P:name | (P:parentAbstractSyntax.P:parentMetapackage) | P:superClass
----------------------------------------------------------------------------
>
Now, lets's create an new entity 'Person' and insert it to our database ...
> Person person = eocSession.insert( Person() );
>
Attribute objects, like 'Address' needn't be inserted to the database ...
> Address address = Address();
>
Alternatively, you can create an attribute object
and set all its initial fields immediately ...
> address = Address("Munich", 80809, "Germany");
>
To get an attribute object actually stored in the
database it must belong to an entity. An attribute
object cannot exist alone ...
> person.setBirthPlace(address);
>
To get the whole object graph stored in the database
you have to commit the transaction. The commit will fail,
because the person does not satisfy the model constraints!
> eocSession.commit();
org.oomega.core.ConstraintViolationException: 
Person 100:2:0 is violated in field "name": Multiplicity is out of boundary. 0 not in [1..1].
Person 100:2:0 is violated in field "sex": Multiplicity is out of boundary. 0 not in [1..1].
2 constraint violations occured.
>
We add the missing fields ...
> person.setName("Christian Merenda");
> person.setSex(Gender(Gender.MALE));
>
Now the commit will succeed ...
> eocSession.commit();
>
We define two additional lists of fields ...
> simplePersonFields = List(
>     Person.F.oid(),
>     P(Person.P.name),
>     Person.F.sex(),
>     Person.F.birthDay(),
>     Person.F.birthPlace()
> );
> extendedPersonFields = List(
>     Person.F.oid(),
>     P(Person.P.name),
>     Person.F.parents(),
>     P(Person.P.children),
>     Person.F.spouse(),
>     Person.F.pictures()
> ); 
>
Let's check by showing the extent of Person ...
> pp.printExtent(Person.class, simplePersonFields);
P:oid   | P:name            | P:sex | P:birthDay | P:birthPlace          
-------------------------------------------------------------------------
100:2:0 | Christian Merenda | male  | {  }       | Munich, 80809, Germany
>
>

==============================================================
==  LESSON 2 - jSDL and custom constraints                  ==
==============================================================
>
Let's find the first person again ...
> Person child1 = (Person) eocSession.execute(Query(from(Person.CID), where(eq(P(Person.F.name),V("Christian Merenda"))))).iterator().next(); 
>
To create a second person, we use jSDL in a nested way ...
> Person child1 = eocSession.insert( Person( 
>     "Stefano Merenda",  
>     Gender(Gender.MALE),  
>     new java.util.Date(), 
>     Address(              
>         "Rome",         
>         10685,            
>         "Italy"         
>     ),                    
>     null,null,null,null   
> ) );                      
> eocSession.commit();             
>
Let's insert two more persons ...
> Person mom = eocSession.insert( Person() ); 
> mom.setName("Roswitha Merenda");   
> mom.setSex(Gender(Gender.FEMALE));   
>
> Person dad = eocSession.insert( Person() ); 
> dad.setName("Lauro Merenda");      
> dad.setSex(Gender(Gender.MALE));     
>
> eocSession.commit(); 
>
Now we link parents and childs ... 
>
> mom.addToChildren(child1); 
> mom.addToChildren(child2); 
> dad.addToChildren(child1); 
> dad.addToChildren(child2); 
>
The commit will throw an Exception because of the violation
of custom constaints
> eocSession.commit();
org.oomega.core.ConstraintViolationException: 
Person ""Stefano Merenda"" is violated in field "parents": The parents must be married!
Person ""Christian Merenda"" is violated in field "parents": The parents must be married!
2 constraint violations occured.
>
Let's marry the parents ...
> mom.setSpouse(dad); 
>
Now the commit will work!
> eocSession.commit(); 
>
Let's check by showing the extent of Person ...
> pp.printExtent(Person.CID, extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda     | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda  | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
>
>

==============================================================
==  LESSON 3 - OOMEGA's Java-embedded Query Language        ==
==============================================================
>
Let's define a query...
> Query query =                                             
>     Query(                                                
>         from(Person.CID),                                 
>         where(                                            
>             and(                                          
>                 like(lower(P(Person.P.name)),"*o mer*"),
>                 not(empty(P(Person.P.spouse)))            
>             )                                             
>         )                                                 
>     );                                                    
>
There is also a string representation for queries ...
> System.out.println( query.toString(ConcreteSyntaxIdentifier.get("M2L")) ); 
select *
	from 2102
	where ((lower(P:name) like "*o mer*") & !((size(P:spouse) = 0)))
>
And now let's use the query ...
> pp.printAsTable(eocSession.execute(query),extendedPersonFields);
P:oid   | P:name        | P:parents | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:5:0 | Lauro Merenda | {  }      | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
>
You can define every query inline, of course!
We try to find all persons without children ...
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(empty(P(Person.P.children))))),extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children | P:spouse | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
>
Since a query itself is an attribute object it can be easily
stored in the container itself ...
> eocSession.insert(NamedQuery("our first Query",query)); 
> eocSession.commit(); 
>
... and we can find the query by querying for it again ...
> Query query2 = ((NamedQuery) eocSession.execute(Query(from(NamedQuery.CID), 
>         where(eq(P(NamedQuery.P.name),V("our first Query")))           
>         )).iterator().next()).getQuery();                            
>
We can also alter the query:
Let's remove the second operator of the main 'and'
> ((And)query2.getWhere()).removeFromOperand( not(empty(P(Person.P.spouse))) ); 
>
Let's have a look at the new query ...
> System.out.println( query2.toString(ConcreteSyntaxIdentifier.get("M2L")) ); 
select *
	from 2102
	where ((lower(P:name) like "*o mer*"))
>
Now we get two results, because the person can be married or not
> pp.printAsTable(eocSession.execute(query2),extendedPersonFields);
P:oid   | P:name          | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda   | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
>
Let's demonstrate some more features of the query language: You can select certain fields ...
> pp.printAsTable(eocSession.execute(Query(select(P(Person.P.name), Person.F.sex()), from(Person.CID)))); 
------------------------------
[Stefano Merenda]   | [male]  
[Christian Merenda] | [male]  
[Lauro Merenda]     | [male]  
[Roswitha Merenda]  | [female]
>
You can apply aggregation functions to results ...
> pp.printAsTable(eocSession.execute(Query(select(countAgg()), from(Person.CID)))); 
-----
[4.0]
>
There's not only COUNT, but also AVG, SUM, MIN and MAX available ...
> pp.printAsTable(eocSession.execute(Query(select(avgAgg(nav(P(Person.P.birthPlace),P(Address.P.zipCode)))), from(Person.CID)))); 
---------
[80810.0]
>
You can build groups and apply aggregation functions to individual groups ...
> pp.printAsTable(eocSession.execute(Query(select(P(Person.P.sex), countAgg()), from(Person.CID)))); 
----------------
[female] | [1.0]
[male]   | [3.0]
>
You may also apply conditions to groups ...
> pp.printAsTable(eocSession.execute(Query(select(P(Person.P.sex), countAgg()), from(Person.CID), having(eq(countAgg(), VSet(3)))))); 
--------------
[male] | [3.0]
>
You can use common comparision operators as like, eq, neq, gt,geq, lt, leq
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(eq(P(Person.P.name), V("Christian Merenda"))))), extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children | P:spouse | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
>
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(like(P(Person.P.name), "*hr*")))), extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children | P:spouse | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
>
There are also some set comparision operators: superset,  superseteq, subset, subseteq, element, empty, exists, instance
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(not(empty(P(Person.P.children)))))), extendedPersonFields);
P:oid   | P:name           | P:parents | P:children                                                                 | P:spouse                           | P:pictures
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:5:0 | Lauro Merenda    | {  }      | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda | {  }      | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
>
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(exists(P(Person.P.children))))), extendedPersonFields);
P:oid   | P:name           | P:parents | P:children                                                                 | P:spouse                           | P:pictures
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:5:0 | Lauro Merenda    | {  }      | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda | {  }      | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
>
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(instance(Person.CID)))), extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda     | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda  | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
>
These are the set expressions: intersection, union, size, avg, sum, min, max
> pp.printAsTable(eocSession.execute(Query(from(Person.CID),where(eq(P(Person.P.name),intersect(VSet("Christian Merenda"), VSet("Christian Merenda", "Lauro Merenda")))))),simplePersonFields);
P:oid   | P:name            | P:sex | P:birthDay | P:birthPlace          
-------------------------------------------------------------------------
100:2:0 | Christian Merenda | male  | {  }       | Munich, 80809, Germany
>
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(eq(castNumber(nav(P(Person.P.birthPlace),P(Address.P.zipCode))),max(castNumber(nav(P(Person.P.birthPlace),P(Address.P.zipCode)))))))),simplePersonFields);
P:oid   | P:name            | P:sex  | P:birthDay                   | P:birthPlace          
--------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | male   | Thu Oct 29 20:23:49 CET 2009 | Munich, 80809, Germany
100:2:0 | Christian Merenda | male   | {  }                         | Munich, 80809, Germany
100:5:0 | Lauro Merenda     | male   | {  }                         | Tuglie, 80811, Italy  
100:4:0 | Roswitha Merenda  | female | {  }                         | Graz, 80811, Austria  
>
There are two string expressions "length" and "lower" which can be used in comparison operators.
> pp.printAsTable(eocSession.execute(Query(from(Person.CID),where(gt(length(P(Person.P.name)),V(4))))), simplePersonFields); 
P:oid   | P:name            | P:sex  | P:birthDay                   | P:birthPlace          
--------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | male   | Thu Oct 29 20:23:49 CET 2009 | Munich, 80809, Germany
100:2:0 | Christian Merenda | male   | {  }                         | Munich, 80809, Germany
100:5:0 | Lauro Merenda     | male   | {  }                         | Tuglie, 80811, Italy  
100:4:0 | Roswitha Merenda  | female | {  }                         | Graz, 80811, Austria  
>
> pp.printAsTable(eocSession.execute(Query(from(Person.CID),where(eq(lower(P(Person.P.name)),V("christian merenda"))))),simplePersonFields);
P:oid   | P:name            | P:sex | P:birthDay | P:birthPlace          
-------------------------------------------------------------------------
100:2:0 | Christian Merenda | male  | {  }       | Munich, 80809, Germany
>
Navigation beyond collection-valued path expressions is allowed ...
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(eq(nav(P(Person.P.children),P(Person.P.name)), VSet("Christian Merenda","Stefano Merenda") )))),simplePersonFields); 
P:oid   | P:name           | P:sex  | P:birthDay | P:birthPlace        
-----------------------------------------------------------------------
100:5:0 | Lauro Merenda    | male   | {  }       | Tuglie, 80811, Italy
100:4:0 | Roswitha Merenda | female | {  }       | Graz, 80811, Austria
>
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(eq(nav(P(Person.P.children),P(Person.P.name)), VSet("Christian Merenda","Stefano Merenda") )))),simplePersonFields); 
P:oid   | P:name           | P:sex  | P:birthDay | P:birthPlace        
-----------------------------------------------------------------------
100:5:0 | Lauro Merenda    | male   | {  }       | Tuglie, 80811, Italy
100:4:0 | Roswitha Merenda | female | {  }       | Graz, 80811, Austria
>
Here are some particular expressions ...
> pp.printAsTable(eocSession.execute(Query(from(Person.CID),where(eq(self(),P(EntityObject.P.oid))))),simplePersonFields);
P:oid   | P:name            | P:sex  | P:birthDay                   | P:birthPlace          
--------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | male   | Thu Oct 29 20:23:49 CET 2009 | Munich, 80809, Germany
100:2:0 | Christian Merenda | male   | {  }                         | Munich, 80809, Germany
100:5:0 | Lauro Merenda     | male   | {  }                         | Tuglie, 80811, Italy  
100:4:0 | Roswitha Merenda  | female | {  }                         | Graz, 80811, Austria  
>
> pp.printExtent(Person.CID, P(Person.P.name),intersect(C(EntityObject.CID),successor()));
P:name            | (C:[CID=2] intersect *)                                                                                     
--------------------------------------------------------------------------------------------------------------------------------
Stefano Merenda   | { Person:"Stefano Merenda"[100:3:0]; Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4: ... }
Christian Merenda | { Person:"Christian Merenda"[100:2:0]; Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100: ... }
Lauro Merenda     | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0]; Person:"Lauro Merenda"[100:5 ... }
Roswitha Merenda  | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0]; Person:"Lauro Merenda"[100:5 ... }
>
P:name            | (C:[CID=2] intersect *)                                                                                     
--------------------------------------------------------------------------------------------------------------------------------
Stefano Merenda   | { Person:"Stefano Merenda"[100:3:0]; Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4: ... }
Christian Merenda | { Person:"Christian Merenda"[100:2:0]; Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100: ... }
Lauro Merenda     | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0]; Person:"Lauro Merenda"[100:5 ... }
Roswitha Merenda  | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0]; Person:"Lauro Merenda"[100:5 ... }
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), where(exists(inverse(P(Person.P.children)))))),simplePersonFields); 
P:oid   | P:name            | P:parents                                                               | P:children | P:spouse | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
>
Of course, a result can be sorted by one or more criteria ...
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), orderby(asc(P(Person.P.name))))),simplePersonFields); 
P:oid   | P:name            | P:sex  | P:birthDay                   | P:birthPlace          
--------------------------------------------------------------------------------------------
100:2:0 | Christian Merenda | male   | {  }                         | Munich, 80809, Germany
100:5:0 | Lauro Merenda     | male   | {  }                         | Tuglie, 80811, Italy  
100:4:0 | Roswitha Merenda  | female | {  }                         | Graz, 80811, Austria  
100:3:0 | Stefano Merenda   | male   | Thu Oct 29 20:23:49 CET 2009 | Munich, 80809, Germany
>
> pp.printAsTable(eocSession.execute(Query(from(Person.CID), orderby(desc(P(Person.P.name))))),simplePersonFields); 
P:oid   | P:name            | P:sex  | P:birthDay                   | P:birthPlace          
--------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | male   | Thu Oct 29 20:23:49 CET 2009 | Munich, 80809, Germany
100:4:0 | Roswitha Merenda  | female | {  }                         | Graz, 80811, Austria  
100:5:0 | Lauro Merenda     | male   | {  }                         | Tuglie, 80811, Italy  
100:2:0 | Christian Merenda | male   | {  }                         | Munich, 80809, Germany
>
>

==============================================================
==  LESSON 4 - Object Identifiers (OIDs)                    ==
==============================================================
>
The oid is the unique identifer of an entity object.
After an insert, every entity object has a unique oid
> Person person = eocSession.insert( Person() ); 
> OId oid = person.getOid();              
> System.out.println( "OID: " + oid );  
OID: 100:7:0
>
An oid consists of two natural numbers. The first one is 
called producer id (pid) and the second one local id (lid)
The pid is set to the pid of the container (in our case 100
as defined in lesson 1). It has to be secured, that every
container has its unique pid. The lid is a consecutive number
created by the container.
> System.out.println( "PID: " + oid.getPid() );  
> System.out.println( "LID: " + oid.getLid() );  
PID: 100
LID: 7
>
We set name and gender of the person ...
> person.setName("Albert Einstein"); 
> person.setSex(Gender(Gender.MALE));  
> eocSession.commit(); 
>
Having an oid, you can find the appropriate entity object ... 
> System.out.println( eocSession.resolve(Person.CID, oid).getName() ); 
Albert Einstein
>
For associations you additionally have special getters and setters
which operates only with the oids instead of the real objects
To get the oids of the children of a father ...
> Person dad = (Person) eocSession.execute(Query(from(Person.CID), where(eq(P(Person.P.name),V("Lauro Merenda"))))).iterator().next(); 
> Set<OId> oids = dad.getIdsOfChildren();  
> System.out.println( "OIDs: " + oids ); 
OIDs: [100:3:0, 100:2:0]
>
Of course you can resolve a set of oids ...
> Set<Person> children = eocSession.resolve(Person.CID, oids);
> pp.printAsTable(children,extendedPersonFields); 
P:oid   | P:name            | P:parents                                                               | P:children | P:spouse | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
>
>

==============================================================
==  LESSON 5 - Read, alter and delete entities              ==
==============================================================
>
Let's find our mum ...
> Person mum = (Person) eocSession.execute(Query(from(Person.CID), where(eq(P(Person.P.name),V("Roswitha Merenda"))))).iterator().next(); 
>
To read an attribute or association you can use standard getters ...
> System.out.println( mum.getBirthDay() ); 
null
>
The birthday seams not to be set, yet. So let's do it by a
calling a standard setter ...
> mum.setBirthDay( new java.util.Date() /*today*/ ); 
>
Since this seams not be the right birthday, we remove it again ...
> mum.setBirthDay( null ); 
>
For collections you can do the same, e.g. reading ...
> System.out.println( mum.getChildren() ); 
[Person:"Stefano Merenda"[100:3:0], Person:"Christian Merenda"[100:2:0]]
>
In addition to the standard getters and setters, for collection
addToXy() and removeFromXy() are provided. E.g. we can add
Albert Einstein to the children ...
> Person albert = (Person) eocSession.execute(Query(from(Person.CID), where(eq(P(Person.P.name),V("Albert Einstein"))))).iterator().next(); 
> mum.addToChildren(albert); 
>
Let's have a look at the children, again ...
> System.out.println( mum.getChildren() ); 
[Person:"Stefano Merenda"[100:3:0], Person:"Christian Merenda"[100:2:0], Person:"Albert Einstein"[100:7:0]]
>
Since 'Children' is a bidirectional association to 'Parents',
the parents of Albert Einstein are also updated ...
> pp.printAsTable(mum.getChildren(),extendedPersonFields); 
P:oid   | P:name            | P:parents                                                               | P:children | P:spouse | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }       | {  }     | {  }      
100:7:0 | Albert Einstein   | Person:"Roswitha Merenda"[100:4:0]                                      | {  }       | {  }     | {  }      
>
Since this all is rubbish, we delete Albert Einstein ...
> eocSession.delete(albert); 
>
There are no dangling references.
Let's have a look at the children, again ...
> System.out.println( mum.getChildren() ); 
[Person:"Stefano Merenda"[100:3:0], Person:"Christian Merenda"[100:2:0]]
>
If you access to an already deleted entity object, 
a DeletedEntityExcpetion is thrown ... 
> albert.getName(); 
org.oomega.core.DeletedEntityException: Access to an already deleted entity object is not allowed.
>
Let's check by showing the extent of Person ...
> pp.printExtent(Person.CID, extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda     | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda  | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
>
>

==============================================================
==  LESSON 6 - Transactions                                 ==
==============================================================
>
First of all, we want to have our Albert Einstein back ...
> eocSession.rollback(); 
>
Let's check by showing the extent of Person ...
> pp.printExtent(Person.CID, extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda     | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda  | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
100:7:0 | Albert Einstein   | {  }                                                                    | {  }                                                                       | {  }                               | {  }      
>
If a prepare() or commit() fails because of a constraint
violation, a ConstraintViolationException is thrown, showing
all violations. To give the user/programmer a chance to
solve the problems, no automatic rollback is initiated ...
> Person person = eocSession.insert(Person()); 
> eocSession.commit();        
org.oomega.core.ConstraintViolationException: 
Person 100:8:0 is violated in field "name": Multiplicity is out of boundary. 0 not in [1..1].
Person 100:8:0 is violated in field "sex": Multiplicity is out of boundary. 0 not in [1..1].
2 constraint violations occured.
>
After the commit() the person without a name is still there ...
> pp.printExtent(Person.CID, extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda     | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda  | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
100:7:0 | Albert Einstein   | {  }                                                                    | {  }                                                                       | {  }                               | {  }      
100:8:0 | {  }              | {  }                                                                    | {  }                                                                       | {  }                               | {  }      
>
Now we are able to correct the problem ...
> person.setName("Pumuckl");        
> person.setSex(Gender(Gender.MALE)); 
>
Let's check by preparing the transaction ... 
> eocSession.prepare(); 
>
Now we start a nested transaction ... 
> TXContext nestedTX = eocSession.begin(); 
>
Now Pumuckl becomes a child of Albert
> Person albert = (Person) eocSession.execute(Query(from(Person.CID), where(eq(P(Person.P.name),V("Albert Einstein"))))).iterator().next(); 
> albert.addToChildren(person);
>
Let's have a look at the extent of Person ...
> pp.printExtent(Person.CID, extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda     | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda  | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
100:7:0 | Albert Einstein   | {  }                                                                    | Person:Pumuckl[100:8:0]                                                    | {  }                               | {  }      
100:8:0 | Pumuckl           | Person:"Albert Einstein"[100:7:0]                                       | {  }                                                                       | {  }                               | {  }      
>
We rollback the nested transaction ...
> nestedTX.rollback(); 
>
Let's check by showing the extent of Person ...
> pp.printExtent(Person.CID, extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda     | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda  | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
100:7:0 | Albert Einstein   | {  }                                                                    | {  }                                                                       | {  }                               | {  }      
100:8:0 | Pumuckl           | {  }                                                                    | {  }                                                                       | {  }                               | {  }      
>
Of course, we also can rollback the main transaction
(insert of Pumuckl) ... 
> eocSession.rollback(); 
>
By using a reference to an entity object, this entity object
is put back in the transaction automatically ...
> albert.addToChildren(albert); 
>
Let's check by showing the extent of Person ...
> pp.printExtent(Person.CID, extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda     | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda  | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
100:7:0 | Albert Einstein   | Person:"Albert Einstein"[100:7:0]                                       | Person:"Albert Einstein"[100:7:0]                                          | {  }                               | {  }      
>
We rollback again ...
> eocSession.rollback(); 
>
Let's check by showing the extent of Person ...
> pp.printExtent(Person.CID, extendedPersonFields);
P:oid   | P:name            | P:parents                                                               | P:children                                                                 | P:spouse                           | P:pictures
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:3:0 | Stefano Merenda   | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:2:0 | Christian Merenda | { Person:"Lauro Merenda"[100:5:0]; Person:"Roswitha Merenda"[100:4:0] } | {  }                                                                       | {  }                               | {  }      
100:5:0 | Lauro Merenda     | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Roswitha Merenda"[100:4:0] | {  }      
100:4:0 | Roswitha Merenda  | {  }                                                                    | { Person:"Stefano Merenda"[100:3:0]; Person:"Christian Merenda"[100:2:0] } | Person:"Lauro Merenda"[100:5:0]    | {  }      
100:7:0 | Albert Einstein   | {  }                                                                    | Person:"Albert Einstein"[100:7:0]                                          | {  }                               | {  }      
>
>

==============================================================
==  LESSON 7 - Weak entities and cascading deletes          ==
==============================================================
>
The class Picture is a weak entity class and the model says,
that a person might be shown on many pictures and a picture
shows exactly one person. The association is modelled as 
composition, i.e. each picture is part of a person.
Let's create such a picture ... 
> Picture picture = eocSession.insert(Picture()); 
> picture.setJpeg(new byte[1024]);                
>
Now we say that Albert is shown on the picture and commit ... 
> Person albert = (Person) eocSession.execute(Query(from(Person.CID), where(eq(P(Person.P.name),V("Albert Einstein"))))).iterator().next(); 
> picture.setShownPerson(albert); 
> eocSession.commit(); 
>
Let's have a look at the Picture extent ...
> pp.printExtent(Picture.CID, Picture.P.ALL);
P:oid   | P:vts | P:syntaxInformation | P:influencesConstraintsOf | P:constraintsInfluencedBy | P:associateSucc                   | P:compositeSucc | P:attributeSucc        | P:parent                          | P:hkey | P:ckey | P:lkeyEnv       | P:date | P:jpeg    | P:shownPerson                    
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
100:9:0 | {  }  | {  }                | {  }                      | {  }                      | Person:"Albert Einstein"[100:7:0] | {  }            | { [B@a83a13; 100:9:0 } | Person:"Albert Einstein"[100:7:0] | {  }   | {  }   | Albert Einstein | {  }   | [B@2b7db1 | Person:"Albert Einstein"[100:7:0]
>
Now we delete Albert ... 
> eocSession.delete(albert); 
>
Please note that the picture is still part of the database   
although the picture has no compositional parent, which      
is not allowed for weak entities; an inconsistent database   
state is permitted during the execution of a transaction!    
You can see the compositional parent by the inferred property
'parent'. (An inferred property cannot be changed directly.) 
> pp.printExtent(Picture.CID, Picture.P.ALL);
P:oid | P:vts | P:syntaxInformation | P:influencesConstraintsOf | P:constraintsInfluencedBy | P:associateSucc | P:compositeSucc | P:attributeSucc | P:parent | P:hkey | P:ckey | P:lkeyEnv | P:date | P:jpeg | P:shownPerson
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
Now we commit the current transaction. At commit time the state of   
the database is still inconsistent due to the constraint violation   
of the picture. Nevertheless the commit will succeed, because Picture
is a weak entity and therefore the entity object container is allowed
to delete this entity autonomous if no compositional parent exists.  
> eocSession.commit(); 
>
The Picture extent now contains no pictures any more ...
> pp.printExtent(Picture.CID, Picture.P.ALL);
P:oid | P:vts | P:syntaxInformation | P:influencesConstraintsOf | P:constraintsInfluencedBy | P:associateSucc | P:compositeSucc | P:attributeSucc | P:parent | P:hkey | P:ckey | P:lkeyEnv | P:date | P:jpeg | P:shownPerson
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>

==============================================================
==  LESSON 8 - OOMEGA's Reflection API                      ==
==============================================================
>
As we already used in predicate definitions, we can easily define
field paths. Let's define a fieldpath for the name of the spouse
of a person ... 
> Edge edge = nav(P(Person.P.spouse),P(Person.P.name)); 
> 
We can also create the same fieldpath dynamically ... 
> edge = FieldPath(Property.get("spouse"),Property.get("name")); 
>
Every object provides generic getters and setters.
Let's try to get the name of the spouse of 'Lauro' ... 
> Person dad = (Person) eocSession.execute(Query(from(Person.CID), where(like(lower(P(Person.P.name)),"lauro*")))).iterator().next(); 
> System.out.println( edge.toString(ConcreteSyntaxIdentifier.get("M2L")) + ": " + dad.evaluate(edge)); 
(P:spouse.P:name): [Roswitha Merenda]
>
>

==============================================================
==  LESSON 9 - Observing entity objects (events)            ==
==============================================================
>
Create a new person: Hugo Boss ... 
> Person hugo = eocSession.insert(Person());
> hugo.setName("Hugo Boss"); 
>
No we attach an observer. The observer implements the EOObserver
interface which contains only the method 'setterCallback'. If the
entity gets modified / deleted, it will inform all observers ... 
> EOObserver observer = new DemoObserver(); 
> hugo.attachObserver(observer); 
>
Set the birthday of the observed entity.
> hugo.setBirthDay( new java.util.Date() ); 
CALLBACK: Person:"Hugo Boss"[100:10:0] has been modified in field 'birthDay'
>
Add the person to his own set of children. As this
is a bidirectional association, the son is changed
automatically in its field parents. Therefore
the setter callback is invoked twice!
> hugo.addToChildren(hugo); 
CALLBACK: Person:"Hugo Boss"[100:10:0] has been modified in field 'children'
CALLBACK: Person:"Hugo Boss"[100:10:0] has been modified in field 'parents'
>
Delete the observed entity in the database. 
During deletion all bidirectional associations
are adjusted, thus this results actually in 
three setter callbacks.
> eocSession.delete(hugo); 
CALLBACK: Person:"Hugo Boss"[100:10:0] has been modified in field 'parents'
CALLBACK: Person:"Hugo Boss"[100:10:0] has been modified in field 'children'
CALLBACK: The calling entity has been deleted!
>
>

==============================================================
==  LESSON 10 - Graph traversing (transitive closures)      ==
==============================================================
>
First of all let's add one additional generation ... 
> Person mum = (Person) eocSession.execute(Query(from(Person.CID), where(like(lower(P(Person.P.name)),"lauro*")))).iterator().next();
> Person grandpa = eocSession.insert(Person()); 
> grandpa.setName("Julius Caesar");    
> grandpa.setSex(Gender(Gender.MALE));   
> grandpa.addToChildren(mum);            
> eocSession.commit();                          
>
Let's find one of the jungest generation ...
> Person jungest = (Person) eocSession.execute(Query(from(Person.CID), where(empty(P(Person.P.children))))).iterator().next(); 
> System.out.println( jungest );
Person:"Stefano Merenda"[100:3:0]
>
Now let's get all entities that are reachable from that person.  
Note, that the object itself is also returned.                   
> System.out.println( jungest.evaluate((closure(successor()))) );
[0.0, Lauro Merenda, Julius Caesar, Tuglie, 80811, Italy, Munich, 80809, Germany, 1.0, Italy, Graz, 80811, Austria, Tuglie, 80809.0, Person:"Stefano Merenda"[100:3:0], Person:"Christian Merenda"[100:2:0], Munich, Person:"Lauro Merenda"[100:5:0], Person:"Roswitha Merenda"[100:4:0], male, female, Graz, Stefano Merenda, Person:"Julius Caesar"[100:11:0], Austria, Thu Oct 29 20:23:49 CET 2009, Roswitha Merenda, Christian Merenda, Germany, 80811.0]
>
You can restrict the depth of the graph traversing. Now only the      
element itself is returned ...                                        
> System.out.println( jungest.evaluate((closure(successor(),V(0)))) );
[Person:"Stefano Merenda"[100:3:0]]
>
Now only the parents are returned. To get the children and the        
parents of them, you would need a minimum depth of 2 ...              
> System.out.println( jungest.evaluate((closure(successor(),V(1)))) );
[Thu Oct 29 20:23:49 CET 2009, Person:"Stefano Merenda"[100:3:0], Person:"Lauro Merenda"[100:5:0], Person:"Roswitha Merenda"[100:4:0], male, Munich, 80809, Germany, Stefano Merenda]
>
When you are intersted in special fields, you can use properites   
instead of successor(). In this example we want only the children  
to be returned ...                                                 
> System.out.println( jungest.evaluate((closure(P(Person.P.children),V(2)))) ); 
[Person:"Stefano Merenda"[100:3:0]]
>
>

==============================================================
==  LESSON 11 - OOMEGA's Streaming API                      ==
==============================================================
>
We distinguish sources (EOInputStream) and sinks (EOOutputStream). 
Streams can be seperated in sequences.
To visualize a stream the utility class EOOutputWriter is provided ... 
> EOOutputStream<Person> out = new EOOutputWriter<Person>(System.out); 
> out.putNext(Person(OId(10,10),"Marie Curie",Gender(Gender.FEMALE),null,null,null,null,null,null)); 
> out.putNext(Person(OId(10,15),"Galileo Galilei",Gender(Gender.MALE),null,null,null,null,null,null)); 
> out.startNextSequence(); 
> out.putNext(Person(OId(10,20),"Isaac Newton",Gender(Gender.MALE),null,null,null,null,null,null)); 
> out.close();
-  2102 10:10:0 Person:"Marie Curie"[10:10:0]
-  2102 10:15:0 Person:"Galileo Galilei"[10:15:0]
NEW SEQUENCE
-  2102 10:20:0 Person:"Isaac Newton"[10:20:0]
STREAM CLOSED.
>
A sink can also be a list of collections. Every sequence is stored
in one collection ... 
> out = new EOOutputCollection<Person>(); 
> out.putNext(Person(OId(10,10),"Marie Curie",Gender(Gender.FEMALE),null,null,null,null,null,null)); 
> out.putNext(Person(OId(10,15),"Galileo Galilei",Gender(Gender.MALE),null,null,null,null,null,null)); 
> out.startNextSequence(); 
> out.putNext(Person(OId(10,20),"Isaac Newton",Gender(Gender.MALE),null,null,null,null,null,null)); 
> out.close();
> List<List<Person>> outCollections = ((EOOutputCollection<Person>)out).getCollections(); 
> System.out.println("How many sequences: " + outCollections.size() ); 
> System.out.println("The result: " + outCollections );
How many sequences: 2
The result: [[Person:"Marie Curie"[10:10:0], Person:"Galileo Galilei"[10:15:0]], [Person:"Isaac Newton"[10:20:0]]]
>
We can use these collections also as input collections ... 
> EOInputStream<Person> in = new EOInputCollection<Person>(outCollections.toArray(new Collection[0])); 
>
We can pipe this EOInputStream to an EOOutputWriter to see what's
in the EOInputStream. This is done by ActivePipe ... 
> out = new EOOutputWriter<Person>(System.out); 
> new ActivePipe<Person>(out,in).run(); 
-  2102 10:10:0 Person:"Marie Curie"[10:10:0]
-  2102 10:15:0 Person:"Galileo Galilei"[10:15:0]
NEW SEQUENCE
-  2102 10:20:0 Person:"Isaac Newton"[10:20:0]
>
Every entity object container can act as an input or output stream.
First we use our container as an outputstream in order to insert
our collection to the container ... 
> in = new EOInputCollection<Person>(outCollections.toArray(new Collection[0])); 
> out = (EOOutputStream)eocSession.getEOOutputStream();
> new ActivePipe<Person>(out,in).run(); 
>
Let's check by showing the extent of Person ...
> pp.printExtent(Person.CID, simplePersonFields);
P:oid    | P:name            | P:sex  | P:birthDay                   | P:birthPlace          
---------------------------------------------------------------------------------------------
100:3:0  | Stefano Merenda   | male   | Thu Oct 29 20:23:49 CET 2009 | Munich, 80809, Germany
10:10:0  | Marie Curie       | female | {  }                         | {  }                  
100:2:0  | Christian Merenda | male   | {  }                         | Munich, 80809, Germany
100:5:0  | Lauro Merenda     | male   | {  }                         | Tuglie, 80811, Italy  
100:4:0  | Roswitha Merenda  | female | {  }                         | Graz, 80811, Austria  
10:15:0  | Galileo Galilei   | male   | {  }                         | {  }                  
100:11:0 | Julius Caesar     | male   | {  }                         | {  }                  
10:20:0  | Isaac Newton      | male   | {  }                         | {  }                  
>
Both, sources and sinks can be decorated e.g. by filtering or 
manipulating the stream. Now we use the container as input stream 
Since the result will be the whole content of the container, we filter 
the result: We are only interested in the stored persons ... 
> in  = new EOISFilter<Person>(eocSession.getEOInputStream(),instance(Person.CID),eocSession); 
> out = new EOOutputWriter<Person>(System.out); 
> new ActivePipe<Person>(out,in).run(); 
NEW SEQUENCE
-  2102 10:10:0 Person:"Marie Curie"[10:10:0]
-  2102 10:15:0 Person:"Galileo Galilei"[10:15:0]
-  2102 10:20:0 Person:"Isaac Newton"[10:20:0]
-  2102 100:3:0 Person:"Stefano Merenda"[100:3:0]
-  2102 100:2:0 Person:"Christian Merenda"[100:2:0]
-  2102 100:5:0 Person:"Lauro Merenda"[100:5:0]
-  2102 100:4:0 Person:"Roswitha Merenda"[100:4:0]
-  2102 100:11:0 Person:"Julius Caesar"[100:11:0]
>
To copy the content from one container to an other, just connect 
their streams by an active pipe. The container do not have to be 
of the same type, so you can transfer data from e.g. a hibernate 
connected MySQL to a Versant Object Database ... 
> EOContainerSession newEOC = MemoryEOC.createEOC(110).getSession(); 
> new ActivePipe<EntityObject>(newEOC.getEOOutputStream(),eocSession.getEOInputStream()).run(); 
>
Let's check by showing the extent Person of the new container ...
> new PrettyPrinter(newEOC,System.out).printExtent(Person.CID, simplePersonFields); 
P:oid    | P:name            | P:sex  | P:birthDay                   | P:birthPlace          
---------------------------------------------------------------------------------------------
100:3:0  | Stefano Merenda   | male   | Thu Oct 29 20:23:49 CET 2009 | Munich, 80809, Germany
100:2:0  | Christian Merenda | male   | {  }                         | Munich, 80809, Germany
10:10:0  | Marie Curie       | female | {  }                         | {  }                  
100:5:0  | Lauro Merenda     | male   | {  }                         | Tuglie, 80811, Italy  
100:4:0  | Roswitha Merenda  | female | {  }                         | Graz, 80811, Austria  
10:15:0  | Galileo Galilei   | male   | {  }                         | {  }                  
100:11:0 | Julius Caesar     | male   | {  }                         | {  }                  
10:20:0  | Isaac Newton      | male   | {  }                         | {  }                  
>
>

==============================================================
==  LESSON 12 - OOMEGA's XML and binary serialisation       ==
==============================================================
>
For both XML and binary serialisation corresponding sources and 
sinks for the streaming API are provided. They are called 
SDFCoder and SDFDecoder for the binary serialisation and 
SDMLCoder and SDMLDecoder for the XML serialisation.
>
We serialise all the persons stored in the container ... 
> EOInputStream<EntityObject> in  = new EOISFilter<EntityObject>(eocSession.getEOInputStream(),instance(Person.CID),eocSession); 
> EOOutputStream<EntityObject> out = new SDFCoder(new FileOutputStream("build/output/demo-lessons/persons.sdf")); 
> new ActivePipe<EntityObject>(out,in).run(); 
> out.close(); 
>
To convert from the binary to the XML format, just connect the 
appropriate coder and decoder by an active pipe ... 
> in  = new SDFDecoder(new FileInputStream("build/output/demo-lessons/persons.sdf"),eocSession.getEOC().getClassDirectory()); 
> out = new SDMLCoder(new FileOutputStream("build/output/demo-lessons/persons.xml")); 
> new ActivePipe<EntityObject>(out,in).run(); 
> out.close(); 
>
Of course you can also dump the whole database to an XML file ... 
> in  = eocSession.getEOInputStream(); 
> out = new SDMLCoder(new FileOutputStream("build/output/demo-lessons/dbdump.xml")); 
> new ActivePipe<EntityObject>(out,in).run(); 
> out.close(); 
>
Now we can read the dump into a new container ... 
> EOContainerSession newEOC = MemoryEOC.createEOC(110).getSession(); 
> in  = new SDMLDecoder(new FileInputStream("build/output/demo-lessons/dbdump.xml"),eocSession.getEOC().getClassDirectory()); 
> out = newEOC.getEOOutputStream(); 
> new ActivePipe<EntityObject>(out,in).run(); 
> out.close(); 
>
Let's check by showing the extent Person of the new container ...
> new PrettyPrinter(newEOC,System.out).printExtent(Person.CID, simplePersonFields); 
P:oid    | P:name            | P:sex  | P:birthDay                   | P:birthPlace          
---------------------------------------------------------------------------------------------
100:3:0  | Stefano Merenda   | male   | Thu Oct 29 20:23:49 CET 2009 | Munich, 80809, Germany
100:2:0  | Christian Merenda | male   | {  }                         | Munich, 80809, Germany
10:10:0  | Marie Curie       | female | {  }                         | {  }                  
100:5:0  | Lauro Merenda     | male   | {  }                         | Tuglie, 80811, Italy  
100:4:0  | Roswitha Merenda  | female | {  }                         | Graz, 80811, Austria  
10:15:0  | Galileo Galilei   | male   | {  }                         | {  }                  
100:11:0 | Julius Caesar     | male   | {  }                         | {  }                  
10:20:0  | Isaac Newton      | male   | {  }                         | {  }                  
>
>
==============================================================
==  Disconnect and logout                                   ==
==============================================================
>
> eocSession.logout();
> eocSession.disconnect();
>
>
Congratulations! You have done all our lessons.
If you have more questions please join <community@oomega.net> ...
>
>

Next chapter: API Reference

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.