RSS Feed
Aug 15

GnuCash Android v1.4.0 release

Posted on Friday, August 15, 2014 in Coding, GnuCash

After more than 3 weeks in beta, GnuCash Android v.1.4.0 has finally been released to production today. Due to the significant architectural changes in this release, it is being made available on a rolling basis. So don’t fret if you don’t see an update notification right away.

GnuCash Android split editor

GnuCash Android split editor

The most significant change in this release is the introduction of split transactions. Each transaction can now have multiple split amounts. This was one of the most requested features and I’m glad it is finally available. Changes have been made to improve the reliability of account imports from GnuCash XML and resilience of database upgrades in future versions.

A summary of other changes in this release include:

  • Feature: Introduced a new Split editor for the creation and editing of splits
  • Feature: Use account-specific labels for CREDIT/DEBIT instead of just generic “debit” and “credit”
  • Feature: Import GnuCash XML files – accounts and transactions only
  • Feature: Back up transactions in an XML format (similar to GnuCash XML) called .gnca (Gnucash Android)
  • Feature: Option for saving opening balances before deleting transactions
  • Improved: Updated processes for moving, creating, exporting, deleting transactions to work with splits
  • Improved: Updated computation of account and transaction balances to be in line with accounting principles
  • Improved: Updated color (red/green) display to match movement in the account, and not a representation of the side of the split

A big thank you to all the beta testers who patiently put the pre-release versions through its paces and reported bugs and suggestions for improvement.

For those who do not use the Play Store to install apps, the properly signed application package can also be downloaded from Github.

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.