X-Git-Url: https://git.ktnx.net/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fmodel%2FMobileLedgerProfile.java;h=8cdc9c914e00bd8b312093752d1725abcd70125d;hb=7c71910950d18868e1f419eed5234f113ee51776;hp=15be74b6be1c572ba9c4e65d4a94e84dab2bfcbd;hpb=2de3d8a8c96e78f4ab89880be9fab05735acc910;p=mobile-ledger.git diff --git a/app/src/main/java/net/ktnx/mobileledger/model/MobileLedgerProfile.java b/app/src/main/java/net/ktnx/mobileledger/model/MobileLedgerProfile.java index 15be74b6..8cdc9c91 100644 --- a/app/src/main/java/net/ktnx/mobileledger/model/MobileLedgerProfile.java +++ b/app/src/main/java/net/ktnx/mobileledger/model/MobileLedgerProfile.java @@ -22,15 +22,25 @@ import android.content.Intent; import android.content.res.Resources; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.os.AsyncTask; import android.os.Bundle; -import android.text.TextUtils; import android.util.SparseArray; import androidx.annotation.Nullable; +import androidx.room.Transaction; import net.ktnx.mobileledger.App; import net.ktnx.mobileledger.R; import net.ktnx.mobileledger.async.DbOpQueue; +import net.ktnx.mobileledger.dao.AccountDAO; +import net.ktnx.mobileledger.dao.DescriptionHistoryDAO; +import net.ktnx.mobileledger.dao.OptionDAO; +import net.ktnx.mobileledger.dao.ProfileDAO; +import net.ktnx.mobileledger.dao.TransactionDAO; +import net.ktnx.mobileledger.db.AccountValue; +import net.ktnx.mobileledger.db.AccountWithAmounts; +import net.ktnx.mobileledger.db.DB; +import net.ktnx.mobileledger.db.Profile; import net.ktnx.mobileledger.json.API; import net.ktnx.mobileledger.ui.profiles.ProfileDetailActivity; import net.ktnx.mobileledger.ui.profiles.ProfileDetailFragment; @@ -43,7 +53,6 @@ import org.jetbrains.annotations.Contract; import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Objects; @@ -154,7 +163,7 @@ public final class MobileLedgerProfile { try { int orderNo = 0; for (MobileLedgerProfile p : Objects.requireNonNull(Data.profiles.getValue())) { - db.execSQL("update profiles set order_no=? where uuid=?", + db.execSQL("update profiles set order_no=? where id=?", new Object[]{orderNo, p.getId()}); p.orderNo = orderNo; orderNo++; @@ -176,6 +185,26 @@ public final class MobileLedgerProfile { intent.putExtras(args); context.startActivity(intent, args); } + public static MobileLedgerProfile fromDBO(Profile newProfile) { + MobileLedgerProfile p = new MobileLedgerProfile(newProfile.getId()); + p.setDetectedVersion(new HledgerVersion(newProfile.getDetectedVersionMajor(), + newProfile.getDetectedVersionMinor())); + p.setApiVersion(newProfile.getApiVersion()); + p.setAuthEnabled(newProfile.useAuthentication()); + p.setAuthUserName(newProfile.getAuthUser()); + p.setAuthPassword(newProfile.getAuthPassword()); + p.setDefaultCommodity(newProfile.getDefaultCommodity()); + p.setFutureDates(newProfile.getFutureDates()); + p.setName(newProfile.getName()); + p.setPostingPermitted(newProfile.permitPosting()); + p.setPreferredAccountsFilter(newProfile.getPreferredAccountsFilter()); + p.setShowCommentsByDefault(newProfile.getShowCommentsByDefault()); + p.setShowCommodityByDefault(newProfile.getShowCommodityByDefault()); + p.setUrl(newProfile.getUrl()); + p.setThemeId(newProfile.getTheme()); + + return p; + } public HledgerVersion getDetectedVersion() { return detectedVersion; } @@ -378,49 +407,6 @@ public final class MobileLedgerProfile { }); // debug("accounts", String.format("Stored account '%s' in DB [%s]", acc.getName(), uuid)); } - public void storeAccountValue(SQLiteDatabase db, int generation, String name, String currency, - Float amount) { - if (!TextUtils.isEmpty(currency)) { - boolean exists; - try (Cursor c = db.rawQuery("select 1 from currencies where name=?", - new String[]{currency})) - { - exists = c.moveToFirst(); - } - if (!exists) { - db.execSQL( - "insert into currencies(id, name, position, has_gap) values((select max" + - "(id) from currencies)+1, ?, ?, ?)", new Object[]{currency, - Objects.requireNonNull( - Data.currencySymbolPosition.getValue()).toString(), - Data.currencyGap.getValue() - }); - } - } - - long accId = findAddAccount(db, name); - - db.execSQL("replace into account_values(account_id, " + - "currency, value, generation) values(?, ?, ?, ?);", - new Object[]{accId, Misc.emptyIsNull(currency), amount, generation}); - } - private long findAddAccount(SQLiteDatabase db, String accountName) { - try (Cursor c = db.rawQuery("select id from accounts where profile_id=? and name=?", - new String[]{String.valueOf(id), accountName})) - { - if (c.moveToFirst()) - return c.getLong(0); - - } - - try (Cursor c = db.rawQuery( - "insert into accounts(profile_id, name, name_upper) values(?, ?, ?) returning id", - new String[]{String.valueOf(id), accountName, accountName.toUpperCase()})) - { - c.moveToFirst(); - return c.getInt(0); - } - } public void storeTransaction(SQLiteDatabase db, int generation, LedgerTransaction tr) { tr.fillDataHash(); // Logger.debug("storeTransaction", String.format(Locale.US, "ID %d", tr.getId())); @@ -449,7 +435,7 @@ public final class MobileLedgerProfile { }); db.execSQL("INSERT INTO transaction_accounts(transaction_id, " + "order_no, account_name, amount, currency, comment, generation) " + - "select ?, ?, ?, ?, ?, ?, ?, ? WHERE (select changes() = 0)", + "select ?, ?, ?, ?, ?, ?, ? WHERE (select changes() = 0)", new Object[]{tr.getId(), accountOrderNo, item.getAccountName(), item.getAmount(), Misc.nullIsEmpty(item.getCurrency()), item.getComment(), generation @@ -514,20 +500,9 @@ public final class MobileLedgerProfile { setOption(name, String.valueOf(value)); } public void removeFromDB() { - SQLiteDatabase db = App.getDatabase(); - debug("db", String.format(Locale.ROOT, "removing profile %d from DB", id)); - db.beginTransactionNonExclusive(); - try { - Object[] id_param = new Object[]{id}; - db.execSQL("delete from transactions where profile_id=?", id_param); - db.execSQL("delete from accounts where profile=?", id_param); - db.execSQL("delete from options where profile=?", id_param); - db.execSQL("delete from profiles where id=?", id_param); - db.setTransactionSuccessful(); - } - finally { - db.endTransaction(); - } + ProfileDAO dao = DB.get() + .getProfileDAO(); + AsyncTask.execute(() -> dao.deleteSync(dao.getByIdSync(id))); } public LedgerTransaction loadTransaction(int transactionId) { LedgerTransaction tr = new LedgerTransaction(transactionId, this.id); @@ -547,60 +522,45 @@ public final class MobileLedgerProfile { this.themeHue = themeHue; } public int getNextTransactionsGeneration(SQLiteDatabase db) { - int generation = 1; try (Cursor c = db.rawQuery( "SELECT generation FROM transactions WHERE profile_id=? LIMIT 1", new String[]{String.valueOf(id)})) { - if (c.moveToFirst()) { - generation = c.getInt(0) + 1; - } - } - return generation; - } - private int getNextAccountsGeneration(SQLiteDatabase db) { - int generation = 1; - try (Cursor c = db.rawQuery("SELECT generation FROM accounts WHERE profile_id=? LIMIT 1", - new String[]{String.valueOf(id)})) - { - if (c.moveToFirst()) { - generation = c.getInt(0) + 1; - } + if (c.moveToFirst()) + return c.getInt(0) + 1; } - return generation; - } - private void deleteNotPresentAccounts(SQLiteDatabase db, int generation) { - Logger.debug("db/benchmark", "Deleting obsolete accounts"); - db.execSQL("DELETE FROM account_values WHERE profile=? AND generation <> ?", - new Object[]{id, generation}); - db.execSQL("DELETE FROM accounts WHERE profile=? AND generation <> ?", - new Object[]{id, generation}); - Logger.debug("db/benchmark", "Done deleting obsolete accounts"); + return 1; } private void deleteNotPresentTransactions(SQLiteDatabase db, int generation) { Logger.debug("db/benchmark", "Deleting obsolete transactions"); - db.execSQL("DELETE FROM transaction_accounts WHERE profile=? AND generation <> ?", + db.execSQL( + "DELETE FROM transaction_accounts WHERE (select t.profile_id from transactions t " + + "where t.id=transaction_accounts.transaction_id)=? AND generation" + " <> ?", new Object[]{id, generation}); - db.execSQL("DELETE FROM transactions WHERE profile=? AND generation <> ?", + db.execSQL("DELETE FROM transactions WHERE profile_id=? AND generation <> ?", new Object[]{id, generation}); Logger.debug("db/benchmark", "Done deleting obsolete transactions"); } + @Transaction + public void wipeAllDataSync() { + OptionDAO optDao = DB.get() + .getOptionDAO(); + optDao.deleteSync(optDao.allForProfileSync(id)); + + AccountDAO accDao = DB.get() + .getAccountDAO(); + accDao.deleteSync(accDao.allForProfileSync(id)); + + TransactionDAO trnDao = DB.get() + .getTransactionDAO(); + trnDao.deleteSync(trnDao.allForProfileSync(id)); + + DescriptionHistoryDAO descDao = DB.get() + .getDescriptionHistoryDAO(); + descDao.sweepSync(); + } public void wipeAllData() { - SQLiteDatabase db = App.getDatabase(); - db.beginTransaction(); - try { - String[] pUuid = new String[]{String.valueOf(id)}; - db.execSQL("delete from options where profile=?", pUuid); - db.execSQL("delete from accounts where profile=?", pUuid); - db.execSQL("delete from account_values where profile=?", pUuid); - db.execSQL("delete from transactions where profile=?", pUuid); - db.execSQL("delete from transaction_accounts where profile=?", pUuid); - db.setTransactionSuccessful(); - debug("wipe", String.format(Locale.ENGLISH, "Profile %s wiped out", pUuid[0])); - } - finally { - db.endTransaction(); - } + AsyncTask.execute(this::wipeAllDataSync); } public List getCurrencies() { SQLiteDatabase db = App.getDatabase(); @@ -746,26 +706,10 @@ public final class MobileLedgerProfile { SQLiteDatabase db = App.getDatabase(); db.beginTransactionNonExclusive(); try { - int accountsGeneration = profile.getNextAccountsGeneration(db); - if (isInterrupted()) - return; - int transactionsGeneration = profile.getNextTransactionsGeneration(db); if (isInterrupted()) return; - for (LedgerAccount acc : accounts) { - profile.storeAccount(db, accountsGeneration, acc, false); - if (isInterrupted()) - return; - for (LedgerAmount amt : acc.getAmounts()) { - profile.storeAccountValue(db, accountsGeneration, acc.getName(), - amt.getCurrency(), amt.getAmount()); - if (isInterrupted()) - return; - } - } - for (LedgerTransaction tr : transactions) { profile.storeTransaction(db, transactionsGeneration, tr); if (isInterrupted()) @@ -776,9 +720,6 @@ public final class MobileLedgerProfile { if (isInterrupted()) { return; } - profile.deleteNotPresentAccounts(db, accountsGeneration); - if (isInterrupted()) - return; Map unique = new HashMap<>(); @@ -805,6 +746,37 @@ public final class MobileLedgerProfile { finally { db.endTransaction(); } + + AsyncTask.execute(() -> { + List list = new ArrayList<>(); + + final AccountDAO dao = DB.get() + .getAccountDAO(); + + for (LedgerAccount acc : accounts) { + AccountWithAmounts rec = new AccountWithAmounts(); + rec.account = acc.toDBO(); + + if (isInterrupted()) + return; + + rec.amounts = new ArrayList<>(); + for (LedgerAmount amt : acc.getAmounts()) { + AccountValue av = new AccountValue(); + av.setCurrency(amt.getCurrency()); + av.setValue(amt.getAmount()); + + rec.amounts.add(av); + } + + list.add(rec); + } + + if (isInterrupted()) + return; + + dao.storeAccountsSync(list, profile.getId()); + }); } private void storeDescription(SQLiteDatabase db, int generation, String description, String descriptionUpper) {