package com.letsvote.provider.base;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import android.content.Context;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
public abstract class AbstractSelection<T extends AbstractSelection<?>> {
private static final String EQ = "=?";
private static final String PAREN_OPEN = "(";
private static final String PAREN_CLOSE = ")";
private static final String AND = " AND ";
private static final String OR = " OR ";
private static final String IS_NULL = " IS NULL";
private static final String IS_NOT_NULL = " IS NOT NULL";
private static final String IN = " IN (";
private static final String NOT_IN = " NOT IN (";
private static final String COMMA = ",";
private static final String GT = ">?";
private static final String LT = "<?";
private static final String GT_EQ = ">=?";
private static final String LT_EQ = "<=?";
private static final String NOT_EQ = "<>?";
private static final String LIKE = " LIKE ?";
private static final String CONTAINS = " LIKE '%' || ? || '%'";
private static final String STARTS = " LIKE ? || '%'";
private static final String ENDS = " LIKE '%' || ?";
private static final String COUNT = "COUNT(*)";
private static final String DESC = " DESC";
private final StringBuilder mSelection = new StringBuilder();
private final List<String> mSelectionArgs = new ArrayList<String>(5);
private final StringBuilder mOrderBy = new StringBuilder();
Boolean mNotify;
String mGroupBy;
String mHaving;
Integer mLimit;
protected void addEquals(String column, Object[] value) {
mSelection.append(column);
if (value == null) {
// Single null value
mSelection.append(IS_NULL);
} else if (value.length > 1) {
// Multiple values ('in' clause)
mSelection.append(IN);
for (int i = 0; i < value.length; i++) {
mSelection.append("?");
if (i < value.length - 1) {
mSelection.append(COMMA);
}
mSelectionArgs.add(valueOf(value[i]));
}
mSelection.append(PAREN_CLOSE);
} else {
// Single value
if (value[0] == null) {
// Single null value
mSelection.append(IS_NULL);
} else {
// Single not null value
mSelection.append(EQ);
mSelectionArgs.add(valueOf(value[0]));
}
}
}
protected void addNotEquals(String column, Object[] value) {
mSelection.append(column);
if (value == null) {
// Single null value
mSelection.append(IS_NOT_NULL);
} else if (value.length > 1) {
// Multiple values ('in' clause)
mSelection.append(NOT_IN);
for (int i = 0; i < value.length; i++) {
mSelection.append("?");
if (i < value.length - 1) {
mSelection.append(COMMA);
}
mSelectionArgs.add(valueOf(value[i]));
}
mSelection.append(PAREN_CLOSE);
} else {
// Single value
if (value[0] == null) {
// Single null value
mSelection.append(IS_NOT_NULL);
} else {
// Single not null value
mSelection.append(NOT_EQ);
mSelectionArgs.add(valueOf(value[0]));
}
}
}
protected void addLike(String column, String[] values) {
mSelection.append(PAREN_OPEN);
for (int i = 0; i < values.length; i++) {
mSelection.append(column);
mSelection.append(LIKE);
mSelectionArgs.add(values[i]);
if (i < values.length - 1) {
mSelection.append(OR);
}
}
mSelection.append(PAREN_CLOSE);
}
protected void addContains(String column, String[] values) {
mSelection.append(PAREN_OPEN);
for (int i = 0; i < values.length; i++) {
mSelection.append(column);
mSelection.append(CONTAINS);
mSelectionArgs.add(values[i]);
if (i < values.length - 1) {
mSelection.append(OR);
}
}
mSelection.append(PAREN_CLOSE);
}
protected void addStartsWith(String column, String[] values) {
mSelection.append(PAREN_OPEN);
for (int i = 0; i < values.length; i++) {
mSelection.append(column);
mSelection.append(STARTS);
mSelectionArgs.add(values[i]);
if (i < values.length - 1) {
mSelection.append(OR);
}
}
mSelection.append(PAREN_CLOSE);
}
protected void addEndsWith(String column, String[] values) {
mSelection.append(PAREN_OPEN);
for (int i = 0; i < values.length; i++) {
mSelection.append(column);
mSelection.append(ENDS);
mSelectionArgs.add(values[i]);
if (i < values.length - 1) {
mSelection.append(OR);
}
}
mSelection.append(PAREN_CLOSE);
}
protected void addGreaterThan(String column, Object value) {
mSelection.append(column);
mSelection.append(GT);
mSelectionArgs.add(valueOf(value));
}
protected void addGreaterThanOrEquals(String column, Object value) {
mSelection.append(column);
mSelection.append(GT_EQ);
mSelectionArgs.add(valueOf(value));
}
protected void addLessThan(String column, Object value) {
mSelection.append(column);
mSelection.append(LT);
mSelectionArgs.add(valueOf(value));
}
protected void addLessThanOrEquals(String column, Object value) {
mSelection.append(column);
mSelection.append(LT_EQ);
mSelectionArgs.add(valueOf(value));
}
public void addRaw(String raw, Object... args) {
mSelection.append(" ");
mSelection.append(raw);
mSelection.append(" ");
for (Object arg : args) {
mSelectionArgs.add(valueOf(arg));
}
}
private String valueOf(Object obj) {
if (obj instanceof Date) {
return String.valueOf(((Date) obj).getTime());
} else if (obj instanceof Boolean) {
return (Boolean) obj ? "1" : "0";
} else if (obj instanceof Enum) {
return String.valueOf(((Enum<?>) obj).ordinal());
}
return String.valueOf(obj);
}
@SuppressWarnings("unchecked")
public T openParen() {
mSelection.append(PAREN_OPEN);
return (T) this;
}
@SuppressWarnings("unchecked")
public T closeParen() {
mSelection.append(PAREN_CLOSE);
return (T) this;
}
@SuppressWarnings("unchecked")
public T and() {
mSelection.append(AND);
return (T) this;
}
@SuppressWarnings("unchecked")
public T or() {
mSelection.append(OR);
return (T) this;
}
protected Object[] toObjectArray(int... array) {
Object[] res = new Object[array.length];
for (int i = 0; i < array.length; i++) {
res[i] = array[i];
}
return res;
}
protected Object[] toObjectArray(long... array) {
Object[] res = new Object[array.length];
for (int i = 0; i < array.length; i++) {
res[i] = array[i];
}
return res;
}
protected Object[] toObjectArray(float... array) {
Object[] res = new Object[array.length];
for (int i = 0; i < array.length; i++) {
res[i] = array[i];
}
return res;
}
protected Object[] toObjectArray(double... array) {
Object[] res = new Object[array.length];
for (int i = 0; i < array.length; i++) {
res[i] = array[i];
}
return res;
}
protected Object[] toObjectArray(Boolean value) {
return new Object[] { value };
}
/**
* Returns the selection produced by this object.
*/
public String sel() {
return mSelection.toString();
}
/**
* Returns the selection arguments produced by this object.
*/
public String[] args() {
int size = mSelectionArgs.size();
if (size == 0) return null;
return mSelectionArgs.toArray(new String[size]);
}
/**
* Returns the order string produced by this object.
*/
public String order() {
return mOrderBy.length() > 0 ? mOrderBy.toString() : null;
}
/**
* Returns the {@code uri} argument to pass to the {@code ContentResolver} methods.
*/
public Uri uri() {
Uri uri = baseUri();
if (mNotify != null) uri = BaseContentProvider.notify(uri, mNotify);
if (mGroupBy != null) uri = BaseContentProvider.groupBy(uri, mGroupBy);
if (mHaving != null) uri = BaseContentProvider.having(uri, mHaving);
if (mLimit != null) uri = BaseContentProvider.limit(uri, String.valueOf(mLimit));
return uri;
}
protected abstract Uri baseUri();
/**
* Deletes row(s) specified by this selection.
*
* @param contentResolver The content resolver to use.
* @return The number of rows deleted.
*/
public int delete(ContentResolver contentResolver) {
return contentResolver.delete(uri(), sel(), args());
}
/**
* Deletes row(s) specified by this selection.
*
* @param context The context to use.
* @return The number of rows deleted.
*/
public int delete(Context context) {
return context.getContentResolver().delete(uri(), sel(), args());
}
@SuppressWarnings("unchecked")
public T notify(boolean notify) {
mNotify = notify;
return (T) this;
}
@SuppressWarnings("unchecked")
public T groupBy(String groupBy) {
mGroupBy = groupBy;
return (T) this;
}
@SuppressWarnings("unchecked")
public T having(String having) {
mHaving = having;
return (T) this;
}
@SuppressWarnings("unchecked")
public T limit(int limit) {
mLimit = limit;
return (T) this;
}
@SuppressWarnings("unchecked")
public T orderBy(String order, boolean desc) {
if (mOrderBy.length() > 0) mOrderBy.append(COMMA);
mOrderBy.append(order);
if (desc) mOrderBy.append(DESC);
return (T) this;
}
public T orderBy(String order) {
return orderBy(order, false);
}
@SuppressWarnings("unchecked")
public T orderBy(String... orders) {
for (String order : orders) {
orderBy(order, false);
}
return (T) this;
}
public int count(ContentResolver resolver) {
Cursor cursor = resolver.query(uri(), new String[] { COUNT }, sel(), args(), null);
if (cursor == null) return 0;
try {
return cursor.moveToFirst() ? cursor.getInt(0) : 0;
} finally {
cursor.close();
}
}
}