Posted Monday, October 12, 2009 01:42:43 AM by dfe

Well, it's been a long time coming but I finally got a blog up. For whatever reason I decided to write a blogging system from scratch.

You may not notice from the "friendly" URLs but this blog is powered by WebObjects. Eventually I hope to throw most of the rest of the site content in here and move it in to the 21st century.

Why WebObjects? Because I needed to eat some of my own dogfood. Of course, the development environment isn't perfect and in the interest of saving time I did use Eclipse+WOLips to set up the build system. But after trying to get used to Eclipse's Java editor I finally gave up and created an Xcode project that runs ant to build the project. Once I added the java source files and .wo components into the Xcode project I even got WebObjects Builder working.

In Mike's defense, the WOLips Component Editor (used to edit .wo) is arguably the best part of WOLips. Where I had things that were broken in WebObjects Builder (e.g. display groups cannot be edited) it worked well. But for general editing of the components and setting bindings WebObjects Builder was the easiest.

I did use Entity Modeler to do the model editing but that's going to change soon. Like the rest of Eclipse it has a habit of warning you about things that are not problems. A quick example: one trick I have used on several occasions is to add multiple attributes to an entity with the same DB column name. Now, why would I do this? Well, so I could put a read format on one of them and get the DB to do some special queries for me.

For instance, this very entry has a publishedTimestamp attribute which is stored as a timestamptz in PostgreSQL. But to look it up by date the SQL I want to use is WHERE published_timestamp::date = ?. That is, I want the DB to cast the timestamptz to a date for me, and then compare that to the date that is passed in. In PostgreSQL this causes the time portion to be ignored. So to accomplish this I added a publishedDate attribute which is not a class property (thus, doesn't get fetched) and not used for locking (thus, doesn't get used in update statement where clauses) and has a read format of %P::date. In short, the attribute does absolutely nothing at all except for the case when you use "publishedDate" in an EOQualifier. In that case it causes EOF to generate exactly the SQL I'm looking for with minimum fuss. I can even take this to the next level and add yet another attribute to get the month (i.e. year-month) and another one to get just the year. In the end, it's all stored in the DB as one single timestamptz column.

The trick to this is that if the qualifier ever gets used to filter in-memory EOs then it bombs since the publishedDate attribute isn't available. But.. come on people, this is EOF. So you just add a publishedDate() getter to do the right thing in Java and voila; you now have the ability to filter in memory.

Granted it would be theoretically better if EOF had some facility for doing arbitrary data conversions and a way to cause that to execute a method java-side and generate the text for a function-call SQL side. For example, something like publishedTimestamp.@convertToDate. But for most purposes the built-in EOF facilities can be abused like this to do exactly what you need.

I should point out one caveat to this. In past programs I have always left the column name blank and then put %Pcolumn_name in the read format. The reason for this is just in case EOF does for some strange reason decide to generate an UPDATE statement, it won't have a valid column name (read format cannot apply to a column name for an update) and the update will fail instead of attempting to set the column value to something completely bogus. But in this case Entity Modeler still warns you that there is no column name. I suppose that's good. I mean how else would I know there was no column name other than.. wait for it... looking at the list of attributes. Since the DB column name is one of the things you see in the attribute list an empty one already stands out like a sore thumb.

So, like this blog, getting a comfortable WO development environment is a work in progress. My hope is that by having this blog written in WO it will force me to occasionally get off my duff and start getting something together that works well for me. With any luck some of you other stranded WO developers who keep mailing me can benefit as well.