package com.android.example.leanback.search; import android.database.sqlite.SQLiteDatabase; import android.provider.BaseColumns; import android.util.Log; import com.android.example.leanback.search.BuildConfig; import java.util.LinkedList; public class AbstractContract { protected static final String _ID = BaseColumns._ID; protected static final String TYPE_PRIMARY_KEY = "INTEGER PRIMARY KEY"; protected static final String TYPE_INTEGER = "INTEGER"; protected static final String TYPE_TEXT = "TEXT"; /*package*/ static class Ddl { public static enum Type { TABLE("TABLE"), VIRTUAL_TABLE("VIRTUAL TABLE"), VIEW("VIEW"); public final String token; private Type(final String token) { this.token = token; } } private static Ddl instance = null; public static Ddl builder() { return null == instance ? (instance = new Ddl()) : instance; } public static void reset() { instance = null; } private final StringBuilder sql; private Ddl() { this(256); } private Ddl(final int bufferSize) { sql = new StringBuilder(bufferSize); } @Override public String toString() { return sql.toString(); } public String build() { final String statement = sql.toString(); sql.setLength(0); return statement; } public void execSql(final SQLiteDatabase db) { db.execSQL(build()); } public Ddl append(final CharSequence string) { sql.append(string); return this; } /*public Ddl append(final CharSequence... strings) { for (final CharSequence s : strings) { sql.append(s); } return this; }*/ public Ddl create(final Type type, final String name) { sql.append("CREATE ").append(type.token).append(' ').append(name); if (Type.VIEW == type) { sql.append(" AS SELECT"); } return this; } public Ddl drop(final Type type, final String name) { sql.append("DROP ") .append(Type.VIRTUAL_TABLE == type ? Type.TABLE.token : type.token) .append(" IF EXISTS ").append(name); return this; } public Ddl columnDef(final String... columns) { if (BuildConfig.DEBUG) { if (0 != (columns.length % 2)) { throw new IllegalArgumentException("Column def array mus have even number of entries"); } } final int size = columns.length; sql.append('('); for (int i=0; i<size; i+=2) { sql.append(columns[i]).append(' ').append(columns[i + 1]).append(','); } if (size > 0) { sql.setLength(sql.length() - 1); } sql.append(')'); return this; } public Ddl columnList(final String... columns) { final int size = columns.length; sql.append(' '); for (int i=0; i<size; i++) { sql.append(columns[i]).append(','); } if (size > 0) { sql.setLength(sql.length() - 1); } return this; } public Ddl from(final String name) { sql.append(" FROM ").append(name); return this; } public Ddl join(final String name, final String on) { sql.append(" JOIN ").append(name).append(" ON ").append(on); return this; } } /*package*/ static abstract class Table { /*package*/ Table() { } /*package*/ abstract String name(); /*package*/ abstract void onCreate(SQLiteDatabase db); /*package*/ abstract void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion); } /*package*/ static Table table(final Class<? extends Table> klass) { try { return klass.newInstance(); } catch (InstantiationException | IllegalAccessException e) { throw new RuntimeException(e); } } /*package*/ static Table[] tables(final Class<? extends AbstractContract> contract) { final LinkedList<Table> tables = new LinkedList<>(); for (final Class<?> klass : contract.getClasses()) { if (Table.class.isAssignableFrom(klass)) { try { if (klass.getSimpleName().endsWith("View")) { tables.add((Table) klass.newInstance()); } else { tables.addFirst((Table) klass.newInstance()); } } catch (InstantiationException | IllegalAccessException e) { if (BuildConfig.DEBUG) { Log.e(UniversalSearchContract.class.getSimpleName(), "Cannot instantiate table " + klass, e); } } } } return tables.toArray(new Table[tables.size()]); } protected AbstractContract() { } } // EOF