Wednesday, April 16, 2008

Safari 3.1 Offline Database

I'm a little slow: after a couple weeks of running Safari, I randomly poked about in the prefs and noticed a new section mentioning databases.

Databases! Does this mean a persistent and offline storage feature like Google Gears in Firefox? Why, yes, it appears to be. Suddenly, the door is open for Safari users to get access to the world of future sweetness which is barreling down the tracks: offline versions of online applications. Google, of course, is moving toward this with offline Google Apps, allowing you to work on your various word processing docs, spreadsheets and whatnot without your computer being on the net.

Of course, this spells trouble for the M$ empire, which makes us all happy (unless you are not 'us', but rather, 'them').

Looking around for info on the Safari database, I found this page on the Webkit website, which describes offline database storage being a pre-final Html 5 feature. (Seems goofy to me that programatic access to databases would be part of the Html spec. Ah, well.) Even better is a simple sticky note demo application which uses the db for storage between visits.

I pried into the source to see how they're doing it in Javascript. This is a typical function:
function loadNotes()
db.transaction(function(tx) {
tx.executeSql("SELECT id, note, timestamp, left, top, zindex FROM WebKitStickyNotes", [], function(tx, result) {
for (var i = 0; i < result.rows.length; ++i) {
var row = result.rows.item(i);
var note = new Note(); = row['id'];
note.text = row['note'];
note.timestamp = row['timestamp'];
note.left = row['left']; = row['top'];
note.zIndex = row['zindex'];

if (row['id'] > highestId)
highestId = row['id'];
if (row['zindex'] > highestZ)
highestZ = row['zindex'];

if (!result.rows.length)
}, function(tx, error) {
alert('Failed to retrieve notes from database - ' + error.message);
Wacky, huh? Access to the db is asynchronous and the data is returned to your application through a callback. Comments on the webkit site claims that the new functions are secure because each database is unique to a domain, and calls to the database are subject to a single origin policy, just as cookies are. No doubt, funny business will ensue (i.e. don't store credit card numbers, maiden names of any of your mothers, or pet's favorite snacks).

Web Inspector in the Develop menu (available in Webkit, and also in my copy of Safari, probably because I was running pre 3.1 Webkit builds) lets you peer into your local databases, which is pretty tasty:

I don't particularly like the intermingling of markup and sql. The slogging of year ago through asp and jsp and all those ugly, early database web apps really gives me the fear of this kind of thing. It's early, I know, and the 21st century, so no doubt we'll start to get persistence frameworks, domain models, and ORM software packages in Javascript to provide the same layering and separation of duties that server-side developers are used to. Will we have Hibernate for Javascript? I'm really looking forward when GWT starts to support offline databases and you'll be able to write in pure, pure Java.


Brad Neuberg said...

There are GWT bindings for Gears so that you can access the client-side relational database using GWT's Java syntax.

Brad Neuberg

t said...

Thanks! It's funny, after I posted this, I thought "hmmm. I'd better check on GWT and gears", low and behold, I found the gwt-google apis:

But I'm sure *you* know all about that...