X-Git-Url: https://git.ktnx.net/?p=mobile-ledger.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fasync%2FRetrieveTransactionsTask.java;h=b8a341344fb478ab5d5202173c02a1b257e26923;hp=63b30b5c0a9467d71163d062ee866bb7ff6c6c05;hb=0bbdc409d82da31324c031f36607510f17d992e6;hpb=70c486fbea2d6606f68d35fceedc90680fd13f7f diff --git a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java index 63b30b5c..b8a34134 100644 --- a/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java +++ b/app/src/main/java/net/ktnx/mobileledger/async/RetrieveTransactionsTask.java @@ -18,16 +18,15 @@ package net.ktnx.mobileledger.async; import android.annotation.SuppressLint; -import android.content.Context; import android.content.SharedPreferences; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import android.util.Log; import net.ktnx.mobileledger.R; -import net.ktnx.mobileledger.TransactionListActivity; import net.ktnx.mobileledger.model.LedgerTransaction; -import net.ktnx.mobileledger.model.LedgerTransactionItem; +import net.ktnx.mobileledger.model.LedgerTransactionAccount; +import net.ktnx.mobileledger.ui.transaction_list.TransactionListFragment; import net.ktnx.mobileledger.utils.MLDB; import net.ktnx.mobileledger.utils.NetworkUtil; @@ -39,6 +38,7 @@ import java.io.InputStreamReader; import java.lang.ref.WeakReference; import java.net.HttpURLConnection; import java.net.MalformedURLException; +import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -50,66 +50,74 @@ public class RetrieveTransactionsTask extends private static final Pattern transactionDescriptionPattern = Pattern.compile(" contextRef; + protected WeakReference contextRef; protected int error; private boolean success; - public RetrieveTransactionsTask(WeakReference contextRef) { + public RetrieveTransactionsTask(WeakReference contextRef) { this.contextRef = contextRef; } private static final void L(String msg) { - Log.d("transaction-parser", msg); +// Log.d("transaction-parser", msg); } @Override protected void onProgressUpdate(Progress... values) { super.onProgressUpdate(values); - TransactionListActivity context = getContext(); + TransactionListFragment context = getContext(); if (context == null) return; context.onRetrieveProgress(values[0]); } @Override protected void onPreExecute() { super.onPreExecute(); - TransactionListActivity context = getContext(); + TransactionListFragment context = getContext(); if (context == null) return; context.onRetrieveStart(); } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); - TransactionListActivity context = getContext(); + TransactionListFragment context = getContext(); if (context == null) return; context.onRetrieveDone(success); } + @Override + protected void onCancelled() { + super.onCancelled(); + TransactionListFragment context = getContext(); + if (context == null) return; + context.onRetrieveDone(false); + } @SuppressLint("DefaultLocale") @Override protected Void doInBackground(Params... params) { Progress progress = new Progress(); + int maxTransactionId = Progress.INDETERMINATE; success = false; try { HttpURLConnection http = NetworkUtil.prepare_connection(params[0].getBackendPref(), "journal"); http.setAllowUserInteraction(false); publishProgress(progress); - Context ctx = contextRef.get(); + TransactionListFragment ctx = getContext(); if (ctx == null) return null; - try (SQLiteDatabase db = MLDB.getWritableDatabase(ctx)) { + try (SQLiteDatabase db = MLDB.getWritableDatabase(ctx.getActivity())) { try (InputStream resp = http.getInputStream()) { if (http.getResponseCode() != 200) throw new IOException( String.format("HTTP error %d", http.getResponseCode())); db.beginTransaction(); try { - db.execSQL("DELETE FROM transactions;"); - db.execSQL("DELETE FROM transaction_accounts"); + db.execSQL("UPDATE transactions set keep=0"); int state = ParserState.EXPECTING_JOURNAL; String line; BufferedReader buf = new BufferedReader(new InputStreamReader(resp, "UTF-8")); - int transactionCount = 0; + int processedTransactionCount = 0; int transactionId = 0; + int matchedTransactionsCount = 0; LedgerTransaction transaction = null; LINES: while ((line = buf.readLine()) != null) { @@ -133,8 +141,11 @@ public class RetrieveTransactionsTask extends L(String.format( "found transaction %d → expecting " + "description", transactionId)); - progress.setProgress(++transactionCount); - if (progress.getTotal() == Progress.INDETERMINATE) + progress.setProgress(++processedTransactionCount); + if (maxTransactionId < transactionId) + maxTransactionId = transactionId; + if ((progress.getTotal() == Progress.INDETERMINATE) || + (progress.getTotal() < transactionId)) progress.setTotal(transactionId); publishProgress(progress); } @@ -166,7 +177,31 @@ public class RetrieveTransactionsTask extends case ParserState.EXPECTING_TRANSACTION_DETAILS: if (line.isEmpty()) { // transaction data collected - transaction.insertInto(db); + if (transaction.existsInDb(db)) { + db.execSQL("UPDATE transactions SET keep = 1 WHERE id" + + "=?", new Integer[]{transaction.getId()}); + matchedTransactionsCount++; + + if (matchedTransactionsCount == 100) { + db.execSQL("UPDATE transactions SET keep=1 WHERE " + + "id < ?", + new Integer[]{transaction.getId()}); + success = true; + progress.setTotal(progress.getProgress()); + publishProgress(progress); + break LINES; + } + } + else { + db.execSQL("DELETE from transactions WHERE id=?", + new Integer[]{transaction.getId()}); + db.execSQL("DELETE from transaction_accounts WHERE " + + "transaction_id=?", + new Integer[]{transaction.getId()}); + transaction.insertInto(db); + matchedTransactionsCount = 0; + progress.setTotal(maxTransactionId); + } state = ParserState.EXPECTING_TRANSACTION; L(String.format( @@ -186,27 +221,40 @@ public class RetrieveTransactionsTask extends if (m.find()) { String acc_name = m.group(1); String amount = m.group(2); + String currency = m.group(3); amount = amount.replace(',', '.'); - transaction.add_item(new LedgerTransactionItem(acc_name, - Float.valueOf(amount))); + transaction.addAccount( + new LedgerTransactionAccount(acc_name, + Float.valueOf(amount), currency)); L(String.format("%s = %s", acc_name, amount)); } else throw new IllegalStateException( - String.format("Can't parse transaction details")); + String.format("Can't parse transaction %d details", + transactionId)); } break; default: throw new RuntimeException( - String.format("Unknown " + "parser state %d", state)); + String.format("Unknown parser state %d", state)); } } - if (!isCancelled()) db.setTransactionSuccessful(); + if (!isCancelled()) { + db.execSQL("DELETE FROM transactions WHERE keep = 0"); + db.setTransactionSuccessful(); + } } finally { db.endTransaction(); } } } + + if (success && !isCancelled()) { + Log.d("db", "Updating transaction list stamp"); + MLDB.set_option_value(ctx.getActivity(), MLDB.OPT_TRANSACTION_LIST_STAMP, + new Date().getTime()); + ctx.model.reloadTransactions(ctx); + } } catch (MalformedURLException e) { error = R.string.err_bad_backend_url; @@ -222,38 +270,19 @@ public class RetrieveTransactionsTask extends } return null; } - TransactionListActivity getContext() { + TransactionListFragment getContext() { return contextRef.get(); } public static class Params { - static final int DEFAULT_LIMIT = 100; private SharedPreferences backendPref; - private String accountsRoot; - private int limit; public Params(SharedPreferences backendPref) { this.backendPref = backendPref; - this.accountsRoot = null; - this.limit = DEFAULT_LIMIT; - } - Params(SharedPreferences backendPref, String accountsRoot) { - this(backendPref, accountsRoot, DEFAULT_LIMIT); - } - Params(SharedPreferences backendPref, String accountsRoot, int limit) { - this.backendPref = backendPref; - this.accountsRoot = accountsRoot; - this.limit = limit; - } - String getAccountsRoot() { - return accountsRoot; } SharedPreferences getBackendPref() { return backendPref; } - int getLimit() { - return limit; - } } public class Progress {