diff --git a/src/com/activeandroid/query/From.java b/src/com/activeandroid/query/From.java index ab3837a90..31a10851f 100644 --- a/src/com/activeandroid/query/From.java +++ b/src/com/activeandroid/query/From.java @@ -29,63 +29,63 @@ import java.util.List; public final class From implements Sqlable { - private Sqlable mQueryBase; - - private Class mType; - private String mAlias; - private List mJoins; - private final StringBuilder mWhere = new StringBuilder(); - private String mGroupBy; - private String mHaving; - private String mOrderBy; - private String mLimit; - private String mOffset; - - private List mArguments; - - public From(Class table, Sqlable queryBase) { - mType = table; - mJoins = new ArrayList(); - mQueryBase = queryBase; - - mJoins = new ArrayList(); - mArguments = new ArrayList(); - } - - public From as(String alias) { - mAlias = alias; - return this; - } - - public Join join(Class table) { - Join join = new Join(this, table, null); - mJoins.add(join); - return join; - } - - public Join leftJoin(Class table) { - Join join = new Join(this, table, JoinType.LEFT); - mJoins.add(join); - return join; - } - - public Join outerJoin(Class table) { - Join join = new Join(this, table, JoinType.OUTER); - mJoins.add(join); - return join; - } - - public Join innerJoin(Class table) { - Join join = new Join(this, table, JoinType.INNER); - mJoins.add(join); - return join; - } - - public Join crossJoin(Class table) { - Join join = new Join(this, table, JoinType.CROSS); - mJoins.add(join); - return join; - } + private Sqlable mQueryBase; + + private Class mType; + private String mAlias; + private List mJoins; + private final StringBuilder mWhere = new StringBuilder(); + private String mGroupBy; + private String mHaving; + private String mOrderBy; + private String mLimit; + private String mOffset; + + private List mArguments; + + public From(Class table, Sqlable queryBase) { + mType = table; + mJoins = new ArrayList(); + mQueryBase = queryBase; + + mJoins = new ArrayList(); + mArguments = new ArrayList(); + } + + public From as(String alias) { + mAlias = alias; + return this; + } + + public Join join(Class table) { + Join join = new Join(this, table, null); + mJoins.add(join); + return join; + } + + public Join leftJoin(Class table) { + Join join = new Join(this, table, JoinType.LEFT); + mJoins.add(join); + return join; + } + + public Join outerJoin(Class table) { + Join join = new Join(this, table, JoinType.OUTER); + mJoins.add(join); + return join; + } + + public Join innerJoin(Class table) { + Join join = new Join(this, table, JoinType.INNER); + mJoins.add(join); + return join; + } + + public Join crossJoin(Class table) { + Join join = new Join(this, table, JoinType.CROSS); + mJoins.add(join); + return join; + } public From where(String clause) { // Chain conditions if a previous condition exists. @@ -121,48 +121,48 @@ public From or(String clause, Object... args) { or(clause).addArguments(args); return this; } - - public From groupBy(String groupBy) { - mGroupBy = groupBy; - return this; - } - - public From having(String having) { - mHaving = having; - return this; - } - - public From orderBy(String orderBy) { - mOrderBy = orderBy; - return this; - } - - public From limit(int limit) { - return limit(String.valueOf(limit)); - } - - public From limit(String limit) { - mLimit = limit; - return this; - } - - public From offset(int offset) { - return offset(String.valueOf(offset)); - } - - public From offset(String offset) { - mOffset = offset; - return this; - } - - void addArguments(Object[] args) { - for(Object arg : args) { + + public From groupBy(String groupBy) { + mGroupBy = groupBy; + return this; + } + + public From having(String having) { + mHaving = having; + return this; + } + + public From orderBy(String orderBy) { + mOrderBy = orderBy; + return this; + } + + public From limit(int limit) { + return limit(String.valueOf(limit)); + } + + public From limit(String limit) { + mLimit = limit; + return this; + } + + public From offset(int offset) { + return offset(String.valueOf(offset)); + } + + public From offset(String offset) { + mOffset = offset; + return this; + } + + void addArguments(Object[] args) { + for (Object arg : args) { if (arg.getClass() == boolean.class || arg.getClass() == Boolean.class) { arg = (arg.equals(true) ? 1 : 0); } mArguments.add(arg); } - } + } private void addFrom(final StringBuilder sql) { sql.append("FROM "); @@ -293,33 +293,34 @@ public String toCountSql() { return sqlString(sql); } - public List execute() { - if (mQueryBase instanceof Select) { - return SQLiteUtils.rawQuery(mType, toSql(), getArguments()); - - } else { - SQLiteUtils.execSql(toSql(), getArguments()); - Cache.getContext().getContentResolver().notifyChange(ContentProvider.createUri(mType, null), null); - return null; - - } - } - - public T executeSingle() { - if (mQueryBase instanceof Select) { - limit(1); - return (T) SQLiteUtils.rawQuerySingle(mType, toSql(), getArguments()); - - } else { - limit(1); - SQLiteUtils.rawQuerySingle(mType, toSql(), getArguments()).delete(); - return null; - - } - } - + public List execute() { + if (mQueryBase instanceof Select) { + return SQLiteUtils.rawQuery(mType, toSql(), getArguments()); + + } else { + SQLiteUtils.execSql(toSql(), getArguments()); + Cache.getContext().getContentResolver().notifyChange(ContentProvider.createUri(mType, null), null); + return null; + + } + } + + public T executeSingle() { + if (mQueryBase instanceof Select) { + limit(1); + return (T) SQLiteUtils.rawQuerySingle(mType, toSql(), getArguments()); + + } else { + limit(1); + SQLiteUtils.rawQuerySingle(mType, toSql(), getArguments()).delete(); + return null; + + } + } + /** * Gets a value indicating whether the query returns any rows. + * * @return true if the query returns at least one row; otherwise, false. */ public boolean exists() { @@ -333,14 +334,81 @@ public int count() { return SQLiteUtils.intQuery(toCountSql(), getArguments()); } - public String[] getArguments() { - final int size = mArguments.size(); - final String[] args = new String[size]; + public String[] getArguments() { + final int size = mArguments.size(); + final String[] args = new String[size]; - for (int i = 0; i < size; i++) { - args[i] = mArguments.get(i).toString(); - } + for (int i = 0; i < size; i++) { + args[i] = mArguments.get(i).toString(); + } + + return args; + } + + + public int avg(String column) { + return SQLiteUtils.intQuery(toFunctionSql("avg", column), getArguments()); + } + + public int max(String column) { + return SQLiteUtils.intQuery(toFunctionSql("max", column), getArguments()); + } - return args; - } + public int min(String column) { + return SQLiteUtils.intQuery(toFunctionSql("min", column), getArguments()); + } + + private String toFunctionSql(String functionName, String column) { + final StringBuilder sql = new StringBuilder(); + sql.append("SELECT "); + sql.append(functionName); + sql.append("("); + sql.append(column); + sql.append(") "); + + addFrom(sql); + addJoins(sql); + addWhere(sql); + addGroupBy(sql); + addHaving(sql); + addLimit(sql); + addOffset(sql); + + return sqlString(sql); + } + + public T last() { + String mode = " DESC "; + return getSingleOrdered(mode); + } + + public T first() { + String mode = " ACS "; + return getSingleOrdered(mode); + } + + private T getSingleOrdered(String mode) { + final StringBuilder sql = new StringBuilder(); + sql.append(mQueryBase.toSql()); + + addFrom(sql); + addJoins(sql); + addWhere(sql); + addGroupBy(sql); + addHaving(sql); + + sql.append("ORDER BY "); + if (mOrderBy == null) + sql.append(1); + else + sql.append(mOrderBy); + sql.append(mode); + +// addLimit(sql); + sql.append("LIMIT "); + sql.append(1); + sql.append(" "); +// addOffset(sql); + return (T) SQLiteUtils.rawQuerySingle(mType, sql.toString(), getArguments()); + } }