Skip to content

Commit

Permalink
rewrite Criteria serialization with Gson
Browse files Browse the repository at this point in the history
  • Loading branch information
tiberiusteng committed Jan 11, 2024
1 parent 1ce47dc commit e5aa8db
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 247 deletions.
69 changes: 26 additions & 43 deletions app/src/main/java/tw/tib/financisto/activity/BlotterFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -283,63 +283,46 @@ 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) {
// 100~900
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) {
Expand Down Expand Up @@ -696,15 +679,15 @@ 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);
} else {
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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ protected <T extends MyEntity> 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:
Expand Down
144 changes: 67 additions & 77 deletions app/src/main/java/tw/tib/financisto/filter/Criteria.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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<String> 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() {
Expand Down Expand Up @@ -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() {
Expand All @@ -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();
Expand All @@ -183,56 +208,21 @@ public int size() {
}

public String[] getSelectionArgs() {
if (children.length > 0) {
LinkedList<String> 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;
}

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();
}
}

}
61 changes: 1 addition & 60 deletions app/src/main/java/tw/tib/financisto/filter/DateTimeCriteria.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
}
Expand Down
Loading

0 comments on commit e5aa8db

Please sign in to comment.