diff --git a/financius/src/main/java/com/code44/finance/data/db/DBMigration.java b/financius/src/main/java/com/code44/finance/data/db/DBMigration.java index ded25f94..30ba1239 100644 --- a/financius/src/main/java/com/code44/finance/data/db/DBMigration.java +++ b/financius/src/main/java/com/code44/finance/data/db/DBMigration.java @@ -9,12 +9,14 @@ import com.code44.finance.common.model.GroupSeparator; import com.code44.finance.common.model.ModelState; import com.code44.finance.common.model.SymbolPosition; +import com.code44.finance.common.model.TransactionState; import com.code44.finance.common.model.TransactionType; import com.code44.finance.data.model.Account; import com.code44.finance.data.model.Category; import com.code44.finance.data.model.Currency; import com.code44.finance.data.model.SyncState; import com.code44.finance.data.model.Tag; +import com.code44.finance.data.model.Transaction; import java.util.UUID; @@ -41,7 +43,7 @@ public static void upgradeV19(SQLiteDatabase db) { final String tempCurrenciesTable = v19MigrateCurrencies(db); final String tempAccountsTable = v19MigrateAccounts(db, tempCurrenciesTable); final String tempCategoriesTable = v19MigrateCategories(db); - final String tempTransactionsTable = v19MigrateTransactions(db); + final String tempTransactionsTable = v19MigrateTransactions(db, tempAccountsTable, tempCategoriesTable); db.execSQL("drop table " + tempCurrenciesTable); db.execSQL("drop table " + tempAccountsTable); @@ -77,12 +79,12 @@ private static String v19MigrateCurrencies(SQLiteDatabase db) { db.execSQL(Tables.Currencies.createScript()); DBHelper.createIndex(db, Tables.Currencies.ID); - final String[] projection = {tempTableName + "_server_id", tempTableName + "_code", - tempTableName + "_symbol", tempTableName + "_decimals", - tempTableName + "_decimal_separator", tempTableName + "_group_separator", - tempTableName + "_symbol_format", tempTableName + "_is_default", - tempTableName + "_exchange_rate"}; - final String selection = tempTableName + "_delete_state = 0"; + final String[] projection = {oldTableName + "_server_id", oldTableName + "_code", + oldTableName + "_symbol", oldTableName + "_decimals", + oldTableName + "_decimal_separator", oldTableName + "_group_separator", + oldTableName + "_symbol_format", oldTableName + "_is_default", + oldTableName + "_exchange_rate"}; + final String selection = oldTableName + "_delete_state = 0"; final Cursor cursor = db.query(tempTableName, projection, selection, null, null, null, null); if (cursor != null && cursor.moveToFirst()) { final Currency currency = new Currency(); @@ -109,18 +111,18 @@ private static String v19MigrateCurrencies(SQLiteDatabase db) { return tempTableName; } - private static String v19MigrateAccounts(SQLiteDatabase db, String currencyTempTableName) { + private static String v19MigrateAccounts(SQLiteDatabase db, String tempCurrenciesTable) { final String oldTableName = "accounts"; final String tempTableName = "temp_" + oldTableName; db.execSQL("alter table " + oldTableName + " rename to " + tempTableName); db.execSQL(Tables.Accounts.createScript()); DBHelper.createIndex(db, Tables.Accounts.ID); - final String[] projection = {tempTableName + "_server_id", currencyTempTableName + "_server_id", - tempTableName + "_title", tempTableName + "_note", tempTableName + "_show_in_totals"}; - final String selection = tempTableName + "_delete_state = 0 and " + tempTableName + "_origin = 1"; - final String tables = tempTableName + " inner join " + currencyTempTableName + " on " + - currencyTempTableName + "._id=" + tempTableName + "_currency_id"; + final String[] projection = {oldTableName + "_server_id", "currencies_server_id", + oldTableName + "_title", oldTableName + "_note", oldTableName + "_show_in_totals"}; + final String selection = oldTableName + "_delete_state = 0 and " + oldTableName + "_origin = 1"; + final String tables = tempTableName + " inner join " + tempCurrenciesTable + " on " + + tempCurrenciesTable + "._id=" + oldTableName + "_currency_id"; final Cursor cursor = db.query(tables, projection, selection, null, null, null, null); if (cursor != null && cursor.moveToFirst()) { final Currency currency = new Currency(); @@ -148,10 +150,10 @@ private static String v19MigrateCategories(SQLiteDatabase db) { db.execSQL(Tables.Categories.createScript()); DBHelper.createIndex(db, Tables.Categories.ID); - final String[] projection = {tempTableName + "_server_id", tempTableName + "_title", - tempTableName + "_color", tempTableName + "_type", tempTableName + "_order", - tempTableName + "_level"}; - final String selection = tempTableName + "_delete_state = 0 and " + tempTableName + "_origin = 1"; + final String[] projection = {oldTableName + "_server_id", oldTableName + "_title", + oldTableName + "_color", oldTableName + "_type", oldTableName + "_order", + oldTableName + "_level"}; + final String selection = oldTableName + "_delete_state = 0 and " + oldTableName + "_origin = 1"; final Cursor cursor = db.query(tempTableName, projection, selection, null, null, null, null); if (cursor != null && cursor.moveToFirst()) { final Category category = new Category(); @@ -181,14 +183,92 @@ private static String v19MigrateCategories(SQLiteDatabase db) { return tempTableName; } - private static String v19MigrateTransactions(SQLiteDatabase db) { + private static String v19MigrateTransactions(SQLiteDatabase db, String tempAccountsTable, String tempCategoriesTable) { final String oldTableName = "transactions"; final String tempTableName = "temp_" + oldTableName; db.execSQL("alter table " + oldTableName + " rename to " + tempTableName); db.execSQL(Tables.Transactions.createScript()); DBHelper.createIndex(db, Tables.Transactions.ID); - // TODO Migrate + final String tempFromAccountsTable = tempAccountsTable + "_from"; + final String tempToAccountsTable = tempAccountsTable + "_to"; + final String tempChildCategoriesTable = tempCategoriesTable + "_child"; + final String tempParentCategoriesTable = tempCategoriesTable + "_parent"; + final String tables = tempTableName + + " inner join " + tempAccountsTable + " as " + tempFromAccountsTable + " on " + tempFromAccountsTable + "._id=" + oldTableName + "_account_from_id" + + " inner join " + tempAccountsTable + " as " + tempToAccountsTable + " on " + tempToAccountsTable + "._id=" + oldTableName + "_account_to_id" + + " inner join " + tempCategoriesTable + " as " + tempChildCategoriesTable + " on " + tempChildCategoriesTable + "._id=" + oldTableName + "_category_id" + + " left join " + tempCategoriesTable + " as " + tempParentCategoriesTable + " on " + tempParentCategoriesTable + "._id=" + tempChildCategoriesTable + ".categories_parent_id"; + final String[] projection = {oldTableName + "_server_id", oldTableName + "_date", + oldTableName + "_amount", oldTableName + "_exchange_rate", oldTableName + "_note", + oldTableName + "_state", oldTableName + "_show_in_totals", + tempFromAccountsTable + ".accounts_server_id", tempToAccountsTable + ".accounts_server_id", + tempChildCategoriesTable + "._id", tempChildCategoriesTable + ".categories_server_id", + tempChildCategoriesTable + ".categories_level", tempChildCategoriesTable + ".categories_type", + tempParentCategoriesTable + ".categories_server_id"}; + final String selection = oldTableName + "_delete_state = 0"; + + final Cursor cursor = db.query(tables, projection, selection, null, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + final ContentValues values = new ContentValues(); + final Category category = new Category(); + final Account accountFrom = new Account(); + final Account accountTo = new Account(); + final Transaction transaction = new Transaction(); + transaction.setModelState(ModelState.Normal); + transaction.setSyncState(SyncState.None); + + do { + transaction.setId(cursor.getString(0)); + transaction.setDate(cursor.getLong(1)); + transaction.setAmount(Math.round(cursor.getDouble(2) * 100)); + transaction.setExchangeRate(cursor.getDouble(3)); + transaction.setNote(cursor.getString(4)); + transaction.setTransactionState(TransactionState.fromInt(cursor.getInt(5) + 1)); + transaction.setIncludeInReports(cursor.getInt(6) != 0); + + final int categoryType = cursor.getInt(12); + transaction.setTransactionType(categoryType == 0 ? TransactionType.Income : categoryType == 1 ? TransactionType.Expense : TransactionType.Transfer); + + final long categoryId = cursor.getLong(9); + if (categoryId > 3) { + final int level = cursor.getInt(11); + if (level == 1) { + category.setId(cursor.getString(10)); + } else { + category.setTitle(cursor.getString(13)); + values.clear(); + values.put(Tables.TransactionTags.TRANSACTION_ID.getName(), transaction.getId()); + values.put(Tables.TransactionTags.TAG_ID.getName(), cursor.getString(10)); + db.insert(Tables.TransactionTags.TABLE_NAME, null, values); + } + transaction.setCategory(category); + } else { + transaction.setCategory(null); + } + + switch (transaction.getTransactionType()) { + case Expense: + accountFrom.setId(cursor.getString(7)); + transaction.setAccountFrom(accountFrom); + transaction.setAccountTo(null); + break; + case Income: + transaction.setAccountFrom(null); + accountTo.setId(cursor.getString(8)); + transaction.setAccountTo(accountTo); + break; + case Transfer: + accountFrom.setId(cursor.getString(7)); + transaction.setAccountFrom(accountFrom); + accountTo.setId(cursor.getString(8)); + transaction.setAccountTo(accountTo); + break; + } + + db.insert(Tables.Transactions.TABLE_NAME, null, transaction.asValues()); + } while (cursor.moveToNext()); + } return tempTableName; }