diff --git a/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java b/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java index ef0ffb01f..a69dc5155 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/ApkProvider.java @@ -488,10 +488,10 @@ public class ApkProvider extends FDroidProvider { for (final String field : projection) { queryBuilder.addField(field); } - queryBuilder.addSelection(query.getSelection()); + queryBuilder.addSelection(query); queryBuilder.addOrderBy(sortOrder); - Cursor cursor = db().rawQuery(queryBuilder.toString(), query.getArgs()); + Cursor cursor = db().rawQuery(queryBuilder.toString(), queryBuilder.getArgs()); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } diff --git a/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java b/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java index f67803ecf..396c6cf63 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java +++ b/app/src/main/java/org/fdroid/fdroid/data/AppProvider.java @@ -317,7 +317,7 @@ public class AppProvider extends FDroidProvider { } public void addSelection(AppQuerySelection selection) { - addSelection(selection.getSelection()); + super.addSelection(selection); if (selection.naturalJoinToInstalled()) { naturalJoinToInstalledTable(); } @@ -828,12 +828,11 @@ public class AppProvider extends FDroidProvider { } Query query = new Query(); - query.addSelection(selection); query.addFields(projection); // TODO: Make the order of addFields/addSelection not dependent on each other... query.addOrderBy(sortOrder); - Cursor cursor = db().rawQuery(query.toString(), selection.getArgs()); + Cursor cursor = db().rawQuery(query.toString(), query.getArgs()); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } diff --git a/app/src/main/java/org/fdroid/fdroid/data/OrderClause.java b/app/src/main/java/org/fdroid/fdroid/data/OrderClause.java new file mode 100644 index 000000000..eb888f4cf --- /dev/null +++ b/app/src/main/java/org/fdroid/fdroid/data/OrderClause.java @@ -0,0 +1,25 @@ +package org.fdroid.fdroid.data; + +public class OrderClause { + + public final String expression; + private String[] args; + + public OrderClause(String expression) { + this.expression = expression; + } + + public OrderClause(String field, String[] args, boolean isAscending) { + this.expression = field + " " + (isAscending ? "ASC" : "DESC"); + this.args = args; + } + + @Override + public String toString() { + return expression; + } + + public String[] getArgs() { + return args; + } +} \ No newline at end of file diff --git a/app/src/main/java/org/fdroid/fdroid/data/QueryBuilder.java b/app/src/main/java/org/fdroid/fdroid/data/QueryBuilder.java index 862fcf859..ac1584a28 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/QueryBuilder.java +++ b/app/src/main/java/org/fdroid/fdroid/data/QueryBuilder.java @@ -1,5 +1,8 @@ package org.fdroid.fdroid.data; +import android.support.annotation.Nullable; +import android.text.TextUtils; + import java.util.ArrayList; import java.util.List; @@ -8,7 +11,8 @@ abstract class QueryBuilder { private final List fields = new ArrayList<>(); private final StringBuilder tables = new StringBuilder(getRequiredTables()); private String selection; - private String orderBy; + private String[] selectionArgs; + private final List orderBys = new ArrayList<>(); protected abstract String getRequiredTables(); @@ -58,12 +62,51 @@ abstract class QueryBuilder { fields.add(fieldBuilder.toString()); } - public void addSelection(String selection) { - this.selection = selection; + public void addSelection(@Nullable QuerySelection selection) { + if (selection == null) { + this.selection = null; + this.selectionArgs = null; + } else { + this.selection = selection.getSelection(); + this.selectionArgs = selection.getArgs(); + } } + /** + * Add an order by, which includes an expression and optionally ASC or DESC afterward. + */ public void addOrderBy(String orderBy) { - this.orderBy = orderBy; + if (orderBy != null) { + orderBys.add(new OrderClause(orderBy)); + } + } + + public void addOrderBy(@Nullable OrderClause orderClause) { + if (orderClause != null) { + orderBys.add(orderClause); + } + } + + public String[] getArgs() { + List args = new ArrayList<>(); + + if (selectionArgs != null) { + for (String arg : selectionArgs) { + args.add(arg); + } + } + + for (OrderClause orderBy : orderBys) { + if (orderBy.getArgs() != null) { + for (String arg : orderBy.getArgs()) { + args.add(arg); + } + } + } + + String[] strings = new String[args.size()]; + args.toArray(strings); + return strings; } protected final void leftJoin(String table, String alias, String condition) { @@ -94,14 +137,7 @@ abstract class QueryBuilder { } private String fieldsSql() { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < fields.size(); i++) { - if (i > 0) { - sb.append(','); - } - sb.append(fields.get(i)); - } - return sb.toString(); + return TextUtils.join(", ", fields); } private String whereSql() { @@ -109,7 +145,11 @@ abstract class QueryBuilder { } private String orderBySql() { - return orderBy != null ? " ORDER BY " + orderBy : ""; + if (orderBys.size() == 0) { + return ""; + } else { + return " ORDER BY " + TextUtils.join(", ", orderBys); + } } private String groupBySql() { diff --git a/app/src/main/java/org/fdroid/fdroid/data/QuerySelection.java b/app/src/main/java/org/fdroid/fdroid/data/QuerySelection.java index c6f7a9631..b7a37ca51 100644 --- a/app/src/main/java/org/fdroid/fdroid/data/QuerySelection.java +++ b/app/src/main/java/org/fdroid/fdroid/data/QuerySelection.java @@ -19,7 +19,7 @@ public class QuerySelection { public QuerySelection(String selection) { this.selection = selection; - this.args = null; + this.args = new String[] {}; } public QuerySelection(String selection, String[] args) {