Sonntag, 15. Juni 2008

Groovy and db4o

It's already a long time since my last post. Got caught in my current project.
However, recently I used some time to have a look at some topics of interest.
One of these points were Groovy. Currently, there is a lot of momentum in the area of dynamic languages. Groovy is part of it and it's really cool. I think it as a natural complementary fit to Java if used in the right way.
You can choose between dynamic and static typed programming. This freedom may be heaven and hell. However, it brings some useful and well though language constucts and features to ease programming. Just to mention a few: Closures, Everything is an object, Handling of list and maps, Proxying, Meta-class programming, construction of DSL.

The latter one is based on a groovy's builder concept.
Since I wanted to check it out, I used my favourite object oriented database db4o and built a db4o builder on top of it. It is hosted on google. You can download it here or browse the svn for the latest code.

The Groovy builder pattern is a powerful concept to provide arbitrary nested trees of objects or events, providing a tree-like façade. Though the db4o API is already very simple to use on its own, the db4o builder provides another easy way of accessing db4o databases. A Groovy builder relies on closures to setup its tree-like structure based on nodes.

Db4o has a very easy Java API that can be used in groovy as is. Open a database by and work on a Db4oContainer object to store and access objects by simply calling set and get or performing complex queries.


// Open the database
Db4oObjectContainer oc = Db4o.openFile(“d:/Db4oSampleDatabase.yap”);

// Store an object
oc.set(new Person("Doe","John") );
// query data
Query q = oc.query();
q.constrain(Person.class);
ObjectSet objectSet = q.execute();

// close it again, database operations are committed automatically
oc.close();
Well, that is already really easy.

However, in groovy you can leverage the builder concept to let it open and close the database automatically. Same when specifying a query the builder may execute the query automatically when the query has been set.

That is what the db4o builder is about.

You can do the same as above using the following syntax.


