Saturday, February 20, 2010

GAE Developer Tip: Updating Database Schema

The backend of Google App Engine is not relational. One of the implications is different records in the same table can have different number of columns. Sometimes it's just fine, other times you want it the conventional way - all rows having the same columns.

The practical consequence of such a design is that a field added to a domain object will only appear in objects of this type created after the structure of the object was modified. All the objects created before the change will happily live with the old structure.

Before you know it you'll want to filter or sort on the newly added attributes. What happens next is you realize your queries totally ignore your good ol' buddies without the new attributes. Which makes you wanting desperately to bring your schema to order and add the missing columns to all the records of your table so to speak.

Here comes a surprise. You can't really do that easily. What you need to do is to fetch ALL the objects and re-save them. You might have thought that the new columns are there and you can query for something like "myNewColumn == null". No such luck. GAE makes a stark distinction between null and missing columns. Until you explicitly set your newly added columns to null they are non-existent in the eyes of our beloved App Engine.

Back to the show. You need to fetch ALL the objects and re-save them. While not a problem per se, the approach faces a number of technical challenges due to another design feature of App Engine - the limitation on the number of results the query can return and on the duration of a single request. Currently a query is restricted to 1000 results and a single request can't take longer than a certain number of milliseconds. Meaning you have to batch up your work.

Batching up the to-be updated objects can become a non-trivial task and will likely be a one-off solution for every schema update. This is not optimal as what you want is to think once and run everywhere.

If you made it to this point we are on the same page. Now bear with me.

For our batching effort to succeed we need something that we can query reliably to figure out what needs to be updated. To this end we create a special attribute called, say, schemaVersion.

We created schemaVersion attribute for ALL our entities and assign it a default value. From now on all our objects are versioned in a database sense.

Fast forward into the future. Having been in production for a few months we realize we need another attribute on that entity. What do we do?
  1. Add the new attribute to the entity
  2. Increase the default value of schemaVersion
  3. Create a finder method in your DAO tier to retrieve a fixed number of entities whose version number is below current
  4. Create a cron job to retrieve the outdated objects and update them as needed based on their version and the current schema version for the entity in question
Rejoice - you are in control of your database schema again.

The code snippets below illustrate the approach.

In your domain object:

 public class Action implements Serializable {  
@Persistent
private Integer deleted = 0;
@Persistent
private Integer schemaVersion = 1;
}

Somewhere in your DAO layer:

    PersistenceManager pm = PMF.get().getPersistenceManager();  
try {
Query query = pm.newQuery(Action.class);
query.setFilter("schemaVersion < :schemaVersion");
query.setRange(0, 100);
actions.addAll(pm.detachCopyAll((Collection<Action>) query.execute(currentVersion)));
} finally {
DAOUtil.closePM(pm, logger);
}

In your batch job:

    List<Action> actions = actionDAO.findForSchemaUpdate(1);  
for (Action action : actions) {
int currentVersion = action.getSchemaVersion();
switch (currentVersion) {
case 0:
action.setDeleted(0);
default:
break;
}
action.setSchemaVersion(1);
actionDAO.save(action);
}

Thursday, February 11, 2010

Cleaning up Indexes in Google App Engine/Java

This is so peculiar I still can't decide if I should laugh or cry...

In short, if you use GAE Java SDK you can't delete indexes in your App Engine application.

To give you some context, indexes is GAE's only way of executing queries against the data store and a single query can use a maximum of 1 (one) index. For the things to be entertaining there is a free quota of 100 indexes per application. Before you know it the indexes quota goes in the red area on the dashboard and your next deployment fails.

At this point you realize a good deal of the indexes out there are not relevant any more and should be disposed of. You head to the dashboard and verify that it is the case indeed. You look for Delete button. For Remove button. For Purge button. For any button... No such luck. There are no buttons on Datastore Indexes page of GAE Dashboard.

Alright, you think. There must be a utility of some kind to get those darn indexes out of sight. And yes there sure is one! In GAE Python SDK...

This is the hilarious part. You program in Java and you use Python to "vacuum" your indexes. Isn't that intuitive?

This must be one of their April Fools jokes that slipped through the fingers. To remind the fine folks at Google we are not there yet star this issue.

Friday, January 29, 2010

On iPad and Business Opportunity

Like it or not - iPad is there to be unleashed on the consumer in less than 60 days.

Will it outsell its older diminutive cousins? Probably not. Will it sell in quantities? Likely so. Which leaves me wondering what kind of business opportunity lies behind the polish and gloss of Apple's latest brainchild.

iPad has a modestly good screen resolution of 1024 x 768 pixels and sports a screaming-fast browser. All that makes it a good candidate for running web applications. While "native" apps will definitely run better and look nicer on the tablet, the web applications on iPad should be quite usable as compared to the experience on other mobile i devices.

Now imagine you have a web application...

All of a sudden your user base might expand into the segments you'd never thought of as your "customers". Those people are likely going to be less computer-savvy than you might imagine. Yet iPad will make it ridiculously easy for them to access your web application.

The moral? If you are a web application... Look good at 1024 x 768. Be utterly intuitive - no iPad user is going to read the manual.

Thursday, January 14, 2010

Looks Matter. Even If You Are a Smartphone

It must have been the thousandth time I saw a Nexus One ad for the past week. And every singly time I see it I ask myself the same question: why that trackball thingy panel?

