-lgnodbify-gtk

A while back, I wrote about this GObject-based Object/Relational mapper that I wrote, which is called 'GNoDbify'. It isn't complete yet, but parts of the library work; I use it for a project that I'm supposed to commercially support. For those who don't know what that is: an O/R mapper builds objects out of database tuples; so I can run a 'lookup' function on the object class and get one (or more) objects representing data from the database, then perform some modifications on that object, and store it back in the database; my O/R mapper does all the SQL magic.

Last week, I've been working on another object that takes an array of GNoDbify objects, and presents them using the GtkTreeModel interface, for easy viewing in a GtkTreeView:

my @customers = Vpbs::Db::Customer->get_all();
my $model = GNoDbify::ListStore->new_from_array(@customers);
my $view = Gtk2::TreeView->new_with_model($model);
my $renderer = Gtk2::CellRendererText->new();
my $column = Gtk2::TreeViewColumn->new_with_attributes("Name", $renderer, "text", $model->get_column("name"));
$view->append_column($column);

And there you have it: a treeview showing all the names of all the customers in the database. On the classical approach, one would have to use DBI or some such to fetch data from the database, create a GtkListStore or something similar, and then append the data one row at a time to that. Of course that still happens here, in a manner of speaking, but it all happens behind the scenes. It also means that in an application which wants to show a load of data, I don't have to do the same thing all the time.

The magic happens in the second line, and in the second-to-last line. GNoDbify::ListStore->new_from_array is pretty much self-explanatory, really. It takes an array of GNoDbify objects, and returns a GNoDbify::ListStore.

The second-to-last line shows how to add a column to a GtkTreeView. With GtkListStore and GtkTreeStore you basically define yourself what column gets what number; however, with GNoDbify, that isn't as easy (it depends on the implementation of the GNoDbify subclass), so the ->get_column returns the number of a column as represented by the model, and wants the name of the field that you want the column of.

Everything else is really the same.

It won't stop here, though. The original plan for GNoDbify was that it could detect changes in the database, and update the tree model accordingly. Most of that has already been implemented in GNoDbify (though not yet in the ListStore thing), but just needs some debugging. The fun thing is, the above six lines of code would not have to change at all for that.

Of course all this juicyness comes at a price. In order to generalize this much, I had to do a lot of extra stuff; so there's some performance loss. Especially in perl; most of GNoDbify is written in C, and converting perl arrays to and from C arrays is a process that can only be done by looping over the perl array (or the C array) and creating the other side of the equation. Obviously, that's a costly approach, performance-wise; an obvious optimization of the above example could be to have a subroutine that returns Customer objects already in a GtkTreeView in one API call. We'll see.