diff options
Diffstat (limited to 'gallerycommon/src/com/android/gallery3d/common/EntrySchema.java')
-rw-r--r-- | gallerycommon/src/com/android/gallery3d/common/EntrySchema.java | 542 |
1 files changed, 0 insertions, 542 deletions
diff --git a/gallerycommon/src/com/android/gallery3d/common/EntrySchema.java b/gallerycommon/src/com/android/gallery3d/common/EntrySchema.java deleted file mode 100644 index 7bf7e431c..000000000 --- a/gallerycommon/src/com/android/gallery3d/common/EntrySchema.java +++ /dev/null @@ -1,542 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.gallery3d.common; - -import android.content.ContentValues; -import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; -import android.text.TextUtils; - -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Field; -import java.util.ArrayList; - -public final class EntrySchema { - @SuppressWarnings("unused") - private static final String TAG = "EntrySchema"; - - public static final int TYPE_STRING = 0; - public static final int TYPE_BOOLEAN = 1; - public static final int TYPE_SHORT = 2; - public static final int TYPE_INT = 3; - public static final int TYPE_LONG = 4; - public static final int TYPE_FLOAT = 5; - public static final int TYPE_DOUBLE = 6; - public static final int TYPE_BLOB = 7; - private static final String SQLITE_TYPES[] = { - "TEXT", "INTEGER", "INTEGER", "INTEGER", "INTEGER", "REAL", "REAL", "NONE" }; - - private static final String FULL_TEXT_INDEX_SUFFIX = "_fulltext"; - - private final String mTableName; - private final ColumnInfo[] mColumnInfo; - private final String[] mProjection; - private final boolean mHasFullTextIndex; - - public EntrySchema(Class<? extends Entry> clazz) { - // Get table and column metadata from reflection. - ColumnInfo[] columns = parseColumnInfo(clazz); - mTableName = parseTableName(clazz); - mColumnInfo = columns; - - // Cache the list of projection columns and check for full-text columns. - String[] projection = {}; - boolean hasFullTextIndex = false; - if (columns != null) { - projection = new String[columns.length]; - for (int i = 0; i != columns.length; ++i) { - ColumnInfo column = columns[i]; - projection[i] = column.name; - if (column.fullText) { - hasFullTextIndex = true; - } - } - } - mProjection = projection; - mHasFullTextIndex = hasFullTextIndex; - } - - public String getTableName() { - return mTableName; - } - - public ColumnInfo[] getColumnInfo() { - return mColumnInfo; - } - - public String[] getProjection() { - return mProjection; - } - - public int getColumnIndex(String columnName) { - for (ColumnInfo column : mColumnInfo) { - if (column.name.equals(columnName)) { - return column.projectionIndex; - } - } - return -1; - } - - public ColumnInfo getColumn(String columnName) { - int index = getColumnIndex(columnName); - return (index < 0) ? null : mColumnInfo[index]; - } - - private void logExecSql(SQLiteDatabase db, String sql) { - db.execSQL(sql); - } - - public <T extends Entry> T cursorToObject(Cursor cursor, T object) { - try { - for (ColumnInfo column : mColumnInfo) { - int columnIndex = column.projectionIndex; - Field field = column.field; - switch (column.type) { - case TYPE_STRING: - field.set(object, cursor.isNull(columnIndex) - ? null - : cursor.getString(columnIndex)); - break; - case TYPE_BOOLEAN: - field.setBoolean(object, cursor.getShort(columnIndex) == 1); - break; - case TYPE_SHORT: - field.setShort(object, cursor.getShort(columnIndex)); - break; - case TYPE_INT: - field.setInt(object, cursor.getInt(columnIndex)); - break; - case TYPE_LONG: - field.setLong(object, cursor.getLong(columnIndex)); - break; - case TYPE_FLOAT: - field.setFloat(object, cursor.getFloat(columnIndex)); - break; - case TYPE_DOUBLE: - field.setDouble(object, cursor.getDouble(columnIndex)); - break; - case TYPE_BLOB: - field.set(object, cursor.isNull(columnIndex) - ? null - : cursor.getBlob(columnIndex)); - break; - } - } - return object; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - private void setIfNotNull(Field field, Object object, Object value) - throws IllegalAccessException { - if (value != null) field.set(object, value); - } - - /** - * Converts the ContentValues to the object. The ContentValues may not - * contain values for all the fields in the object. - */ - public <T extends Entry> T valuesToObject(ContentValues values, T object) { - try { - for (ColumnInfo column : mColumnInfo) { - String columnName = column.name; - Field field = column.field; - switch (column.type) { - case TYPE_STRING: - setIfNotNull(field, object, values.getAsString(columnName)); - break; - case TYPE_BOOLEAN: - setIfNotNull(field, object, values.getAsBoolean(columnName)); - break; - case TYPE_SHORT: - setIfNotNull(field, object, values.getAsShort(columnName)); - break; - case TYPE_INT: - setIfNotNull(field, object, values.getAsInteger(columnName)); - break; - case TYPE_LONG: - setIfNotNull(field, object, values.getAsLong(columnName)); - break; - case TYPE_FLOAT: - setIfNotNull(field, object, values.getAsFloat(columnName)); - break; - case TYPE_DOUBLE: - setIfNotNull(field, object, values.getAsDouble(columnName)); - break; - case TYPE_BLOB: - setIfNotNull(field, object, values.getAsByteArray(columnName)); - break; - } - } - return object; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - public void objectToValues(Entry object, ContentValues values) { - try { - for (ColumnInfo column : mColumnInfo) { - String columnName = column.name; - Field field = column.field; - switch (column.type) { - case TYPE_STRING: - values.put(columnName, (String) field.get(object)); - break; - case TYPE_BOOLEAN: - values.put(columnName, field.getBoolean(object)); - break; - case TYPE_SHORT: - values.put(columnName, field.getShort(object)); - break; - case TYPE_INT: - values.put(columnName, field.getInt(object)); - break; - case TYPE_LONG: - values.put(columnName, field.getLong(object)); - break; - case TYPE_FLOAT: - values.put(columnName, field.getFloat(object)); - break; - case TYPE_DOUBLE: - values.put(columnName, field.getDouble(object)); - break; - case TYPE_BLOB: - values.put(columnName, (byte[]) field.get(object)); - break; - } - } - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - public String toDebugString(Entry entry) { - try { - StringBuilder sb = new StringBuilder(); - sb.append("ID=").append(entry.id); - for (ColumnInfo column : mColumnInfo) { - String columnName = column.name; - Field field = column.field; - Object value = field.get(entry); - sb.append(" ").append(columnName).append("=") - .append((value == null) ? "null" : value.toString()); - } - return sb.toString(); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - public String toDebugString(Entry entry, String... columnNames) { - try { - StringBuilder sb = new StringBuilder(); - sb.append("ID=").append(entry.id); - for (String columnName : columnNames) { - ColumnInfo column = getColumn(columnName); - Field field = column.field; - Object value = field.get(entry); - sb.append(" ").append(columnName).append("=") - .append((value == null) ? "null" : value.toString()); - } - return sb.toString(); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - - public Cursor queryAll(SQLiteDatabase db) { - return db.query(mTableName, mProjection, null, null, null, null, null); - } - - public boolean queryWithId(SQLiteDatabase db, long id, Entry entry) { - Cursor cursor = db.query(mTableName, mProjection, "_id=?", - new String[] {Long.toString(id)}, null, null, null); - boolean success = false; - if (cursor.moveToFirst()) { - cursorToObject(cursor, entry); - success = true; - } - cursor.close(); - return success; - } - - public long insertOrReplace(SQLiteDatabase db, Entry entry) { - ContentValues values = new ContentValues(); - objectToValues(entry, values); - if (entry.id == 0) { - values.remove("_id"); - } - long id = db.replace(mTableName, "_id", values); - entry.id = id; - return id; - } - - public boolean deleteWithId(SQLiteDatabase db, long id) { - return db.delete(mTableName, "_id=?", new String[] { Long.toString(id) }) == 1; - } - - public void createTables(SQLiteDatabase db) { - // Wrapped class must have a @Table.Definition. - String tableName = mTableName; - Utils.assertTrue(tableName != null); - - // Add the CREATE TABLE statement for the main table. - StringBuilder sql = new StringBuilder("CREATE TABLE "); - sql.append(tableName); - sql.append(" (_id INTEGER PRIMARY KEY AUTOINCREMENT"); - StringBuilder unique = new StringBuilder(); - for (ColumnInfo column : mColumnInfo) { - if (!column.isId()) { - sql.append(','); - sql.append(column.name); - sql.append(' '); - sql.append(SQLITE_TYPES[column.type]); - if (!TextUtils.isEmpty(column.defaultValue)) { - sql.append(" DEFAULT "); - sql.append(column.defaultValue); - } - if (column.unique) { - if (unique.length() == 0) { - unique.append(column.name); - } else { - unique.append(',').append(column.name); - } - } - } - } - if (unique.length() > 0) { - sql.append(",UNIQUE(").append(unique).append(')'); - } - sql.append(");"); - logExecSql(db, sql.toString()); - sql.setLength(0); - - // Create indexes for all indexed columns. - for (ColumnInfo column : mColumnInfo) { - // Create an index on the indexed columns. - if (column.indexed) { - sql.append("CREATE INDEX "); - sql.append(tableName); - sql.append("_index_"); - sql.append(column.name); - sql.append(" ON "); - sql.append(tableName); - sql.append(" ("); - sql.append(column.name); - sql.append(");"); - logExecSql(db, sql.toString()); - sql.setLength(0); - } - } - - if (mHasFullTextIndex) { - // Add an FTS virtual table if using full-text search. - String ftsTableName = tableName + FULL_TEXT_INDEX_SUFFIX; - sql.append("CREATE VIRTUAL TABLE "); - sql.append(ftsTableName); - sql.append(" USING FTS3 (_id INTEGER PRIMARY KEY"); - for (ColumnInfo column : mColumnInfo) { - if (column.fullText) { - // Add the column to the FTS table. - String columnName = column.name; - sql.append(','); - sql.append(columnName); - sql.append(" TEXT"); - } - } - sql.append(");"); - logExecSql(db, sql.toString()); - sql.setLength(0); - - // Build an insert statement that will automatically keep the FTS - // table in sync. - StringBuilder insertSql = new StringBuilder("INSERT OR REPLACE INTO "); - insertSql.append(ftsTableName); - insertSql.append(" (_id"); - for (ColumnInfo column : mColumnInfo) { - if (column.fullText) { - insertSql.append(','); - insertSql.append(column.name); - } - } - insertSql.append(") VALUES (new._id"); - for (ColumnInfo column : mColumnInfo) { - if (column.fullText) { - insertSql.append(",new."); - insertSql.append(column.name); - } - } - insertSql.append(");"); - String insertSqlString = insertSql.toString(); - - // Add an insert trigger. - sql.append("CREATE TRIGGER "); - sql.append(tableName); - sql.append("_insert_trigger AFTER INSERT ON "); - sql.append(tableName); - sql.append(" FOR EACH ROW BEGIN "); - sql.append(insertSqlString); - sql.append("END;"); - logExecSql(db, sql.toString()); - sql.setLength(0); - - // Add an update trigger. - sql.append("CREATE TRIGGER "); - sql.append(tableName); - sql.append("_update_trigger AFTER UPDATE ON "); - sql.append(tableName); - sql.append(" FOR EACH ROW BEGIN "); - sql.append(insertSqlString); - sql.append("END;"); - logExecSql(db, sql.toString()); - sql.setLength(0); - - // Add a delete trigger. - sql.append("CREATE TRIGGER "); - sql.append(tableName); - sql.append("_delete_trigger AFTER DELETE ON "); - sql.append(tableName); - sql.append(" FOR EACH ROW BEGIN DELETE FROM "); - sql.append(ftsTableName); - sql.append(" WHERE _id = old._id; END;"); - logExecSql(db, sql.toString()); - sql.setLength(0); - } - } - - public void dropTables(SQLiteDatabase db) { - String tableName = mTableName; - StringBuilder sql = new StringBuilder("DROP TABLE IF EXISTS "); - sql.append(tableName); - sql.append(';'); - logExecSql(db, sql.toString()); - sql.setLength(0); - - if (mHasFullTextIndex) { - sql.append("DROP TABLE IF EXISTS "); - sql.append(tableName); - sql.append(FULL_TEXT_INDEX_SUFFIX); - sql.append(';'); - logExecSql(db, sql.toString()); - } - - } - - public void deleteAll(SQLiteDatabase db) { - StringBuilder sql = new StringBuilder("DELETE FROM "); - sql.append(mTableName); - sql.append(";"); - logExecSql(db, sql.toString()); - } - - private String parseTableName(Class<? extends Object> clazz) { - // Check for a table annotation. - Entry.Table table = clazz.getAnnotation(Entry.Table.class); - if (table == null) { - return null; - } - - // Return the table name. - return table.value(); - } - - private ColumnInfo[] parseColumnInfo(Class<? extends Object> clazz) { - ArrayList<ColumnInfo> columns = new ArrayList<ColumnInfo>(); - while (clazz != null) { - parseColumnInfo(clazz, columns); - clazz = clazz.getSuperclass(); - } - - // Return a list. - ColumnInfo[] columnList = new ColumnInfo[columns.size()]; - columns.toArray(columnList); - return columnList; - } - - private void parseColumnInfo(Class<? extends Object> clazz, ArrayList<ColumnInfo> columns) { - // Gather metadata from each annotated field. - Field[] fields = clazz.getDeclaredFields(); // including non-public fields - for (int i = 0; i != fields.length; ++i) { - // Get column metadata from the annotation. - Field field = fields[i]; - Entry.Column info = ((AnnotatedElement) field).getAnnotation(Entry.Column.class); - if (info == null) continue; - - // Determine the field type. - int type; - Class<?> fieldType = field.getType(); - if (fieldType == String.class) { - type = TYPE_STRING; - } else if (fieldType == boolean.class) { - type = TYPE_BOOLEAN; - } else if (fieldType == short.class) { - type = TYPE_SHORT; - } else if (fieldType == int.class) { - type = TYPE_INT; - } else if (fieldType == long.class) { - type = TYPE_LONG; - } else if (fieldType == float.class) { - type = TYPE_FLOAT; - } else if (fieldType == double.class) { - type = TYPE_DOUBLE; - } else if (fieldType == byte[].class) { - type = TYPE_BLOB; - } else { - throw new IllegalArgumentException( - "Unsupported field type for column: " + fieldType.getName()); - } - - // Add the column to the array. - int index = columns.size(); - columns.add(new ColumnInfo(info.value(), type, info.indexed(), info.unique(), - info.fullText(), info.defaultValue(), field, index)); - } - } - - public static final class ColumnInfo { - private static final String ID_KEY = "_id"; - - public final String name; - public final int type; - public final boolean indexed; - public final boolean unique; - public final boolean fullText; - public final String defaultValue; - public final Field field; - public final int projectionIndex; - - public ColumnInfo(String name, int type, boolean indexed, boolean unique, - boolean fullText, String defaultValue, Field field, int projectionIndex) { - this.name = name.toLowerCase(); - this.type = type; - this.indexed = indexed; - this.unique = unique; - this.fullText = fullText; - this.defaultValue = defaultValue; - this.field = field; - this.projectionIndex = projectionIndex; - - field.setAccessible(true); // in order to set non-public fields - } - - public boolean isId() { - return ID_KEY.equals(name); - } - } -} |