mirror of https://github.com/tasks/tasks
Convert sql package to Kotlin
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 "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue