Convert sql package to Kotlin

pull/996/head
Alex Baker 4 years ago
parent 71721f982a
commit 3841a16607

@ -1,143 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.data;
import static org.tasks.Strings.isNullOrEmpty;
import com.todoroo.andlib.sql.Field;
/**
* Property represents a typed column in a database.
*
* <p>Within a given database row, the parameter may not exist, in which case the value is null, it
* may be of an incorrect type, in which case an exception is thrown, or the correct type, in which
* case the value is returned.
*
* @param <TYPE> a database supported type, such as String or Integer
* @author Tim Su <tim@todoroo.com>
*/
public abstract class Property<TYPE> extends Field implements Cloneable {
// --- implementation
/** The database column name for this property */
public final String name;
/** The database table name this property */
private final Table table;
/**
* Create a property by table and column name. Uses the default property expression which is
* derived from default table name
*/
Property(Table table, String columnName) {
this(table, columnName, (table == null) ? (columnName) : (table.name() + "." + columnName));
}
/** Create a property by table and column name, manually specifying an expression to use in SQL */
Property(Table table, String columnName, String expression) {
super(expression);
this.table = table;
this.name = columnName;
}
/** Return a clone of this property */
@Override
public Property<TYPE> clone() {
try {
return (Property<TYPE>) super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
/** Return a clone of this property */
Property<TYPE> cloneAs(String tableAlias, String columnAlias) {
Table aliasedTable = this.table;
if (!isNullOrEmpty(tableAlias)) {
aliasedTable = table.as(tableAlias);
}
try {
Property<TYPE> newInstance =
this.getClass()
.getConstructor(Table.class, String.class)
.newInstance(aliasedTable, this.name);
if (!isNullOrEmpty(columnAlias)) {
return (Property<TYPE>) newInstance.as(columnAlias);
}
return newInstance;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* Integer property type. See {@link Property}
*
* @author Tim Su <tim@todoroo.com>
*/
public static class IntegerProperty extends Property<Integer> {
public IntegerProperty(Table table, String name) {
super(table, name);
}
IntegerProperty(String name, String expression) {
super(null, name, expression);
}
@Override
public IntegerProperty as(String newAlias) {
return (IntegerProperty) super.as(newAlias);
}
}
/**
* String property type. See {@link Property}
*
* @author Tim Su <tim@todoroo.com>
*/
public static class StringProperty extends Property<String> {
public StringProperty(Table table, String name) {
super(table, name);
}
@Override
public StringProperty as(String newAlias) {
return (StringProperty) super.as(newAlias);
}
}
/**
* Long property type. See {@link Property}
*
* @author Tim Su <tim@todoroo.com>
*/
public static class LongProperty extends Property<Long> {
public LongProperty(Table table, String name) {
super(table, name);
}
@Override
public LongProperty cloneAs(String tableAlias, String columnAlias) {
return (LongProperty) super.cloneAs(tableAlias, columnAlias);
}
}
// --- pseudo-properties
/** Runs a SQL function and returns the result as a string */
public static class CountProperty extends IntegerProperty {
public CountProperty() {
super("count", "COUNT(1)");
alias = "count";
}
}
}

@ -0,0 +1,8 @@
package com.todoroo.andlib.data
import com.todoroo.andlib.sql.Field
class Property internal constructor(@JvmField val name: String?, expression: String) : Field(expression) {
constructor(table: Table, columnName: String) : this(columnName, "${table.name()}.$columnName")
}

@ -1,51 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.data;
import com.todoroo.andlib.sql.SqlTable;
/**
* Table class. Most fields are final, so methods such as <code>as</code> will clone the table when
* it returns.
*
* @author Tim Su <tim@todoroo.com>
*/
public final class Table extends SqlTable {
private final String name;
public Table(String name) {
this(name, null);
}
private Table(String name, String alias) {
super(name);
this.name = name;
this.alias = alias;
}
/** Create a new join table based on this table, but with an alias */
@Override
public Table as(String newAlias) {
return new Table(name, newAlias);
}
@Override
public String toString() {
if (hasAlias()) {
return expression + " AS " + alias; // $NON-NLS-1$
}
return expression;
}
public String name() {
if (hasAlias()) {
return alias;
}
return name;
}
}

@ -0,0 +1,20 @@
package com.todoroo.andlib.data
import com.todoroo.andlib.sql.DBObject
class Table private constructor(private val name: String, alias: String?) : DBObject<Table>(name) {
constructor(name: String) : this(name, null)
fun column(column: String): Property = Property(this, column)
override fun `as`(newAlias: String) = Table(name, newAlias)
override fun toString(): String = alias?.let { "$expression AS $alias" } ?: expression
fun name() = alias ?: name
init {
this.alias = alias
}
}

@ -1,58 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.AND;
import static com.todoroo.andlib.sql.SqlConstants.LEFT_PARENTHESIS;
import static com.todoroo.andlib.sql.SqlConstants.OR;
import static com.todoroo.andlib.sql.SqlConstants.RIGHT_PARENTHESIS;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
public abstract class Criterion {
final Operator operator;
public Criterion(Operator operator) {
this.operator = operator;
}
public static Criterion and(final Criterion criterion, final Criterion... criterions) {
return new Criterion(Operator.and) {
@Override
protected void populate(StringBuilder sb) {
sb.append(criterion);
for (Criterion c : criterions) {
sb.append(SPACE).append(AND).append(SPACE).append(c);
}
}
};
}
public static Criterion or(final Criterion criterion, final Criterion... criterions) {
return new Criterion(Operator.or) {
@Override
protected void populate(StringBuilder sb) {
sb.append(criterion);
for (Criterion c : criterions) {
sb.append(SPACE).append(OR).append(SPACE).append(c.toString());
}
}
};
}
protected abstract void populate(StringBuilder sb);
@Override
public String toString() {
StringBuilder builder = new StringBuilder(LEFT_PARENTHESIS);
populate(builder);
builder.append(RIGHT_PARENTHESIS);
return builder.toString();
}
}

@ -0,0 +1,31 @@
package com.todoroo.andlib.sql
abstract class Criterion(val operator: Operator) {
protected abstract fun populate(): String
override fun toString() = "(${populate()})"
companion object {
@JvmStatic fun and(criterion: Criterion?, vararg criterions: Criterion?): Criterion {
return object : Criterion(Operator.and) {
override fun populate() = criterion.plus(criterions).joinToString(" AND ")
}
}
@JvmStatic fun or(criterion: Criterion?, vararg criterions: Criterion): Criterion {
return object : Criterion(Operator.or) {
override fun populate() = criterion.plus(criterions).joinToString(" OR ")
}
}
operator fun <T> T.plus(tail: Array<out T>): List<T> {
val list = ArrayList<T>(1 + tail.size)
list.add(this)
list.addAll(tail)
return list
}
}
}

@ -1,74 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.AS;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
import java.util.Objects;
public abstract class DBObject<T extends DBObject<?>> implements Cloneable {
protected final String expression;
protected String alias;
DBObject(String expression) {
this.expression = expression;
}
public T as(String newAlias) {
try {
T clone = (T) clone();
clone.alias = newAlias;
return clone;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
protected boolean hasAlias() {
return alias != null;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof DBObject)) {
return false;
}
DBObject<?> dbObject = (DBObject<?>) o;
return Objects.equals(expression, dbObject.expression) && Objects.equals(alias, dbObject.alias);
}
@Override
public int hashCode() {
return Objects.hash(expression, alias);
}
@Override
public String toString() {
if (hasAlias()) {
return alias;
}
return expression;
}
public final String toStringInSelect() {
StringBuilder sb = new StringBuilder(expression);
if (hasAlias()) {
sb.append(SPACE).append(AS).append(SPACE).append(alias);
} else {
int pos = expression.indexOf('.');
if (pos > 0 && !expression.endsWith("*")) {
sb.append(SPACE).append(AS).append(SPACE).append(expression.substring(pos + 1));
}
}
return sb.toString();
}
}

@ -0,0 +1,33 @@
package com.todoroo.andlib.sql
import java.util.*
abstract class DBObject<T : DBObject<T>> internal constructor(@JvmField val expression: String) : Cloneable {
@JvmField var alias: String? = null
open fun `as`(newAlias: String): T {
return try {
val clone = clone() as T
clone.alias = newAlias
clone
} catch (e: CloneNotSupportedException) {
throw RuntimeException(e)
}
}
protected fun hasAlias() = alias != null
override fun equals(other: Any?): Boolean {
if (this === other) {
return true
}
if (other !is DBObject<*>) {
return false
}
return expression == other.expression && alias == other.alias
}
override fun hashCode() = Objects.hash(expression, alias)
override fun toString() = alias ?: expression
}

@ -1,85 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.LEFT_PARENTHESIS;
import static com.todoroo.andlib.sql.SqlConstants.RIGHT_PARENTHESIS;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
import com.google.common.base.Joiner;
import java.util.List;
public class Field extends DBObject<Field> {
protected Field(String expression) {
super(expression);
}
public static Field field(String expression) {
return new Field(expression);
}
public Criterion eq(Object value) {
if (value == null) {
return UnaryCriterion.isNull(this);
}
return UnaryCriterion.eq(this, value);
}
public Criterion gt(Object value) {
return UnaryCriterion.gt(this, value);
}
public Criterion gte(Object value) {
return UnaryCriterion.gte(this, value);
}
public Criterion lt(final Object value) {
return UnaryCriterion.lt(this, value);
}
public Criterion lte(final Object value) {
return UnaryCriterion.lte(this, value);
}
public Criterion like(final String value) {
return UnaryCriterion.like(this, value);
}
public Criterion in(final Query query) {
final Field field = this;
return new Criterion(Operator.in) {
@Override
protected void populate(StringBuilder sb) {
sb.append(field)
.append(SPACE)
.append(Operator.in)
.append(SPACE)
.append(LEFT_PARENTHESIS)
.append(query)
.append(RIGHT_PARENTHESIS);
}
};
}
public <T> Criterion in(List<T> entries) {
final Field field = this;
return new Criterion(Operator.in) {
@Override
protected void populate(StringBuilder sb) {
sb.append(field)
.append(SPACE)
.append(Operator.in)
.append(SPACE)
.append(LEFT_PARENTHESIS)
.append(Joiner.on(",").join(entries))
.append(RIGHT_PARENTHESIS);
}
};
}
}

@ -0,0 +1,51 @@
package com.todoroo.andlib.sql
open class Field(expression: String) : DBObject<Field>(expression) {
fun eq(value: Any?): Criterion = if (value == null) {
UnaryCriterion.isNull(this)
} else {
UnaryCriterion.eq(this, value)
}
fun gt(value: Any?): Criterion = UnaryCriterion.gt(this, value)
fun gte(value: Any?): Criterion = UnaryCriterion.gte(this, value)
fun lt(value: Any?): Criterion = UnaryCriterion.lt(this, value)
fun lte(value: Any?): Criterion = UnaryCriterion.lte(this, value)
fun like(value: String?): Criterion = UnaryCriterion.like(this, value)
fun `in`(query: Query?): Criterion {
val field = this
return object : Criterion(Operator.`in`) {
override fun populate() = "$field IN ($query)"
}
}
fun `in`(entries: List<*>): Criterion {
val field = this
return object : Criterion(Operator.`in`) {
override fun populate() = "$field IN (${entries.joinToString(",")})"
}
}
fun toStringInSelect(): String {
val sb = StringBuilder(expression)
if (hasAlias()) {
sb.append(" AS $alias")
} else {
val pos = expression.indexOf('.')
if (pos > 0 && !expression.endsWith("*")) {
sb.append(" AS ${expression.substring(pos + 1)}")
}
}
return sb.toString()
}
companion object {
@JvmStatic fun field(expression: String): Field = Field(expression)
@JvmStatic val COUNT = Field("COUNT(*)")
}
}

@ -1,19 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public final class Functions {
public static Field upper(Field title) {
return new Field("UPPER(" + title.toString() + ")");
}
/** @return SQL now (in milliseconds) */
public static Field now() {
return new Field("(strftime('%s','now')*1000)");
}
}

@ -0,0 +1,7 @@
package com.todoroo.andlib.sql
object Functions {
@JvmStatic fun upper(title: Field): Field = Field("UPPER($title)")
@JvmStatic fun now(): Field = Field("(strftime('%s','now')*1000)")
}

@ -1,55 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.AND;
import static com.todoroo.andlib.sql.SqlConstants.JOIN;
import static com.todoroo.andlib.sql.SqlConstants.ON;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
public class Join {
private final SqlTable joinTable;
private final JoinType joinType;
private final Criterion[] criterions;
private Join(SqlTable table, JoinType joinType, Criterion... criterions) {
joinTable = table;
this.joinType = joinType;
this.criterions = criterions;
}
public static Join inner(SqlTable expression, Criterion... criterions) {
return new Join(expression, JoinType.INNER, criterions);
}
public static Join left(SqlTable table, Criterion... criterions) {
return new Join(table, JoinType.LEFT, criterions);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(joinType)
.append(SPACE)
.append(JOIN)
.append(SPACE)
.append(joinTable)
.append(SPACE)
.append(ON)
.append(SPACE)
.append("(");
for (int i = 0; i < criterions.length; i++) {
sb.append(criterions[i]);
if (i < criterions.length - 1) {
sb.append(SPACE).append(AND).append(SPACE);
}
}
sb.append(")");
return sb.toString();
}
}

@ -0,0 +1,20 @@
package com.todoroo.andlib.sql
import com.todoroo.andlib.data.Table
class Join private constructor(private val joinTable: Table, private val joinType: JoinType, criterions: List<Criterion>) { private val criterions = criterions.toList()
override fun toString() = "$joinType JOIN $joinTable ON (${criterions.joinToString(" AND ")})"
companion object {
@JvmStatic
fun inner(expression: Table, vararg criterions: Criterion?): Join {
return Join(expression, JoinType.INNER, criterions.filterNotNull())
}
@JvmStatic
fun left(table: Table, vararg criterions: Criterion?): Join {
return Join(table, JoinType.LEFT, criterions.filterNotNull())
}
}
}

@ -1,12 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public enum JoinType {
INNER,
LEFT
}

@ -0,0 +1,5 @@
package com.todoroo.andlib.sql
enum class JoinType {
INNER, LEFT
}

@ -1,32 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public final class Operator {
public static final Operator eq = new Operator("=");
public static final Operator isNull = new Operator("IS NULL");
public static final Operator and = new Operator("AND");
public static final Operator or = new Operator("OR");
public static final Operator not = new Operator("NOT");
public static final Operator like = new Operator("LIKE");
public static final Operator in = new Operator("IN");
static final Operator gt = new Operator(">");
static final Operator gte = new Operator(">=");
static final Operator lt = new Operator("<");
static final Operator lte = new Operator("<=");
private final String operator;
private Operator(String operator) {
this.operator = operator;
}
@Override
public String toString() {
return this.operator;
}
}

@ -0,0 +1,19 @@
package com.todoroo.andlib.sql
class Operator private constructor(private val operator: String) {
override fun toString() = operator
companion object {
val eq = Operator("=")
val isNull = Operator("IS NULL")
val and = Operator("AND")
val or = Operator("OR")
val not = Operator("NOT")
val like = Operator("LIKE")
val `in` = Operator("IN")
val gt = Operator(">")
val gte = Operator(">=")
val lt = Operator("<")
val lte = Operator("<=")
}
}

@ -1,61 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
import java.util.ArrayList;
import java.util.List;
public class Order {
private final Object expression;
private final List<Order> secondaryExpressions;
private final OrderType orderType;
private Order(Object expression) {
this(expression, OrderType.ASC);
}
private Order(Object expression, OrderType orderType) {
this.expression = expression;
this.orderType = orderType;
this.secondaryExpressions = new ArrayList<>();
}
public static Order asc(Object expression) {
return new Order(expression);
}
public static Order desc(Object expression) {
return new Order(expression, OrderType.DESC);
}
public void addSecondaryExpression(Order secondary) {
secondaryExpressions.add(secondary);
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(expression.toString()).append(SPACE).append(orderType.toString());
for (Order secondary : secondaryExpressions) {
sb.append(", ").append(secondary.toString()); // $NON-NLS-1$
}
return sb.toString();
}
public Order reverse() {
if (orderType == OrderType.ASC) {
return new Order(expression, OrderType.DESC);
} else {
return new Order(expression, OrderType.ASC);
}
}
}

@ -0,0 +1,26 @@
package com.todoroo.andlib.sql
import com.todoroo.andlib.sql.OrderType.ASC
import com.todoroo.andlib.sql.OrderType.DESC
import java.util.*
class Order private constructor(private val expression: Any, private val orderType: OrderType = ASC) {
private val secondaryExpressions = ArrayList<Order>()
fun addSecondaryExpression(secondary: Order) {
secondaryExpressions.add(secondary)
}
override fun toString() =
"$expression $orderType${secondaryExpressions.takeIf { it.isNotEmpty() }?.joinToString(", ", ", ") ?: ""}"
fun reverse() = Order(expression, if (orderType === ASC) DESC else ASC)
companion object {
@JvmStatic
fun asc(expression: Any) = Order(expression)
@JvmStatic
fun desc(expression: Any) = Order(expression, DESC)
}
}

@ -1,12 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public enum OrderType {
DESC,
ASC
}

@ -0,0 +1,5 @@
package com.todoroo.andlib.sql
enum class OrderType {
DESC, ASC
}

@ -1,121 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.ALL;
import static com.todoroo.andlib.sql.SqlConstants.COMMA;
import static com.todoroo.andlib.sql.SqlConstants.FROM;
import static com.todoroo.andlib.sql.SqlConstants.SELECT;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
import static com.todoroo.andlib.sql.SqlConstants.WHERE;
import static java.util.Arrays.asList;
import java.util.ArrayList;
public final class Query {
private final ArrayList<Criterion> criterions = new ArrayList<>();
private final ArrayList<Field> fields = new ArrayList<>();
private final ArrayList<Join> joins = new ArrayList<>();
private SqlTable table;
private String queryTemplate = null;
private Query(Field... fields) {
this.fields.addAll(asList(fields));
}
public static Query select(Field... fields) {
return new Query(fields);
}
public Query from(SqlTable fromTable) {
this.table = fromTable;
return this;
}
public Query join(Join... join) {
joins.addAll(asList(join));
return this;
}
public Query where(Criterion criterion) {
criterions.add(criterion);
return this;
}
@Override
public boolean equals(Object o) {
return this == o
|| !(o == null || getClass() != o.getClass()) && this.toString().equals(o.toString());
}
@Override
public int hashCode() {
return toString().hashCode();
}
@Override
public String toString() {
StringBuilder sql = new StringBuilder();
visitSelectClause(sql);
visitFromClause(sql);
visitJoinClause(sql);
if (queryTemplate == null) {
visitWhereClause(sql);
} else {
sql.append(queryTemplate);
}
return sql.toString();
}
private void visitWhereClause(StringBuilder sql) {
if (criterions.isEmpty()) {
return;
}
sql.append(WHERE);
for (Criterion criterion : criterions) {
sql.append(SPACE).append(criterion).append(SPACE);
}
}
private void visitJoinClause(StringBuilder sql) {
for (Join join : joins) {
sql.append(join).append(SPACE);
}
}
private void visitFromClause(StringBuilder sql) {
if (table == null) {
return;
}
sql.append(FROM).append(SPACE).append(table).append(SPACE);
}
private void visitSelectClause(StringBuilder sql) {
sql.append(SELECT).append(SPACE);
if (fields.isEmpty()) {
sql.append(ALL).append(SPACE);
return;
}
for (Field field : fields) {
sql.append(field.toStringInSelect()).append(COMMA);
}
sql.deleteCharAt(sql.length() - 1).append(SPACE);
}
/**
* Add the SQL query template (comes after the "from")
*
* @return query
*/
public Query withQueryTemplate(String template) {
queryTemplate = template;
return this;
}
}

@ -0,0 +1,63 @@
package com.todoroo.andlib.sql
import com.todoroo.andlib.data.Table
import com.todoroo.andlib.sql.StringBuilderExtensions.from
import com.todoroo.andlib.sql.StringBuilderExtensions.join
import com.todoroo.andlib.sql.StringBuilderExtensions.select
import com.todoroo.andlib.sql.StringBuilderExtensions.where
import java.util.*
class Query private constructor(vararg fields: Field?) {
private val criterions = ArrayList<Criterion>()
private val fields = ArrayList<Field>().apply { addAll(fields.filterNotNull()) }
private val joins = ArrayList<Join>()
private var table: Table? = null
private var queryTemplate: String? = null
fun from(fromTable: Table?): Query {
table = fromTable
return this
}
fun join(vararg join: Join): Query {
joins.addAll(join)
return this
}
fun where(criterion: Criterion): Query {
criterions.add(criterion)
return this
}
override fun equals(other: Any?): Boolean {
return this === other
|| !(other == null || javaClass != other.javaClass) && this.toString() == other.toString()
}
override fun hashCode() = toString().hashCode()
override fun toString(): String {
val sql = StringBuilder()
.select(fields)
.from(table)
.join(joins)
if (queryTemplate == null) {
sql.where(criterions)
} else {
sql.append(queryTemplate)
}
return sql.toString()
}
fun withQueryTemplate(template: String?): Query {
queryTemplate = template
return this
}
companion object {
@JvmStatic
fun select(vararg fields: Field?): Query {
return Query(*fields)
}
}
}

@ -1,78 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.COMMA;
import static com.todoroo.andlib.sql.SqlConstants.ORDER_BY;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
import static com.todoroo.andlib.sql.SqlConstants.WHERE;
import static java.util.Arrays.asList;
import java.util.ArrayList;
/**
* Query Template returns a bunch of criteria that allows a query to be constructed
*
* @author Tim Su <tim@todoroo.com>
*/
public final class QueryTemplate {
private final ArrayList<Criterion> criterions = new ArrayList<>();
private final ArrayList<Join> joins = new ArrayList<>();
private final ArrayList<Order> orders = new ArrayList<>();
public QueryTemplate join(Join... join) {
joins.addAll(asList(join));
return this;
}
public QueryTemplate where(Criterion criterion) {
criterions.add(criterion);
return this;
}
public QueryTemplate orderBy(Order... order) {
orders.addAll(asList(order));
return this;
}
@Override
public String toString() {
StringBuilder sql = new StringBuilder();
visitJoinClause(sql);
visitWhereClause(sql);
visitOrderByClause(sql);
return sql.toString();
}
private void visitOrderByClause(StringBuilder sql) {
if (orders.isEmpty()) {
return;
}
sql.append(ORDER_BY);
for (Order order : orders) {
sql.append(SPACE).append(order).append(COMMA);
}
sql.deleteCharAt(sql.length() - 1).append(SPACE);
}
private void visitWhereClause(StringBuilder sql) {
if (criterions.isEmpty()) {
return;
}
sql.append(WHERE);
for (Criterion criterion : criterions) {
sql.append(SPACE).append(criterion).append(SPACE);
}
}
private void visitJoinClause(StringBuilder sql) {
for (Join join : joins) {
sql.append(join).append(SPACE);
}
}
}

@ -0,0 +1,34 @@
package com.todoroo.andlib.sql
import com.todoroo.andlib.sql.StringBuilderExtensions.join
import com.todoroo.andlib.sql.StringBuilderExtensions.orderBy
import com.todoroo.andlib.sql.StringBuilderExtensions.where
import java.util.*
class QueryTemplate {
private val criterions = ArrayList<Criterion>()
private val joins = ArrayList<Join>()
private val orders = ArrayList<Order>()
fun join(vararg join: Join): QueryTemplate {
joins.addAll(join)
return this
}
fun where(criterion: Criterion): QueryTemplate {
criterions.add(criterion)
return this
}
fun orderBy(vararg order: Order): QueryTemplate {
orders.addAll(order)
return this
}
override fun toString() =
StringBuilder()
.join(joins)
.where(criterions)
.orderBy(orders)
.toString()
}

@ -1,27 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public final class SqlConstants {
public static final Field COUNT = Field.field("COUNT(*)");
public static final String SELECT = "SELECT";
static final String SPACE = " ";
public static final String AS = "AS";
public static final String FROM = "FROM";
public static final String ON = "ON";
static final String ALL = "*";
public static final String AND = "AND";
public static final String OR = "OR";
public static final String WHERE = "WHERE";
public static final String NOT = "NOT";
static final String COMMA = ",";
static final String JOIN = "JOIN";
static final String LEFT_PARENTHESIS = "(";
static final String RIGHT_PARENTHESIS = ")";
static final String ORDER_BY = "ORDER BY";
}

@ -1,14 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
public class SqlTable extends DBObject<SqlTable> {
protected SqlTable(String expression) {
super(expression);
}
}

@ -0,0 +1,38 @@
package com.todoroo.andlib.sql
import com.todoroo.andlib.data.Table
object StringBuilderExtensions {
fun StringBuilder.join(joins: List<Join>): StringBuilder {
if (joins.isNotEmpty()) {
append("${joins.joinToString(" ")} ")
}
return this
}
fun StringBuilder.where(criterion: List<Criterion>): StringBuilder {
if (criterion.isNotEmpty()) {
append("WHERE ${criterion.joinToString(" ")} ")
}
return this
}
fun StringBuilder.orderBy(orders: List<Order>): StringBuilder {
if (orders.isNotEmpty()) {
append("ORDER BY ${orders.joinToString(",")} ")
}
return this
}
fun StringBuilder.from(table: Table?): StringBuilder {
if (table != null) {
append("FROM $table ")
}
return this
}
fun StringBuilder.select(fields: List<Field>): StringBuilder {
append("SELECT ${fields.joinToString(", ", transform = Field::toStringInSelect).ifEmpty { "*" }} ")
return this
}
}

@ -1,93 +0,0 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.sql;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
public class UnaryCriterion extends Criterion {
private final Field expression;
private final Object value;
private UnaryCriterion(Field expression, Operator operator, Object value) {
super(operator);
this.expression = expression;
this.value = value;
}
public static Criterion eq(Field expression, Object value) {
return new UnaryCriterion(expression, Operator.eq, value);
}
/** Sanitize the given input for SQL */
public static String sanitize(String input) {
return input.replace("'", "''");
}
static Criterion gt(Field field, Object value) {
return new UnaryCriterion(field, Operator.gt, value);
}
static Criterion gte(Field field, Object value) {
return new UnaryCriterion(field, Operator.gte, value);
}
static Criterion lt(Field field, Object value) {
return new UnaryCriterion(field, Operator.lt, value);
}
static Criterion lte(Field field, Object value) {
return new UnaryCriterion(field, Operator.lte, value);
}
public static Criterion isNull(Field field) {
return new UnaryCriterion(field, Operator.isNull, null) {
@Override
protected void populateOperator(StringBuilder sb) {
sb.append(SPACE).append(operator);
}
};
}
public static Criterion like(Field field, String value) {
return new UnaryCriterion(field, Operator.like, value) {
@Override
protected void populateOperator(StringBuilder sb) {
sb.append(SPACE).append(operator).append(SPACE);
}
};
}
@Override
protected void populate(StringBuilder sb) {
beforePopulateOperator(sb);
populateOperator(sb);
afterPopulateOperator(sb);
}
@SuppressWarnings("WeakerAccess")
void beforePopulateOperator(StringBuilder sb) {
sb.append(expression);
}
void populateOperator(StringBuilder sb) {
sb.append(operator);
}
@SuppressWarnings("WeakerAccess")
void afterPopulateOperator(StringBuilder sb) {
if (value == null) {
return;
}
if (value instanceof String) {
sb.append("'").append(sanitize((String) value)).append("'");
} else {
sb.append(value);
}
}
}

@ -0,0 +1,40 @@
package com.todoroo.andlib.sql
open class UnaryCriterion private constructor(private val expression: Field, operator: Operator, private val value: Any?) : Criterion(operator) {
override fun populate() = "$expression${populateOperator()}${afterPopulateOperator()}"
open fun populateOperator() = "$operator"
private fun afterPopulateOperator(): Any = if (value is String) {
"'${sanitize(value)}'"
} else {
value ?: ""
}
companion object {
fun eq(expression: Field, value: Any?): Criterion = UnaryCriterion(expression, Operator.eq, value)
/** Sanitize the given input for SQL */
fun sanitize(input: String): String = input.replace("'", "''")
fun gt(field: Field, value: Any?): Criterion = UnaryCriterion(field, Operator.gt, value)
fun gte(field: Field, value: Any?): Criterion = UnaryCriterion(field, Operator.gte, value)
fun lt(field: Field, value: Any?): Criterion = UnaryCriterion(field, Operator.lt, value)
fun lte(field: Field, value: Any?): Criterion = UnaryCriterion(field, Operator.lte, value)
fun isNull(field: Field): Criterion {
return object : UnaryCriterion(field, Operator.isNull, null) {
override fun populateOperator() = " $operator"
}
}
fun like(field: Field, value: String?): Criterion {
return object : UnaryCriterion(field, Operator.like, value) {
override fun populateOperator() = " $operator "
}
}
}
}

@ -11,7 +11,6 @@ import androidx.sqlite.db.SimpleSQLiteQuery
import com.todoroo.andlib.sql.Criterion import com.todoroo.andlib.sql.Criterion
import com.todoroo.andlib.sql.Field import com.todoroo.andlib.sql.Field
import com.todoroo.andlib.sql.Functions import com.todoroo.andlib.sql.Functions
import com.todoroo.andlib.sql.SqlConstants
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.api.Filter import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.PermaSql import com.todoroo.astrid.api.PermaSql
@ -263,7 +262,7 @@ abstract class TaskDao(private val database: Database) {
abstract fun getAstrid2TaskProviderTasks(): List<Task> abstract fun getAstrid2TaskProviderTasks(): List<Task>
fun count(filter: Filter): Int { fun count(filter: Filter): Int {
val query = getQuery(filter.sqlQuery, SqlConstants.COUNT) val query = getQuery(filter.sqlQuery, Field.COUNT)
val start = if (BuildConfig.DEBUG) DateUtilities.now() else 0 val start = if (BuildConfig.DEBUG) DateUtilities.now() else 0
val count = count(query) val count = count(query)
Timber.v("%sms: %s", DateUtilities.now() - start, query.sql) Timber.v("%sms: %s", DateUtilities.now() - start, query.sql)

@ -7,7 +7,7 @@ import androidx.annotation.IntDef
import androidx.core.os.ParcelCompat import androidx.core.os.ParcelCompat
import androidx.room.* import androidx.room.*
import com.google.ical.values.RRule import com.google.ical.values.RRule
import com.todoroo.andlib.data.Property.* import com.todoroo.andlib.data.Property
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
import com.todoroo.andlib.sql.Field import com.todoroo.andlib.sql.Field
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
@ -502,22 +502,22 @@ class Task : Parcelable {
const val NO_ID: Long = 0 const val NO_ID: Long = 0
// --- properties // --- properties
@JvmField val ID = LongProperty(TABLE, "_id") @JvmField val ID = TABLE.column("_id")
@JvmField val TITLE = StringProperty(TABLE, "title") @JvmField val TITLE = TABLE.column("title")
@JvmField val IMPORTANCE = IntegerProperty(TABLE, "importance") @JvmField val IMPORTANCE = TABLE.column("importance")
@JvmField val DUE_DATE = LongProperty(TABLE, "dueDate") @JvmField val DUE_DATE = TABLE.column("dueDate")
@JvmField val HIDE_UNTIL = LongProperty(TABLE, "hideUntil") @JvmField val HIDE_UNTIL = TABLE.column("hideUntil")
@JvmField val MODIFICATION_DATE = LongProperty(TABLE, "modified") @JvmField val MODIFICATION_DATE = TABLE.column("modified")
@JvmField val CREATION_DATE = LongProperty(TABLE, "created") @JvmField val CREATION_DATE = TABLE.column("created")
@JvmField val COMPLETION_DATE = LongProperty(TABLE, "completed") @JvmField val COMPLETION_DATE = TABLE.column("completed")
@JvmField val DELETION_DATE = LongProperty(TABLE, "deleted") @JvmField val DELETION_DATE = TABLE.column("deleted")
@JvmField val NOTES = StringProperty(TABLE, "notes") @JvmField val NOTES = TABLE.column("notes")
@JvmField val TIMER_START = LongProperty(TABLE, "timerStart") @JvmField val TIMER_START = TABLE.column("timerStart")
@JvmField val PARENT = LongProperty(TABLE, "parent") @JvmField val PARENT = TABLE.column("parent")
/** constant value for no uuid */ /** constant value for no uuid */
const val NO_UUID = "0" // $NON-NLS-1$ const val NO_UUID = "0" // $NON-NLS-1$
@JvmField val UUID = StringProperty(TABLE, "remoteId") @JvmField val UUID = TABLE.column("remoteId")
/** whether to send a reminder at deadline */ /** whether to send a reminder at deadline */
const val NOTIFY_AT_DEADLINE = 1 shl 1 const val NOTIFY_AT_DEADLINE = 1 shl 1

@ -20,7 +20,7 @@ import com.google.android.material.button.MaterialButtonToggleGroup
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout import com.google.android.material.textfield.TextInputLayout
import com.todoroo.andlib.data.Property.CountProperty import com.todoroo.andlib.sql.Field
import com.todoroo.andlib.sql.Query import com.todoroo.andlib.sql.Query
import com.todoroo.andlib.sql.UnaryCriterion import com.todoroo.andlib.sql.UnaryCriterion
import com.todoroo.andlib.utility.AndroidUtilities import com.todoroo.andlib.utility.AndroidUtilities
@ -301,7 +301,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
private fun updateList() { private fun updateList() {
var max = 0 var max = 0
var last = -1 var last = -1
val sql = StringBuilder(Query.select(CountProperty()).from(Task.TABLE).toString()) val sql = StringBuilder(Query.select(Field.COUNT).from(Task.TABLE).toString())
.append(" WHERE ") .append(" WHERE ")
for (instance in criteria) { for (instance in criteria) {
var value = instance.valueFromCriterion var value = instance.valueFromCriterion
@ -360,7 +360,7 @@ class FilterSettingsActivity : BaseListSettingsActivity() {
if (instance.type == CriterionInstance.TYPE_UNIVERSE || instance.criterion.sql == null) { if (instance.type == CriterionInstance.TYPE_UNIVERSE || instance.criterion.sql == null) {
sql.append(activeAndVisible()).append(' ') sql.append(activeAndVisible()).append(' ')
} else { } else {
val subSql = instance.criterion.sql.replace("?", UnaryCriterion.sanitize(value)) val subSql = instance.criterion.sql.replace("?", UnaryCriterion.sanitize(value!!))
sql.append(Task.ID).append(" IN (").append(subSql).append(") ") sql.append(Task.ID).append(" IN (").append(subSql).append(") ")
} }
} }

@ -113,8 +113,8 @@ class CaldavCalendar : Parcelable {
companion object { companion object {
@JvmField val TABLE = Table("caldav_lists") @JvmField val TABLE = Table("caldav_lists")
@JvmField val UUID = Property.StringProperty(TABLE, "cdl_uuid") @JvmField val UUID = TABLE.column("cdl_uuid")
@JvmField val NAME = Property.StringProperty(TABLE, "cdl_name") @JvmField val NAME = TABLE.column("cdl_name")
@JvmField val CREATOR: Parcelable.Creator<CaldavCalendar> = object : Parcelable.Creator<CaldavCalendar> { @JvmField val CREATOR: Parcelable.Creator<CaldavCalendar> = object : Parcelable.Creator<CaldavCalendar> {
override fun createFromParcel(source: Parcel): CaldavCalendar? { override fun createFromParcel(source: Parcel): CaldavCalendar? {
return CaldavCalendar(source) return CaldavCalendar(source)

@ -1,6 +1,7 @@
package org.tasks.data package org.tasks.data
import androidx.room.* import androidx.room.*
import com.todoroo.andlib.data.Property
import com.todoroo.andlib.data.Property.* import com.todoroo.andlib.data.Property.*
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
import com.todoroo.astrid.helper.UUIDHelper import com.todoroo.astrid.helper.UUIDHelper
@ -71,8 +72,8 @@ class CaldavTask {
companion object { companion object {
const val KEY = "caldav" const val KEY = "caldav"
@JvmField val TABLE = Table("caldav_tasks") @JvmField val TABLE = Table("caldav_tasks")
@JvmField val TASK = IntegerProperty(TABLE, "cd_task") @JvmField val TASK = TABLE.column("cd_task")
@JvmField val DELETED = LongProperty(TABLE, "cd_deleted") @JvmField val DELETED = TABLE.column("cd_deleted")
@JvmField val CALENDAR = StringProperty(TABLE, "cd_calendar") @JvmField val CALENDAR = TABLE.column("cd_calendar")
} }
} }

@ -3,8 +3,7 @@ package org.tasks.data
import android.os.Parcel import android.os.Parcel
import android.os.Parcelable import android.os.Parcelable
import androidx.room.* import androidx.room.*
import com.todoroo.andlib.data.Property.LongProperty import com.todoroo.andlib.data.Property
import com.todoroo.andlib.data.Property.StringProperty
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
import org.tasks.R import org.tasks.R
import org.tasks.preferences.Preferences import org.tasks.preferences.Preferences
@ -119,8 +118,8 @@ class Geofence : Serializable, Parcelable {
companion object { companion object {
const val TABLE_NAME = "geofences" const val TABLE_NAME = "geofences"
@JvmField val TABLE = Table(TABLE_NAME) @JvmField val TABLE = Table(TABLE_NAME)
@JvmField val TASK = LongProperty(TABLE, "task") @JvmField val TASK = TABLE.column("task")
@JvmField val PLACE = StringProperty(TABLE, "place") @JvmField val PLACE = TABLE.column("place")
@JvmField val CREATOR: Parcelable.Creator<Geofence> = object : Parcelable.Creator<Geofence> { @JvmField val CREATOR: Parcelable.Creator<Geofence> = object : Parcelable.Creator<Geofence> {
override fun createFromParcel(source: Parcel): Geofence? { override fun createFromParcel(source: Parcel): Geofence? {
return Geofence(source) return Geofence(source)

@ -1,6 +1,7 @@
package org.tasks.data package org.tasks.data
import androidx.room.* import androidx.room.*
import com.todoroo.andlib.data.Property
import com.todoroo.andlib.data.Property.* import com.todoroo.andlib.data.Property.*
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
@ -97,9 +98,9 @@ class GoogleTask {
companion object { companion object {
const val KEY = "gtasks" const val KEY = "gtasks"
@JvmField val TABLE = Table("google_tasks") @JvmField val TABLE = Table("google_tasks")
@JvmField val PARENT = IntegerProperty(TABLE, "gt_parent") @JvmField val PARENT = TABLE.column("gt_parent")
@JvmField val TASK = IntegerProperty(TABLE, "gt_task") @JvmField val TASK = TABLE.column("gt_task")
@JvmField val DELETED = LongProperty(TABLE, "gt_deleted") @JvmField val DELETED = TABLE.column("gt_deleted")
@JvmField val LIST = StringProperty(TABLE, "gt_list_id") @JvmField val LIST = TABLE.column("gt_list_id")
} }
} }

@ -115,8 +115,8 @@ class GoogleTaskList : Parcelable {
companion object { companion object {
@JvmField val TABLE = Table("google_task_lists") @JvmField val TABLE = Table("google_task_lists")
@JvmField val REMOTE_ID = Property.StringProperty(TABLE, "gtl_remote_id") @JvmField val REMOTE_ID = TABLE.column("gtl_remote_id")
@JvmField val NAME = Property.StringProperty(TABLE, "gtl_title") @JvmField val NAME = TABLE.column("gtl_title")
@JvmField val CREATOR: Parcelable.Creator<GoogleTaskList> = object : Parcelable.Creator<GoogleTaskList> { @JvmField val CREATOR: Parcelable.Creator<GoogleTaskList> = object : Parcelable.Creator<GoogleTaskList> {
override fun createFromParcel(parcel: Parcel): GoogleTaskList? { override fun createFromParcel(parcel: Parcel): GoogleTaskList? {
return GoogleTaskList(parcel) return GoogleTaskList(parcel)

@ -10,7 +10,7 @@ import android.widget.Toast
import androidx.room.* import androidx.room.*
import com.mapbox.api.geocoding.v5.GeocodingCriteria import com.mapbox.api.geocoding.v5.GeocodingCriteria
import com.mapbox.api.geocoding.v5.models.CarmenFeature import com.mapbox.api.geocoding.v5.models.CarmenFeature
import com.todoroo.andlib.data.Property.StringProperty import com.todoroo.andlib.data.Property
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
import com.todoroo.astrid.helper.UUIDHelper import com.todoroo.astrid.helper.UUIDHelper
import net.fortuna.ical4j.model.property.Geo import net.fortuna.ical4j.model.property.Geo
@ -182,9 +182,9 @@ class Place : Serializable, Parcelable {
const val KEY = "place" const val KEY = "place"
const val TABLE_NAME = "places" const val TABLE_NAME = "places"
@JvmField val TABLE = Table(TABLE_NAME) @JvmField val TABLE = Table(TABLE_NAME)
@JvmField val UID = StringProperty(TABLE, "uid") @JvmField val UID = TABLE.column("uid")
@JvmField val NAME = StringProperty(TABLE, "name") @JvmField val NAME = TABLE.column("name")
@JvmField val ADDRESS = StringProperty(TABLE, "address") @JvmField val ADDRESS = TABLE.column("address")
@JvmField val CREATOR: Parcelable.Creator<Place> = object : Parcelable.Creator<Place> { @JvmField val CREATOR: Parcelable.Creator<Place> = object : Parcelable.Creator<Place> {
override fun createFromParcel(source: Parcel): Place? { override fun createFromParcel(source: Parcel): Place? {
return Place(source) return Place(source)

@ -1,8 +1,7 @@
package org.tasks.data package org.tasks.data
import androidx.room.* import androidx.room.*
import com.todoroo.andlib.data.Property.LongProperty import com.todoroo.andlib.data.Property
import com.todoroo.andlib.data.Property.StringProperty
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import org.tasks.backup.XmlReader import org.tasks.backup.XmlReader
@ -62,8 +61,8 @@ class Tag {
companion object { companion object {
const val KEY = "tags-tag" // $NON-NLS-1$ const val KEY = "tags-tag" // $NON-NLS-1$
@JvmField val TABLE = Table("tags") @JvmField val TABLE = Table("tags")
@JvmField val TASK = LongProperty(TABLE, "task") @JvmField val TASK = TABLE.column("task")
@JvmField val TAG_UID = StringProperty(TABLE, "tag_uid") @JvmField val TAG_UID = TABLE.column("tag_uid")
@JvmField val NAME = StringProperty(TABLE, "name") @JvmField val NAME = TABLE.column("name")
} }
} }

@ -1,7 +1,7 @@
package org.tasks.data package org.tasks.data
import com.todoroo.andlib.sql.Criterion import com.todoroo.andlib.sql.Criterion
import com.todoroo.andlib.sql.Field.field import com.todoroo.andlib.sql.Field.Companion.field
import com.todoroo.andlib.sql.Join import com.todoroo.andlib.sql.Join
import com.todoroo.astrid.activity.TaskListFragment import com.todoroo.astrid.activity.TaskListFragment
import com.todoroo.astrid.api.CaldavFilter import com.todoroo.astrid.api.CaldavFilter

@ -1,6 +1,5 @@
package org.tasks.data package org.tasks.data
import com.todoroo.andlib.data.Property.StringProperty
import com.todoroo.andlib.sql.Field import com.todoroo.andlib.sql.Field
import com.todoroo.andlib.sql.Join import com.todoroo.andlib.sql.Join
import com.todoroo.andlib.sql.Query import com.todoroo.andlib.sql.Query
@ -18,10 +17,8 @@ internal object TaskListQueryNonRecursive {
${TaskListQuery.JOINS} ${TaskListQuery.JOINS}
""".trimIndent() """.trimIndent()
private val TAGS = private val TAGS =
StringProperty( Field.field("group_concat(distinct(${TaskListFragment.TAGS_METADATA_JOIN}.tag_uid))")
null, .`as`("tags")
"group_concat(distinct(${TaskListFragment.TAGS_METADATA_JOIN}.tag_uid))")
.`as`("tags")
private val FIELDS = TaskListQuery.FIELDS.plus(TAGS).toTypedArray() private val FIELDS = TaskListQuery.FIELDS.plus(TAGS).toTypedArray()
fun getNonRecursiveQuery(filter: Filter, preferences: Preferences): List<String> { fun getNonRecursiveQuery(filter: Filter, preferences: Preferences): List<String> {

@ -2,7 +2,7 @@ package org.tasks.data
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
import com.todoroo.andlib.sql.Criterion import com.todoroo.andlib.sql.Criterion
import com.todoroo.andlib.sql.Field.field import com.todoroo.andlib.sql.Field.Companion.field
import com.todoroo.andlib.sql.Join import com.todoroo.andlib.sql.Join
import com.todoroo.andlib.sql.Query import com.todoroo.andlib.sql.Query
import com.todoroo.andlib.sql.QueryTemplate import com.todoroo.andlib.sql.QueryTemplate

@ -88,8 +88,8 @@ class UserActivity : Parcelable {
companion object { companion object {
@JvmField val TABLE = Table("userActivity") @JvmField val TABLE = Table("userActivity")
@JvmField val TASK = Property.StringProperty(TABLE, "target_id") @JvmField val TASK = TABLE.column("target_id")
@JvmField val MESSAGE = Property.StringProperty(TABLE, "message") @JvmField val MESSAGE = TABLE.column("message")
@JvmField val CREATOR: Parcelable.Creator<UserActivity> = object : Parcelable.Creator<UserActivity> { @JvmField val CREATOR: Parcelable.Creator<UserActivity> = object : Parcelable.Creator<UserActivity> {
override fun createFromParcel(source: Parcel): UserActivity? { override fun createFromParcel(source: Parcel): UserActivity? {
return UserActivity(source) return UserActivity(source)

@ -4,7 +4,7 @@ import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.Index import androidx.room.Index
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import com.todoroo.andlib.data.Property.LongProperty import com.todoroo.andlib.data.Property
import com.todoroo.andlib.data.Table import com.todoroo.andlib.data.Table
@Entity(tableName = Notification.TABLE_NAME, indices = [Index(value = ["task"], unique = true)]) @Entity(tableName = Notification.TABLE_NAME, indices = [Index(value = ["task"], unique = true)])
@ -32,6 +32,6 @@ class Notification {
companion object { companion object {
const val TABLE_NAME = "notification" const val TABLE_NAME = "notification"
@JvmField val TABLE = Table(TABLE_NAME) @JvmField val TABLE = Table(TABLE_NAME)
@JvmField val TASK = LongProperty(TABLE, "task") @JvmField val TASK = TABLE.column("task")
} }
} }
Loading…
Cancel
Save