package com.evancharlton.mileage.provider.tables;
import com.evancharlton.mileage.dao.Dao;
import com.evancharlton.mileage.dao.Dao.Column;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.provider.BaseColumns;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Set;
public abstract class ContentTable {
protected static String TABLE_NAME = "content_table";
abstract public String getTableName();
public static final HashMap<String, String> buildProjectionMap(String[] map) {
HashMap<String, String> projection = new HashMap<String, String>();
// just in case
projection.put(BaseColumns._ID, BaseColumns._ID);
for (String key : map) {
projection.put(key, key);
}
return projection;
}
public String getDefaultSortOrder() {
return BaseColumns._ID + " desc";
}
abstract public void registerUris();
public int delete(SQLiteDatabase db, Uri uri, String selection, String[] selectionArgs) {
try {
long id = ContentUris.parseId(uri);
if (selection == null) {
selection = "";
}
selection += BaseColumns._ID + " = ?";
if (selectionArgs == null) {
selectionArgs = new String[0];
}
final int length = selectionArgs.length + 1;
String[] args = new String[length];
for (int i = 0; i < length - 1; i++) {
args[i] = selectionArgs[i];
}
args[length - 1] = String.valueOf(id);
selectionArgs = args;
} catch (UnsupportedOperationException e) {
// silently fail
} catch (NumberFormatException e) {
// silently fail
}
return db.delete(getTableName(), selection, selectionArgs);
}
public final boolean isValidType(int type) {
return getType(type) != null;
}
abstract public String getType(int type);
abstract public long insert(int type, SQLiteDatabase db, ContentValues initialValues);
abstract public boolean query(int type, Uri uri, SQLiteQueryBuilder queryBuilder,
Context context, String[] projection);
abstract public int update(int match, SQLiteDatabase db, Uri uri, ContentValues values,
String selection, String[] selectionArgs);
abstract public String[] init(boolean isUpgrade);
abstract protected Class<? extends Dao> getDaoType();
public final String create() throws IllegalArgumentException, IllegalAccessException {
TableBuilder builder = new TableBuilder();
Class<? extends Dao> cls = getDaoType();
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof Column) {
Column columnAnnotation = (Column) annotation;
String columnName = columnAnnotation.name();
switch (columnAnnotation.type()) {
case Column.INTEGER:
case Column.BOOLEAN:
case Column.LONG:
case Column.TIMESTAMP:
builder.addInteger(columnName);
break;
case Column.DOUBLE:
builder.addDouble(columnName);
break;
case Column.STRING:
builder.addText(columnName);
break;
}
break;
}
}
}
return builder.build();
}
abstract public String[] getProjection();
protected final class TableBuilder {
private StringBuilder mBuilder = new StringBuilder();
public TableBuilder() {
mBuilder.append("CREATE TABLE ").append(getTableName()).append(" (");
mBuilder.append(BaseColumns._ID).append(" INTEGER PRIMARY KEY AUTOINCREMENT");
}
public TableBuilder addDouble(String fieldName) {
return addField(fieldName, "DOUBLE");
}
public TableBuilder addInteger(String fieldName) {
return addField(fieldName, "INTEGER");
}
public TableBuilder addText(String fieldName) {
return addField(fieldName, "TEXT");
}
private TableBuilder addField(String fieldName, String fieldType) {
mBuilder.append(", ").append(fieldName).append(" ").append(fieldType);
return this;
}
public String build() {
mBuilder.append(");");
return mBuilder.toString();
}
@Override
public String toString() {
return build();
}
}
protected final class InsertBuilder {
private StringBuilder mBuilder = new StringBuilder();
private HashMap<String, String> mData = new HashMap<String, String>();
public InsertBuilder() {
mBuilder.append("INSERT INTO ").append(getTableName()).append(" (");
}
public InsertBuilder add(String field, String value) {
mData.put(field, value);
return this;
}
public InsertBuilder add(String field, long value) {
return add(field, String.valueOf(value));
}
public String build() {
Set<String> keySet = mData.keySet();
final int length = keySet.size();
String[] values = new String[length];
int i = 0;
for (String key : keySet) {
values[i] = mData.get(key);
mBuilder.append(key);
if (i + 1 < length) {
mBuilder.append(",");
}
i++;
}
mBuilder.append(") VALUES (");
for (i = 0; i < length; i++) {
mBuilder.append("'").append(values[i]).append("'");
if (i + 1 < length) {
mBuilder.append(",");
}
}
mBuilder.append(");");
return mBuilder.toString();
}
@Override
public String toString() {
return build();
}
}
}