Since the first time I saw the phone a few month ago when it was still called HTC Passion I couldn't grasp the grand idea behind the exterior design of the device. It must have been something beyond the design realm that prompted the lower panel. They must have desperately needed that space to ensure proper cooling or something.

One of iPhone appeals is its symmetric design. Somehow Android phone manufacturers at large try to "differentiate" themselves with chins, hips, and other nonsense. Motorola CLIQ comes closest to an eye-pleasing design. If it had decent hardware and software I could have bought it.

Apple figured out the optimal exterior design of a smartphone and Microsoft understands it. That's why Windows Mobile flagship device looks remarkably familiar. When it hits the market, preceded by a monumental marketing push from Redmond, the consumer will go for it.

Google's experimental approach to everything works great with gratis online services. Unless the plan is to give Android phones away, it might make sense to build something that not only works but also looks great. Or just photoshop those ads...

Tuesday, January 12, 2010

Google vs Android Developers

Android SDK 2.1 is out together with a number of questions I'd like to ask.

The first device leveraging the platform was released a week ago. The developers were left in the dark till now. How comes?

This release is yet another manifestation of the lack of well-thought policy over there at Google on what stands behind a version number.

2.1 corresponds to API level 7 ("API level" is an internal SDK version identifier used by Android). It's interesting how 2.0 (API level 6) and 2.0.1 (API level 5) got moved to "Older Platforms" area of the Android developer site while Android 1.6 (API level 4) and 1.5 (API level 3) are still among the "current" platforms.

Is any new Android SDK version going to deprecate it's highest ranked predecessor from now on? With great ancestors 1.5 and 1.6 staying there forever?

Developers need clear version numbering that can be correlated to stability and longevity of the corresponding SDK. Preview and beta versions should be named as such. API-breaking versions should get an incremented minor version number (i.e. 2.o.1 shouldn't have existed, it should have been 2.1.0).

While software versions have been increasingly used for marketing purposes, it's important to remember that they do have a meaning in software engineering.

Here's a painfully true quote of MG Siegler of TechChrunch:
Simply put, iPhone apps, as a whole, are much, much better than Android apps. Maybe that’s because Android apps aren’t quite as mature yet. But I don’t know. The Android Market has been around for over a year now, and the fact that there still isn’t a Twitter app that’s as good as the top five iPhone Twitter apps is a bit odd to me.
Developers are the crucial part of Android ecosystem. Google has some thinking to do. Maybe eventually the horse will be put in front of the cart.

Monday, January 11, 2010

Twitter Lists are Great. Now I Want Twitter Categories

It's been quite a while since Twitter unleashed lists and I'm finding them quite useful for organizing the accounts and people I follow.

TwitHive - an excellent web application for Twitter - has been providing list-like functionality since long before lists came to be. Lists made it a commodity and as it stands now most Twitter clients allow us to access the content we care about naturally via channels.

Which brings us to the current day and makes me think about something very similar to lists but serving a totally different purpose - the ability to split the content I create into separate slices, or categories, so that the people following me can choose either to follow the stream in its entirety or to limit themselves to just a subset of it. In this setup when I configure a new service to auto-post my content to Twitter I'll choose whether I want to post to the "raw" stream or to a particular "category" so that only people following that category of mine will get the update. This way I'll be able to easily separate my lunch-time musings from Android developer tips and such.

Wishful thinking? Sure enough. Yet we all know that Twitter growth has flattened recently and they must be on a desperate search of ways to turn the situation around. Categories might be a step in the right direction.

Friday, January 8, 2010

The Perfect Android Phone

Different people choose Android to be the OS that powers their smartphone for different reasons. My reason is Android provides the best Java implementation in the mobile domain. Forget about Java ME. Android's Java is a real thing that in many respects is on par or better than its desktop counterpart.

Your reason is probably different but you decided to be on the lookout... And found this post talking about my vision of a perfect Android phone.

1. Affordability

Mobile landscape evolves quickly. A smartphone has to be affordable. Affordable to me means less than $200. Enough said.

2. Google Voice and Data-only Plan

I don't mind if the phone's price tag is attached to a contract with a major carrier. The plot is to port my number to Google Voice and run away with a reasonably priced data-only plan.

3. Upgradability

The dictionaries don't know such a term but it's as simple as being able to upgrade your phone to the most recent version of Android. For better or worse Google produces new Android versions at mind-boggling pace and you want to stay on top on that. There are hardware limits to how far you can go with it but you should be able to have a reasonably recent version.

4. A MID (Mobile Internet Device) Will Do

Does it really have to be a phone? Not necessarily. An Android-based tablet a la yet-to-be-announced Dell Streak will do just fine. Tablets typically offer a slightly larger screen (5 inches is a good way of thinking about it) but are still highly pocketable. Due to the larger screen size the on-screen keyboard becomes quite usable and the lack of physical keyboard is less of an issue.

Currently this fine strategy faces a number of obstacles.

1. You can't really port your number to Google Voice (yet).

2. Reasonably priced Android phones are outdated on arrival. I'm going to speculate that Google treats its partners as bad as it treats developers by not providing either with timely information and by frequently changing its plans, conventions, and intents without prior notice.

The moral of the story is that if you are shooting for an Android phone, either as a user or a developer, you'd better look for a future Google-branded device. The odds are you are better off with a MID rather than a phone. If Google happens to plan to offer one that is.

Android will take over the world in about 6 months. I've been saying that for the past year and half.