Db4oBuilder builder = new Db4oBuilder();
builder.file('d:/Db4oSampleDatabase.yap') {
set(new Person("Doe","John") )
query(Person.class) {
}
// query executed, process result
}
As you see, there is nothing special in creating a db4o builder object. You create it like any other java or groovy object. A db4o database is opened and close by using the file method (well to open a remote database server there is also a client method that takes the host, port, user name and password which should work but I haven't tested it yet).

The db4o database is opened on entering the file node and closed on leaving it. The file method is equipped with a closure to take the custom action.

Db4oBuilder builder = new Db4oBuilder();
builder.file('d:/Db4oSampleDatabase.yap') {
}
Within the closure, we now can use additional methods to store, update, delete or query objects. In order to store objects, you simply call the set method within the closure of the file method. The set method takes the object to store as argument.
Db4oBuilder builder = new Db4oBuilder();
builder.file('test.yap') {
set( new Person("Doe","John"))
}
If you need access to the opened db4o database, the db4o builder provides access to a variable called objectContainer which is of type com.db4o.ObjectContainer and represents the opened db4o database connection.
Db4oBuilder builder = new Db4oBuilder();
builder.file('test.yap') {
println objectContainer.ext().version()
}
That’s it basically. You can insert any code within the closure. For example, the following code stores 10 Person objects into the database.
Db4oBuilder builder2 = new Db4oBuilder();
builder2.file('test.yap') {
(1..10).each {
def pers = new Person("Doe"+it,"John");
set(pers)
}
}
Objects can be deleted by using the delete method.
Queries supported are based on SQL or the S.O.D.A. concept.
S.O.D.A. queries are built like a tree. A basic example
Db4oBuilder builder3 = new Db4oBuilder();
builder3.file('d:/Db4oSampleDatabase.yap') {
query() {
constrain(Person.class) {
}
}
}
The output of this query are all persons stored in the db4o database.
This query can also be simplified by using the person class as a parameter to the query node.

Db4oBuilder builder3 = new Db4oBuilder();
builder3.file('d:/Db4oSampleDatabase.yap') {
query(Person.class) {
}
}
The result of the query can be evaluated or processed either within the builder or outside of it.
Db4oBuilder builder3 = new Db4oBuilder();
builder3.file('d:/Db4oSampleDatabase.yap') {
query(Person.class) {
}
if( objectSet ) {
println ("${objectSet.size()}")
objectSet.each() { p ->
println "Person: ${p.lastName},${p.firstName},${p.age}"
}
}
}
Query results are automatically available in a variable called objectSet. Here is more complex example using or operator to combine to subqueries.
import com.db4o.groovy.Db4oBuilder;
import gk.samples.db4o.domain.Person;

Db4oBuilder builder3 = new Db4oBuilder();
builder3.file('d:/Db4oSampleDatabase.yap') {
query(Person.class) {
descend("lastName") {
constrain("KL") {
startsWith() {
or() {
descend("age") {
constrain(34) {
greater()
}
}
}
}
}
}
}
if( objectSet ) {
println "${objectSet.size()}"
objectSet.each() { p -> println "Person: ${p.lastName},${p.firstName},${p.age}" } }
}
SQL Queries are done the same way by using a special node called sqlquery. In addition to query the results after the node and outside of the builder, the query result can be processed within the sqlquery node itself as well. An example:
Db4oBuilder builder = new Db4oBuilder();
builder.file('d:/Db4oSampleDatabase.yap') {
sqlquery("from gk.samples.db4o.domain.Person") {
if( objectSet ) {
println ("${objectSet.size()}")
objectSet.each() { p -> println "Person: ${p.lastName},${p.firstName},${p.age}"}
}
}
}
Db4o allows you to setup configuration parameters. Most of them have to be set before opening the database. That is supported by the db4oBuilder by using a special configuration node.
Db4oBuilder builder = new Db4oBuilder();
builder.configuration() {
}
The configuration node sets up a reference the db4o configuration object. This reference is available by using the config variable can be use to set any db4o configuration parameter.
Db4oBuilder builder = new Db4oBuilder();
builder.configuration() {
config.activationDepth(5)
config.updateDepth(5)
config.freespace().discardSmallerThan(5)
}
Alternatively, you can pass a map of configuration parameters as argument to the configuration node. These will then be set by the db4o builder automatically.
def config = ["activationDepth" : 5, "updateDepth": 5]

builder.configuration( config ) {
}
After setting the configuration the db4o database can be opened as seen before.
builder.configuration() {
config.activationDepth(5)

file('d:/Db4oSampleDatabase.yap') {
// store or query objects
}
}
I will continue looking at Groovy and check out more concepts provided by Groovy.

Sonntag, 11. November 2007

db4o-netbeans updates

db4o-netbeans is available in 0.6.0 now.
Since my time is very limited, I moved in small steps with the plugin only. However, some things have been added, some things have been stabilized.

Documentation has been updated. Go to the db4o-netbeans home or download directly from here.
Well, as ever, any feedback is appreciated.

Soon, after finishing the most important basic features to the plugin, I will have a look on how to add support to the Visual Web Pack integrated into NetBeans. This will be good milestone for a tight integration of db4o database into NetBeans. If only time wouldn't be such a problem...


Dienstag, 23. Oktober 2007

db4o-netbeans 0.3.0 with little changes

Small changes have been added to the db4o-netbeans plug in.
However, I gave it the version number 0.3.0.
The most interesting changes are:
  • Creation of a new db4o database connection: Entering the conection details are integrated into the new file wizard as its own wizard page.
  • Start As Server: You can also start a db4o database file within an embedded server for testing purposes.
  • Auto-update capabilities: A NetBeans Update Center has been added to get an updated plugin downloaded and installed automatically.
Documentation has been updated. Go to the db4o-netbeans home or download directly from here.
Well, as ever, any feedback is appreciated.

Montag, 15. Oktober 2007

db4o-netbeans 0.2.0 available

I have improved the usability of the db4o-netbeans plug-in. It is now available as version 0.2.0.
You may download the new version from here.
In comparison to the version 0.1.0, there are some changes. A document describing the new version and the changes made may downloaded as a pdf from the same location.

I think, it is a good base to improve it by adding more features.
Next steps are focused on improving the editor capabilities, exception handling and preparing the source code to add it to the download section as well.

Check out the new version.
Any feedback or comments how to improve are welcome.


Sonntag, 9. September 2007

db4o-netbeans project launched

I've just started a new project to build a netbeans plugin for the db4o object database. Keep a bookmark to http://code.google.com/p/db4o-netbeans/. Soon, I will add artifacts there that you can download and use.

As a preview, here are some of the first screen shots and some information about the initial version:

db4o database are accessed by simply creating a custom file type choosing New File on the File menu and adding it to an opened java project.













After entering a name, a file of type db4o is added to the java project.












Using the context menu item Open Db4o Editor opens the editor to visualize the db4o database content. The editor may be used to navigate the database content, add or remove objects to or from the database or change values of stored objects.


















Values are edited and changed in the regular properties window provided by net beans.



















A first simple approach to add support for db4o database is by constructing soda based queries. The elements of a query will be added as sub nodes to the db4o database node in the projects navigation view.



















However, this approach has some limitations but is easy to implement.
Executing the query opens another editor window for the query results.


















The count of objects affected by the query is additionally displayed in the title.

Well, the project has just been started and there is quite a lot to do to make it smooth.
Especially, improving the query approach to the latest db4o features and editing capabilities are quite challenging.
Moreover, currently db4o 6.1 is used. I need to make sure that the plugin is independent on a certain db4o version. And last but not least, support for net beans 6.0 is on the list as well.

If you are interested in the project and would like to know more about it, please post a comment here. Contributions are welcome.