Gmail for Mobile HTML5 Series: A Common API for Web Storage

MAY 21, 2009
On April 7th, Google launched a new version of Gmail for mobile for iPhone and Android-powered devices. We shared the behind-the-scenes story through this blog and decided to share more of our learnings in a brief series of follow up blog posts. Over the last few weeks we've talked about how to use the AppCache functionality of HTML5 to launch an application offline. We discussed the impact that AppCache can have on your mobile web applications, as you enable users to launch your app faster in the face of flaky or slow internet connections. This week, I'll talk about how we're using both HTML5 Structured Storage and the Google Gears Database to make devices tolerate flaky network connections.



Although these technologies allow web applications to cache user data on the mobile device and perform data modifications locally, HTML5 Structured Storage uses an asynchronous model, where the Google Gears Database uses a synchronous model. This difference makes it difficult to develop an application on top of both platforms. We dealt with this problem by creating the Web Storage Portability Layer (WSPL) for Gmail. Coming soon under a liberal open source license to code.google.com/p/webstorageportabilitylayer, WSPL provides a common API that supports an identical asynchronous programming model for both platforms by using a worker thread in Gears. Let's take a look!

The WSPL consists of a collection of classes that provide asynchronous transactional access to both Gears and HTML5 databases. It can be used to execute nested statements within callbacks, create statement templates, and optionally control the synchronous/asynchronous modes of the Gears Database Wrapper. There are five basic classes.

google.wspl.Statement - A parametrizable SQL statement class
google.wspl.Transaction - Used to execute one or more Statements with ACID properties
google.wspl.ResultSet - Arrays of JavaScript hash objects, where the hash key is the table column name
google.wspl.Database - A connection to the backing database, also provides transaction support
google.wspl.DatabaseFactory - Creates the appropriate HTML5 or Gears database implementation

Let's take a look at how we can use this API to perform a simple query, starting with the creation of a Database. Note that you'll need to provide a URL to the worker file hosted from your domain.

var database = google.wspl.DatabaseFactory.createDatabase('db name', 'http://yourdomain/dbworker.js');

You can then execute SQL statements without worrying about the specifics of HTML5 and Gears. Refer to the recent blog posts about AppCache to find steps you can follow to see your database contents using sqlite3.
var
      statement = google.wspl.Statement('SELECT col from test_table;');
database.createTransaction(function(tx) {
tx.executeAll([statement], {onSuccess: function(tx, resultSet) {
// Statement succeeded.

for(; resultSet.isValidRow(); resultSet.next()) {
window.console.info(resultSet.getRow()['col']);
}
}, onFailure: function(error) {
// Statement failed.
}});
}, {onSuccess: function() {
// After transaction commits, before any other starts.
}, onFailure: function(error) {
// After transaction fails, before any other starts.
}});
I've found that using the Gears database asynchronously will nicely split up the JavaScript execution, allowing event handlers and other code to execute between the callbacks. This can improve the responsiveness of your application if you're using long transactions. You can also use SQL triggers to avoid the read-modify-write pattern that causes "ping ponging" between threads -- either the main thread and Gears worker or the main thread and the HTML5 SQL thread.

That's all I'll show you for now, but you can look for more details about the Web Storage Portability Layer at Google I/O, May 27-28 in San Francisco where we'll be presenting a session on the architecture of a generic application using HTML5. We'll also be available at the Developer Sandbox and are looking forward to meeting you in person. Stay tuned for the next post where we'll talk about improving the performance of HTML5-based web applications.

By Matthew Bolohan, Software Engineer, Google Mobile