Skip to content

Commit ad36fb9

Browse files
committed
Merge pull request #237 from fefe982/dev-db-up67
Rewrite database upgrade (6 to 7) to remove dependence on old db format
2 parents 965ae21 + 3f2a1d1 commit ad36fb9

1 file changed

Lines changed: 89 additions & 19 deletions

File tree

app/src/org/gnucash/android/db/DatabaseHelper.java

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import android.util.Log;
2525
import android.widget.Toast;
2626
import org.gnucash.android.model.AccountType;
27+
import org.gnucash.android.model.Transaction;
2728

2829
import static org.gnucash.android.db.DatabaseSchema.*;
2930

@@ -33,6 +34,7 @@
3334
* @author Ngewi Fet <ngewif@gmail.com>
3435
*
3536
*/
37+
@SuppressWarnings("deprecation")
3638
public class DatabaseHelper extends SQLiteOpenHelper {
3739

3840
/**
@@ -222,27 +224,95 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
222224

223225
if (oldVersion == 6 && newVersion >= DatabaseSchema.SPLITS_DB_VERSION){
224226
Log.i(LOG_TAG, "Upgrading database to version 7");
225-
226-
//for users who do not have double-entry activated, we create imbalance accounts for their splits
227-
//TODO: Enable when we can hide imbalance accounts from user
228-
// List<Currency> currencies = MigrationHelper.getCurrencies(db);
229-
// AccountsDbAdapter accountsDbAdapter = new AccountsDbAdapter(db);
230-
// for (Currency currency : currencies) {
231-
// accountsDbAdapter.getOrCreateImbalanceAccountUID(currency);
232-
// }
233-
227+
db.beginTransaction();
234228
try {
235-
String filepath = MigrationHelper.exportGnucashXML(db);
236-
237-
dropAllDatabaseTables(db);
238-
createDatabaseTables(db);
239-
240-
MigrationHelper.importGnucashXML(db, filepath);
241-
} catch (Exception e){
242-
Toast.makeText(mContext, "Error upgrading database.\n" + e.getMessage(), Toast.LENGTH_LONG).show();
243-
throw new RuntimeException(e);
229+
// backup transaction table
230+
db.execSQL("ALTER TABLE " + TransactionEntry.TABLE_NAME + " RENAME TO " + TransactionEntry.TABLE_NAME + "_bak");
231+
// create new transaction table
232+
db.execSQL("create table " + TransactionEntry.TABLE_NAME + " ("
233+
+ TransactionEntry._ID + " integer primary key autoincrement, "
234+
+ TransactionEntry.COLUMN_UID + " varchar(255) not null, "
235+
+ TransactionEntry.COLUMN_DESCRIPTION + " varchar(255), "
236+
+ TransactionEntry.COLUMN_NOTES + " text, "
237+
+ TransactionEntry.COLUMN_TIMESTAMP + " integer not null, "
238+
+ TransactionEntry.COLUMN_EXPORTED + " tinyint default 0, "
239+
+ TransactionEntry.COLUMN_CURRENCY + " varchar(255) not null, "
240+
+ TransactionEntry.COLUMN_RECURRENCE_PERIOD + " integer default 0, "
241+
+ "UNIQUE (" + TransactionEntry.COLUMN_UID + ") "
242+
+ ");");
243+
// initialize new transaction table wiht data from old table
244+
db.execSQL("INSERT INTO " + TransactionEntry.TABLE_NAME + " ( "
245+
+ TransactionEntry._ID + " , "
246+
+ TransactionEntry.COLUMN_UID + " , "
247+
+ TransactionEntry.COLUMN_DESCRIPTION + " , "
248+
+ TransactionEntry.COLUMN_NOTES + " , "
249+
+ TransactionEntry.COLUMN_TIMESTAMP + " , "
250+
+ TransactionEntry.COLUMN_EXPORTED + " , "
251+
+ TransactionEntry.COLUMN_CURRENCY + " , "
252+
+ TransactionEntry.COLUMN_RECURRENCE_PERIOD + " ) SELECT "
253+
+ TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry._ID + " , "
254+
+ TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_UID + " , "
255+
+ TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_DESCRIPTION + " , "
256+
+ TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_NOTES + " , "
257+
+ TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_TIMESTAMP + " , "
258+
+ TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_EXPORTED + " , "
259+
+ AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_CURRENCY + " , "
260+
+ TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_RECURRENCE_PERIOD
261+
+ " FROM " + TransactionEntry.TABLE_NAME + "_bak , " + AccountEntry.TABLE_NAME
262+
+ " ON " + TransactionEntry.TABLE_NAME + "_bak.account_uid == " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_UID
263+
);
264+
// create split table
265+
db.execSQL("CREATE TABLE " + SplitEntry.TABLE_NAME + " ("
266+
+ SplitEntry._ID + " integer primary key autoincrement, "
267+
+ SplitEntry.COLUMN_UID + " varchar(255) not null, "
268+
+ SplitEntry.COLUMN_MEMO + " text, "
269+
+ SplitEntry.COLUMN_TYPE + " varchar(255) not null, "
270+
+ SplitEntry.COLUMN_AMOUNT + " varchar(255) not null, "
271+
+ SplitEntry.COLUMN_ACCOUNT_UID + " varchar(255) not null, "
272+
+ SplitEntry.COLUMN_TRANSACTION_UID + " varchar(255) not null, "
273+
+ "FOREIGN KEY (" + SplitEntry.COLUMN_ACCOUNT_UID + ") REFERENCES " + AccountEntry.TABLE_NAME + " (" + AccountEntry.COLUMN_UID + "), "
274+
+ "FOREIGN KEY (" + SplitEntry.COLUMN_TRANSACTION_UID + ") REFERENCES " + TransactionEntry.TABLE_NAME + " (" + TransactionEntry.COLUMN_UID + "), "
275+
+ "UNIQUE (" + SplitEntry.COLUMN_UID + ") "
276+
+ ");");
277+
// Initialize split table with data from backup transaction table
278+
// New split table is initialized after the new transaction table as the
279+
// foreign key constraint will stop any data from being inserted
280+
// If new split table is created before the backup is made, the foreign key
281+
// constraint will be rewritten to refer to the backup transaction table
282+
db.execSQL("INSERT INTO " + SplitEntry.TABLE_NAME + " ( "
283+
+ SplitEntry.COLUMN_UID + " , "
284+
+ SplitEntry.COLUMN_TYPE + " , "
285+
+ SplitEntry.COLUMN_AMOUNT + " , "
286+
+ SplitEntry.COLUMN_ACCOUNT_UID + " , "
287+
+ SplitEntry.COLUMN_TRANSACTION_UID + " ) SELECT "
288+
+ "LOWER(HEX(RANDOMBLOB(16))) , "
289+
+ "CASE WHEN " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_TYPE + " IN ( 'CASH' , 'BANK', 'ASSET', 'EXPENSE', 'RECEIVABLE', 'STOCK', 'MUTUAL' ) THEN CASE WHEN "
290+
+ SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'CREDIT' ELSE 'DEBIT' END ELSE CASE WHEN "
291+
+ SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'DEBIT' ELSE 'CREDIT' END END , "
292+
+ "ABS ( " + TransactionEntry.TABLE_NAME + "_bak.amount ) , "
293+
+ TransactionEntry.TABLE_NAME + "_bak.account_uid , "
294+
+ TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_UID
295+
+ " FROM " + TransactionEntry.TABLE_NAME + "_bak , " + AccountEntry.TABLE_NAME
296+
+ " ON " + TransactionEntry.TABLE_NAME + "_bak.account_uid = " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_UID
297+
+ " UNION SELECT "
298+
+ "LOWER(HEX(RANDOMBLOB(16))) AS " + SplitEntry.COLUMN_UID + " , "
299+
+ "CASE WHEN " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_TYPE + " IN ( 'CASH' , 'BANK', 'ASSET', 'EXPENSE', 'RECEIVABLE', 'STOCK', 'MUTUAL' ) THEN CASE WHEN "
300+
+ SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'DEBIT' ELSE 'CREDIT' END ELSE CASE WHEN "
301+
+ SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'CREDIT' ELSE 'DEBIT' END END , "
302+
+ "ABS ( " + TransactionEntry.TABLE_NAME + "_bak.amount ) , "
303+
+ TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " , "
304+
+ TransactionEntry.TABLE_NAME + "_baK." + TransactionEntry.COLUMN_UID
305+
+ " FROM " + TransactionEntry.TABLE_NAME + "_bak , " + AccountEntry.TABLE_NAME
306+
+ " ON " + TransactionEntry.TABLE_NAME + "_bak.account_uid = " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_UID
307+
+ " WHERE " + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " IS NOT NULL"
308+
);
309+
// drop backup transaction table
310+
db.execSQL("DROP TABLE " + TransactionEntry.TABLE_NAME + "_bak");
311+
db.setTransactionSuccessful();
312+
oldVersion = DatabaseSchema.SPLITS_DB_VERSION;
313+
} finally {
314+
db.endTransaction();
244315
}
245-
oldVersion = DatabaseSchema.SPLITS_DB_VERSION;
246316
}
247317
}
248318

0 commit comments

Comments
 (0)