Question

I'm building a crossplatform HTML/Javascript app for iOS and Android using PhoneGap and jQueryMobile, and I am upgrading my app with (among others) a few new fields in one table of the local database (localdatabase/websql).

The challenge I want to make sure that when the database is expanded with the new table fields, the existing user data, the user data will not be removed or become locked in an inaccesible older version of the database.

The background: My app has a local database of the user's data (incomes and expenses, plus a few settings). These data need to be persitent, and the way to go, back when I started, was using the HTML5 localDatabase functionality, since that is both persistent, and available for the iOS and Android browsers as well as for most desktop browsers.

I am using a Javascript plugin/library/thingy called persistenceJS to make dealing with the localdb a little easier. But my question is not really specific to persistenceJS.

I am working on a new version of the app, which makes uses of a few new fields in the Settings table. So when these users download the new app and run it, it must test if their Settings table contains this field or not, and if not it must create the field.

How do I do this testing? I see two lines of thought:

  1. Use the database label... that's used in the openDatabase function. This seems to be used by some developers to store a version number. My trouble with this option is I only know how to use openDatabase to, well, open a database (and create a new one if none exists), and run a callback specifically if the database did not yet exist. So if I open the table while specifying something like "v2" in the label, will it create a new table? If so, will it copy the old table's values into the new one?

  2. Check for the existence of the table fields... I could use openDatabase and then test for the existence of the table fields. If they don't, I could add them. The test would be run every time a user opens their app, which seems a little primitive.

By the way: I know webSQL/localDb has been deprecated by the overlords, but it's still my tool and I want to stick to it for now.

Was it helpful?

Solution 2

I'm adding another answer because I've learned more about localDb opendatabase and migrating it.

As a reminder, openDatabase takes these parameters: name - (string) name of the database version label - (string) the version you want to open display label - (string) a pretty useless display name that seems to be used nowhere max size - (int) largest safe size is 5 * 1024 * 1024 newly created -= (function) to be fired if the db did not previously exist

It's wisest to assign the output of openDatabase to a variable. I.e.

myapp.db = openDatabase('mydb','','My database',5*1024*1024,newlyCreatedCallback);

First off, it seems wise to make use of the 'newly created' callback that's available as the fifth argument of openDatabase. It will fire only if there was no database with the parameters you specified. To prevent this callback from firing when your database did already exist, make sure you have the name, display label and maximum size set to exactly the values that were used to first create the database.

The reason to do this is that if the database was first created, you know for sure that you will not need to do any migrations. You can go straight to a function that adds tables and fields. I recommend using persistenceJS, a tool that helps you read and manipulate the local database.

Before calling openDatabase, it's wise to use jQuery to create a custom event 'dbopen' whose handler will execute migrations. This handler can be triggered by two events. The first is the 'newly created' callback we just discussed. The second is a setInterval that you define after call openDatabase. The interval must check for the existence of the myapp.db variable that you assigned the openDatabase output to.

The reason to create the dbopen custom event is that if you added a 'newly created' callback which triggers a whole bunch of events and continues the flow of your code afterwards, you will want a similar process for the 'not newly created' scenario. There is no callback for openDatabase that does this, so you will have to manually detect the creation of the local database and trigger 'dbopen' as soon as it has come into existence.

I use a window.setInterval for this. Make sure that you create the custom 'dbopen' event using jquery's .one() function, which will fire at most once. Otherwise if the database was newly created, you will fire the open event once when the 'newly created' callback fires, and once when the myapp.db variable comes into existence.

OTHER TIPS

I've found the answer here: http://blog.maxaller.name/2010/03/html5-web-sql-database-intro-to-versioning-and-migrations/.

Basically, you just apply the changeVersion method with the old and the new version label. If you didn't have a label, then the old label is "". While relabeling, webSQL quietly applies the new schema to the old database. Which in my case means adding the new fields.

The tutorial I linked to is really awesome (and so is the functionality).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top