diff --git a/app/src/main/java/tw/tib/financisto/activity/BlotterFragment.java b/app/src/main/java/tw/tib/financisto/activity/BlotterFragment.java index 6a4b78d..1354789 100644 --- a/app/src/main/java/tw/tib/financisto/activity/BlotterFragment.java +++ b/app/src/main/java/tw/tib/financisto/activity/BlotterFragment.java @@ -283,47 +283,35 @@ public void afterTextChanged(Editable editable) { // 123.45 String val = Double.toString(Math.floor(Double.parseDouble(m.group(2)) * 100)); amount = Criteria.or( - Criteria.or( - Criteria.eq(BlotterFilter.FROM_AMOUNT, val), - Criteria.eq(BlotterFilter.FROM_AMOUNT, "-" + val)), - Criteria.or( - Criteria.eq(BlotterFilter.ORIGINAL_FROM_AMOUNT, val), - Criteria.eq(BlotterFilter.ORIGINAL_FROM_AMOUNT, "-" + val))); + Criteria.eq(BlotterFilter.FROM_AMOUNT, val), + Criteria.eq(BlotterFilter.FROM_AMOUNT, "-" + val), + Criteria.eq(BlotterFilter.ORIGINAL_FROM_AMOUNT, val), + Criteria.eq(BlotterFilter.ORIGINAL_FROM_AMOUNT, "-" + val)); } else if (m.group(3) == null) { // >123.45, <123.45 String val = Double.toString(Math.floor(Double.parseDouble(m.group(2)) * 100)); if (m.group(1).equals("<")) { amount = Criteria.or( - Criteria.or( - Criteria.and( - Criteria.lt(BlotterFilter.FROM_AMOUNT, val), - Criteria.gt(BlotterFilter.FROM_AMOUNT, "0")), - Criteria.and( - Criteria.gt(BlotterFilter.FROM_AMOUNT, "-" + val), - Criteria.lt(BlotterFilter.FROM_AMOUNT, "0")) - ), - Criteria.or( - Criteria.and( - Criteria.lt(BlotterFilter.ORIGINAL_FROM_AMOUNT, val), - Criteria.gt(BlotterFilter.ORIGINAL_FROM_AMOUNT, "0")), - Criteria.and( - Criteria.gt(BlotterFilter.ORIGINAL_FROM_AMOUNT, "-" + val), - Criteria.lt(BlotterFilter.ORIGINAL_FROM_AMOUNT, "0")) - ) - ); + Criteria.and( + Criteria.lt(BlotterFilter.FROM_AMOUNT, val), + Criteria.gt(BlotterFilter.FROM_AMOUNT, "0")), + Criteria.and( + Criteria.gt(BlotterFilter.FROM_AMOUNT, "-" + val), + Criteria.lt(BlotterFilter.FROM_AMOUNT, "0")), + Criteria.and( + Criteria.lt(BlotterFilter.ORIGINAL_FROM_AMOUNT, val), + Criteria.gt(BlotterFilter.ORIGINAL_FROM_AMOUNT, "0")), + Criteria.and( + Criteria.gt(BlotterFilter.ORIGINAL_FROM_AMOUNT, "-" + val), + Criteria.lt(BlotterFilter.ORIGINAL_FROM_AMOUNT, "0"))); } else if (m.group(1).equals(">")) { amount = Criteria.or( - Criteria.or( - Criteria.gt(BlotterFilter.FROM_AMOUNT, val), - Criteria.lt(BlotterFilter.FROM_AMOUNT, "-" + val) - ), - Criteria.or( - Criteria.gt(BlotterFilter.ORIGINAL_FROM_AMOUNT, val), - Criteria.lt(BlotterFilter.ORIGINAL_FROM_AMOUNT, "-" + val) - ) - ); + Criteria.gt(BlotterFilter.FROM_AMOUNT, val), + Criteria.lt(BlotterFilter.FROM_AMOUNT, "-" + val), + Criteria.gt(BlotterFilter.ORIGINAL_FROM_AMOUNT, val), + Criteria.lt(BlotterFilter.ORIGINAL_FROM_AMOUNT, "-" + val)); } } else if (m.group(1) == null) { @@ -331,15 +319,10 @@ else if (m.group(1) == null) { String val2 = Double.toString(Math.floor(Double.parseDouble(m.group(2)) * 100)); String val3 = Double.toString(Math.floor(Double.parseDouble(m.group(3)) * 100)); amount = Criteria.or( - Criteria.or( - Criteria.btw(BlotterFilter.FROM_AMOUNT, val2, val3), - Criteria.btw(BlotterFilter.FROM_AMOUNT, "-" + val3, "-" + val2) - ), - Criteria.or( - Criteria.btw(BlotterFilter.ORIGINAL_FROM_AMOUNT, val2, val3), - Criteria.btw(BlotterFilter.ORIGINAL_FROM_AMOUNT, "-" + val3, "-" + val2) - ) - ); + Criteria.btw(BlotterFilter.FROM_AMOUNT, val2, val3), + Criteria.btw(BlotterFilter.FROM_AMOUNT, "-" + val3, "-" + val2), + Criteria.btw(BlotterFilter.ORIGINAL_FROM_AMOUNT, val2, val3), + Criteria.btw(BlotterFilter.ORIGINAL_FROM_AMOUNT, "-" + val3, "-" + val2)); } } if (amount == null) { @@ -696,7 +679,7 @@ protected Cursor createCursor() { } this.lastTxId = db.getLastTransactionId(); long t2 = System.nanoTime(); - Log.d(TAG, "getLastTransactionId() = " + lastTxId + ", " + (t2 - t1) + " ns"); + Log.d(TAG, "getLastTransactionId() = " + lastTxId + ", " + String.format("%,d", (t2 - t1)) + " ns"); long accountId = blotterFilterCopy.getAccountId(); if (accountId != -1) { c = db.getBlotterForAccount(blotterFilterCopy); @@ -704,7 +687,7 @@ protected Cursor createCursor() { c = db.getBlotter(blotterFilterCopy); } c.getCount(); - Log.d(TAG, "createCursor: " + (System.nanoTime() - t1) + " ns"); + Log.d(TAG, "createCursor: " + String.format("%,d", (System.nanoTime() - t1)) + " ns"); return c; } diff --git a/app/src/main/java/tw/tib/financisto/activity/FilterAbstractActivity.java b/app/src/main/java/tw/tib/financisto/activity/FilterAbstractActivity.java index 16c0034..53ab2d9 100644 --- a/app/src/main/java/tw/tib/financisto/activity/FilterAbstractActivity.java +++ b/app/src/main/java/tw/tib/financisto/activity/FilterAbstractActivity.java @@ -246,6 +246,7 @@ protected void updateEntityFromFilter(String filterCriteria @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case R.id.category_pick: case R.id.category_add: diff --git a/app/src/main/java/tw/tib/financisto/filter/Criteria.java b/app/src/main/java/tw/tib/financisto/filter/Criteria.java index 2542347..532fa2a 100644 --- a/app/src/main/java/tw/tib/financisto/filter/Criteria.java +++ b/app/src/main/java/tw/tib/financisto/filter/Criteria.java @@ -9,9 +9,16 @@ package tw.tib.financisto.filter; import android.content.Intent; +import android.util.Log; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; + +import java.util.Arrays; +import java.util.LinkedList; -import tw.tib.financisto.blotter.BlotterFilter; -import tw.tib.financisto.utils.ArrUtils; import tw.tib.financisto.utils.StringUtil; import tw.tib.orb.Expression; import tw.tib.orb.Expressions; @@ -22,6 +29,7 @@ * Date: 12/17/12 9:06 PM */ public class Criteria { + private static final String TAG = "Criteria"; public static Criteria eq(String column, String value) { return new Criteria(column, WhereFilter.Operation.EQ, value); @@ -69,22 +77,42 @@ public static Criteria raw(String text) { return new Criteria("(" + text + ")", WhereFilter.Operation.NOPE); } - public static Criteria or(Criteria a, Criteria b) { - return new OrCriteria(a, b); + public static Criteria or(Criteria... children) { + Log.d(TAG, "Criteria or() children.length=" + children.length); + return new Criteria(children[0].columnName, WhereFilter.Operation.OR, combineValues(children), children); } - public static Criteria and(Criteria a, Criteria b) { - return new AndCriteria(a, b); + public static Criteria and(Criteria... children) { + Log.d(TAG, "Criteria and() children.length=" + children.length); + return new Criteria(children[0].columnName, WhereFilter.Operation.AND, combineValues(children), children); + } + + private static String[] combineValues(Criteria... children) { + LinkedList values = new LinkedList<>(); + for (Criteria c : children) { + values.addAll(Arrays.asList(c.getValues())); + } + String[] ret = new String[values.size()]; + return values.toArray(ret); } public final String columnName; public final WhereFilter.Operation operation; private final String[] values; + private final Criteria[] children; public Criteria(String columnName, WhereFilter.Operation operation, String... values) { this.columnName = columnName; this.operation = operation; this.values = values; + this.children = new Criteria[0]; + } + + public Criteria(String columnName, WhereFilter.Operation operation, String[] values, Criteria... children) { + this.columnName = columnName; + this.operation = operation; + this.values = values; + this.children = children; } public boolean isNull() { @@ -113,39 +141,27 @@ public Expression toWhereExpression() { } public String toStringExtra() { - StringBuilder sb = new StringBuilder(); - sb.append(columnName).append(","); - sb.append(operation.name()).append(","); - String[] values = this.values; - for (int i = 0; i < values.length; i++) { - if (i > 0) { - sb.append(","); - } - sb.append(values[i]); + JsonArray ret = new JsonArray(); + if (this instanceof DateTimeCriteria) { + ret.add(new JsonPrimitive(DateTimeCriteria.TAG)); + } + else { + ret.add(new JsonPrimitive(Criteria.TAG)); } - return sb.toString(); + ret.add(new Gson().toJsonTree(this)); + return ret.toString(); } public static Criteria fromStringExtra(String extra) { - final String[] p = extra.split(";"); - if (p.length == 2) { - return new OrCriteria(fromStringExtra(p[0]), fromStringExtra(p[1])); - } - else if (p.length == 3) { - return new AndCriteria(fromStringExtra(p[0]), fromStringExtra(p[1])); - } + Log.d(TAG, "fromStringExtra: " + extra); - final String[] a = extra.split(","); - final String col = a[0]; - if (BlotterFilter.DATETIME.equals(col)) { - return DateTimeCriteria.fromStringExtra(extra); - } else if (BlotterFilter.CATEGORY_ID.equals(col)) { - return SingleCategoryCriteria.fromStringExtra(extra); - } else { - String[] values = new String[a.length - 2]; - System.arraycopy(a, 2, values, 0, values.length); - return new Criteria(col, WhereFilter.Operation.valueOf(a[1]), values); + JsonArray array = new JsonParser().parse(extra).getAsJsonArray(); + String typeTag = array.get(0).getAsString(); + if (typeTag.equals(DateTimeCriteria.TAG)) { + return new Gson().fromJson(array.get(1), DateTimeCriteria.class); } + + return new Gson().fromJson(array.get(1), Criteria.class); } public String[] getValues() { @@ -169,6 +185,15 @@ public long getLongValue2() { } public String getSelection() { + if (operation == WhereFilter.Operation.AND || operation == WhereFilter.Operation.OR) + { + String[] childSelection = new String[children.length]; + for (int i = 0; i< children.length; ++i) { + childSelection[i] = children[i].getSelection(); + } + return "(" + String.join(" " + operation.getOp(0) + " ", childSelection) + ")"; + } + String exp = columnName + " " + operation.getOp(getSelectionArgs().length); if (operation.getGroupOp() != null && getValues().length > operation.getValsPerGroup()) { int groupNum = getValues().length / operation.getValsPerGroup(); @@ -183,6 +208,15 @@ public int size() { } public String[] getSelectionArgs() { + if (children.length > 0) { + LinkedList args = new LinkedList<>(); + for (Criteria c : children) { + args.addAll(Arrays.asList(c.getSelectionArgs())); + } + String[] ret = new String[args.size()]; + ret = args.toArray(ret); + return ret; + } return values; } @@ -190,49 +224,5 @@ public void toIntent(String title, Intent intent) { intent.putExtra(WhereFilter.TITLE_EXTRA, title); intent.putExtra(WhereFilter.FILTER_EXTRA, new String[]{toStringExtra()}); } - - static class OrCriteria extends Criteria { - Criteria a, b; - - public OrCriteria(Criteria a, Criteria b) { - super(a.columnName, a.operation, ArrUtils.joinArrays(a.getValues(), b.getValues())); - this.a = a; - this.b = b; - } - - @Override - public String getSelection() { - return "(" + a.getSelection() + " OR " + b.getSelection() + ")"; - } - - @Override - public String toStringExtra() { - StringBuilder sb = new StringBuilder(); - sb.append(a.toStringExtra()).append(";").append(b.toStringExtra()); - return sb.toString(); - } - } - - static class AndCriteria extends Criteria { - Criteria a, b; - - public AndCriteria(Criteria a, Criteria b) { - super(a.columnName, a.operation, ArrUtils.joinArrays(a.getValues(), b.getValues())); - this.a = a; - this.b = b; - } - - @Override - public String getSelection() { - return "(" + a.getSelection() + " AND " + b.getSelection() + ")"; - } - - @Override - public String toStringExtra() { - StringBuilder sb = new StringBuilder(); - sb.append(a.toStringExtra()).append(";").append(b.toStringExtra()).append(";"); - return sb.toString(); - } - } } diff --git a/app/src/main/java/tw/tib/financisto/filter/DateTimeCriteria.java b/app/src/main/java/tw/tib/financisto/filter/DateTimeCriteria.java index b370f6a..4375c54 100644 --- a/app/src/main/java/tw/tib/financisto/filter/DateTimeCriteria.java +++ b/app/src/main/java/tw/tib/financisto/filter/DateTimeCriteria.java @@ -21,29 +21,7 @@ * Date: 12/17/12 9:06 PM */ public class DateTimeCriteria extends Criteria { - - public static final long START_OF_ERA; - public static final long END_OF_ERA; - - static { - Calendar c = Calendar.getInstance(); - c.set(Calendar.YEAR, 1970); - c.set(Calendar.MONTH, 1); - c.set(Calendar.DAY_OF_MONTH, 1); - c.set(Calendar.HOUR_OF_DAY, 0); - c.set(Calendar.MINUTE, 0); - c.set(Calendar.SECOND, 0); - c.set(Calendar.MILLISECOND, 0); - START_OF_ERA = c.getTimeInMillis(); - c.set(Calendar.YEAR, 2025); - c.set(Calendar.MONTH, 12); - c.set(Calendar.DAY_OF_MONTH, 31); - c.set(Calendar.HOUR_OF_DAY, 23); - c.set(Calendar.MINUTE, 59); - c.set(Calendar.SECOND, 59); - c.set(Calendar.MILLISECOND, 999); - END_OF_ERA = c.getTimeInMillis(); - } + public static final String TAG = "DateTimeCriteria"; private final Period period; @@ -60,43 +38,6 @@ public DateTimeCriteria(long start, long end) { this(new Period(PeriodType.CUSTOM, start, end)); } - public String toStringExtra() { - StringBuilder sb = new StringBuilder(); - sb.append(BlotterFilter.DATETIME).append(",#,"); - sb.append(period.type.name()); - if (period.isCustom()) { - sb.append(","); - sb.append(period.start).append(","); - sb.append(period.end); - } - return sb.toString(); - } - - public static Criteria fromStringExtra(String extra) { - String[] a = extra.split(","); - if ("#".equals(a[1])) { - // new format support - PeriodType period = PeriodType.valueOf(a[2]); - if (period == PeriodType.CUSTOM) { - return new DateTimeCriteria(new Period(PeriodType.CUSTOM, Long.parseLong(a[3]), Long.parseLong(a[4]))); - } else { - return new DateTimeCriteria(DateUtils.getPeriod(period)); - } - } else { - // legacy support - WhereFilter.Operation op = WhereFilter.Operation.valueOf(a[1]); - if (op == WhereFilter.Operation.GTE) { - return new DateTimeCriteria(new Period(PeriodType.CUSTOM, Long.parseLong(a[2]), END_OF_ERA)); - } else if (op == WhereFilter.Operation.LTE) { - return new DateTimeCriteria(new Period(PeriodType.CUSTOM, START_OF_ERA, Long.parseLong(a[2]))); - } else if (a.length > 3) { - return new DateTimeCriteria(new Period(PeriodType.CUSTOM, Long.parseLong(a[2]), Long.parseLong(a[3]))); - } else { - return new DateTimeCriteria(DateUtils.getPeriod(PeriodType.THIS_MONTH)); - } - } - } - public Period getPeriod() { return period; } diff --git a/app/src/main/java/tw/tib/financisto/filter/SingleCategoryCriteria.java b/app/src/main/java/tw/tib/financisto/filter/SingleCategoryCriteria.java deleted file mode 100644 index c42eb43..0000000 --- a/app/src/main/java/tw/tib/financisto/filter/SingleCategoryCriteria.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2013 Denis Solonenko. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the GNU Public License v2.0 - * which accompanies this distribution, and is available at - * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html - */ - -package tw.tib.financisto.filter; - -import tw.tib.financisto.blotter.BlotterFilter; - -/** -* Created by IntelliJ IDEA. -* User: denis.solonenko -* Date: 12/17/12 9:06 PM -*/ -public class SingleCategoryCriteria extends Criteria { - - private final long categoryId; - - public SingleCategoryCriteria(long categoryId) { - super(BlotterFilter.CATEGORY_ID, WhereFilter.Operation.EQ, String.valueOf(categoryId)); - this.categoryId = categoryId; - } - - public String toStringExtra() { - StringBuilder sb = new StringBuilder(); - sb.append(BlotterFilter.CATEGORY_ID).append(",EQ,") - .append(categoryId); - return sb.toString(); - } - - public static Criteria fromStringExtra(String extra) { - String[] a = extra.split(","); - return new SingleCategoryCriteria(Long.parseLong(a[2])); - } - - public long getCategoryId() { - return categoryId; - } - -} diff --git a/app/src/main/java/tw/tib/financisto/filter/WhereFilter.java b/app/src/main/java/tw/tib/financisto/filter/WhereFilter.java index fb3d5a8..b681585 100644 --- a/app/src/main/java/tw/tib/financisto/filter/WhereFilter.java +++ b/app/src/main/java/tw/tib/financisto/filter/WhereFilter.java @@ -32,6 +32,7 @@ import static tw.tib.orb.EntityManager.DEF_SORT_COL; public class WhereFilter { + private static final String TAG = "WhereFilter"; public static final String TITLE_EXTRA = "title"; public static final String FILTER_EXTRA = "filter"; @@ -112,7 +113,10 @@ public synchronized WhereFilter contains(String column, String text){ private String getSelection(List criterias) { StringBuilder sb = new StringBuilder(); + Log.d(TAG, "getSelection:"); for (Criteria c : criterias) { + Log.d(TAG, " " + c.toStringExtra()); + Log.d(TAG, " " + String.join(", ", c.getSelection())); if (sb.length() > 0) { sb.append(" AND "); } @@ -123,7 +127,10 @@ private String getSelection(List criterias) { private String[] getSelectionArgs(List criterias) { String[] args = new String[0]; + Log.d(TAG, "getSelectionArgs:"); for (Criteria c : criterias) { + Log.d(TAG, " " + c.toStringExtra()); + Log.d(TAG, " " + String.join(", ", c.getSelectionArgs())); args = ArrUtils.joinArrays(args, c.getSelectionArgs()); } return args; @@ -197,6 +204,7 @@ public synchronized void toBundle(Bundle bundle) { String[] extras = new String[criterias.size()]; for (int i=0; i 0) { - filter.sorts.addAll(Arrays.asList(orders)); + String sortOrder = bundle.getString(SORT_ORDER_EXTRA); + if (sortOrder != null) { + String[] orders = sortOrder.split(","); + if (orders != null && orders.length > 0) { + filter.sorts.addAll(Arrays.asList(orders)); + } } } + } catch (Exception e) { + Log.e(TAG, "fromBundle", e); + return WhereFilter.empty(); } return filter; } @@ -267,21 +280,26 @@ public synchronized void toSharedPreferences(SharedPreferences preferences) { public static WhereFilter fromSharedPreferences(SharedPreferences preferences) { String title = preferences.getString(FILTER_TITLE_PREF, ""); WhereFilter filter = new WhereFilter(title); - synchronized (filter) { - int count = preferences.getInt(FILTER_LENGTH_PREF, 0); - if (count > 0) { - for (int i = 0; i < count; i++) { - String criteria = preferences.getString(FILTER_CRITERIA_PREF + i, ""); - if (criteria.length() > 0) { - filter.put(Criteria.fromStringExtra(criteria)); + try { + synchronized (filter) { + int count = preferences.getInt(FILTER_LENGTH_PREF, 0); + if (count > 0) { + for (int i = 0; i < count; i++) { + String criteria = preferences.getString(FILTER_CRITERIA_PREF + i, ""); + if (criteria.length() > 0) { + filter.put(Criteria.fromStringExtra(criteria)); + } } } + String sortOrder = preferences.getString(FILTER_SORT_ORDER_PREF, ""); + String[] orders = sortOrder.split(","); + if (orders != null && orders.length > 0) { + filter.sorts.addAll(Arrays.asList(orders)); + } } - String sortOrder = preferences.getString(FILTER_SORT_ORDER_PREF, ""); - String[] orders = sortOrder.split(","); - if (orders != null && orders.length > 0) { - filter.sorts.addAll(Arrays.asList(orders)); - } + } catch (Exception e) { + Log.e(TAG, "fromSharedPreferences", e); + return WhereFilter.empty(); } return filter; } @@ -339,7 +357,7 @@ public String getOp(int operands) { return super.getOp(operands).replace("?", StringUtil.generateSeparated("?", ",", operands)); } }, - ISNULL("is NULL"), LIKE("LIKE ?"); + ISNULL("is NULL"), LIKE("LIKE ?"), OR("OR"), AND("AND"); private final String op; private final String groupOp;