RSS Feed
Feb 14

On Upgrading your Android App Database

Posted on Friday, February 14, 2014 in Coding

GnuCash Android has come a long way since it’s first release and in that time, lot of changes have been made to the database schema. Android has a special mechanism for this in the onUpgrade() method which is called when the database version number changes. Up until version 1.2.7, GnuCash had this method implemented as follows:

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (oldVersion < newVersion){
        Log.i(TAG, "Upgrading database to version " + newVersion);
        if (oldVersion == 1 && newVersion == 2){
            //execute upgrade queries
        }
        if (oldVersion == 2 && newVersion == 3){
            //execute database upgrade queries
        }
    }
}

Can you spot the problem? Go ahead, take your time, I’ll wait. Most of it is the common boilerplate you’d expect: checking that the database operation is actually an upgrade, logging, etc.
But then come the important lines…let’s take another look:

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (oldVersion < newVersion){
        Log.i(TAG, "Upgrading database to version " + newVersion);
        if (oldVersion == 1 &amp;&amp; newVersion == 2){
            //execute upgrade queries
        }
        if (oldVersion == 2 && newVersion == 3){
            //execute database upgrade queries
        }
    }
}

Whenever a user skips an upgrade and then tries to upgrade at a later version, then none of the if statements will ever be true. Hence no database upgrade will be performed. This can lead to all manner of headaches for the user due to an inconsistent database schema. Mea maxima culpa!

It has been possible for this error to go undetected for this long because, I guess, most users accept the updates they are proposed or even allow the Play Store to automatically upgrade the apps. But for the small percentage of users who skip an upgrade, well, that would be the beginning of trouble. The typical way to solve this would be to uninstall and reinstall the application, which is not ideal.

While this was going on, Navneet Karnani created a patch which was meant to add another feature to the app, but which included a fix for the database issue.
The database upgrade code should look like this:

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    if (oldVersion < newVersion){
        Log.i(TAG, "Upgrading database to version " + newVersion);
        if (oldVersion == 1 && newVersion >= 2){
            //execute upgrade queries
            oldVersion = 2;
        }
        if (oldVersion == 2 && newVersion >= 3){
            //execute database upgrade queries
            oldVersion = 3;
        }
    }
}

There is a small but very significant difference in the code.
First, we check whether the new database version is greater than or less than what we expect. Also, and very crucially, we update the oldVersion variable to the next version after performing the upgrades to the old version. This ensures that if we are upgrading over several database versions, then all the upgrade steps for the intermediate versions will also be performed.

It is also possible to implement the database upgrade method as switch statements. I’ll leave that as an exercise to you.

The next version of GnuCash Android (v1.3.1) is currently available in the Google Play Store and includes these changes which should improve stability.

Feb 10

GnuCash Android v1.3.0 released

Posted on Monday, February 10, 2014 in Coding, GnuCash

Just a public service announcement to the effect that version 1.3.0 of GnuCash for Android has been released to the Google Play Store.
This version includes numerous changes, including, but not limited to the following:

  • Mark favorite accounts and quickly access them
  • Display different tabs for recent, favorite and all accounts
  • Add, view and delete recurring transactions (daily, weekly, monthly)
  • Mark accounts as placeholder accounts (cannot contain transactions)
  • Set a default transfer account for each account
  • Color code accounts and themed account views
  • Create default GnuCash account structure from within app
  • Numerous bug fixes and improvements

For the full change log, visit the GitHub repository

Thanks to all who contributed in this release and the translators who dutifully put up with me bugging them for string updates.

Work on the next version will commence soon and I am excited for what is coming next.

Enjoy the release!

P.S. If you don’t see it in the Play Store yet, give it some time 😉

Dec 10

Announcing QIF support in GnuCash Android

Posted on Tuesday, December 10, 2013 in Coding

Its been a long while since I last posted here. That’s partly due to the fact that the GnuCash Android releases which have been made since the last post have largely been announced on Google+, and they were mainly bug fixes etc.

When GnuCash Android was first released about a year ago, it came with support for exporting transactions in the OFX (Open Financial eXchange) format. However, there was still a lot of pain when importing into GnuCash desktop. Transactions were not automatically assigned to the corresponding GnuCash accounts, double-entry transactions were not supported, amongst other things.

Since then GnuCash Android has added support for importing the account structure from GnuCash desktop and also supporting different GnuCash account types, as opposed to only OFX account types. But OFX never really made it easy to import transactions.

qif_export_dialogAs from today, support for QIF (Quicken Interchange Format) export has been added and will be the default export format going forward. There were some for whom OFX worked fine, and the option for OFX export is still there. So if you already have a process that works for you, you can stick to it.

But for everyone else, QIF is the new black. 

There is also another important change included in this release, and that is the nomenclature and interpretation of CREDIT/DEBIT transactions. GnuCash Android did not originally support different account types, and CREDIT/DEBIT always meant increase/decrease of the account balance respectively. This has not always been very accurate with respect to the accounting principles used in GnuCash Android.

From version 1.2.6, CREDITs decrease the balance of Asset and Expense accounts, while DEBITs correspondingly increase the balance. This would make sense to long time GnuCash Android users, but may be totally unintuitive for those unused to the principle.

The combination of QIF and correct CREDIT/DEBIT accounting should make for a very seamless process of exporting transactions and importing them into GnuCash for desktop.

I hope you enjoy this release, and as always, I am looking forward to your feedback.