package com.gracecode.iZhihu.db; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteOpenHelper; import org.apache.http.HttpStatus; import java.io.File; import java.util.ArrayList; import java.util.List; public class ThumbnailsDatabase { private static final int DATABASE_VERSION = 1; private static final String FILE_DATABASE_NAME = "thumbnails.sqlite"; private static final String DATABASE_THUMBNAILS_TABLE_NAME = "thumbnails"; private static final String DIR_THUMBNAILS_NAME = "/thumbnails"; protected static final String COLUM_URL = "url"; protected static final String COLUM_LOCAL_PATH = "local"; protected static final String COLUM_HASH = "hash"; protected static final String COLUM_WIDTH = "width"; protected static final String COLUM_HEIGHT = "height"; protected static final String COLUM_SIZE = "size"; protected static final String COLUM_TIMESTAMP = "timeStamp"; protected static final String COLUM_ID = "id"; protected static final String COLUM_MIME_TYPE = "mimeType"; protected static final String COLUM_STATUS = "status"; private final static String[] SQL_CREATE_TABLES = { "CREATE TABLE " + DATABASE_THUMBNAILS_TABLE_NAME + " (" + COLUM_ID + " INTEGER PRIMARY KEY AUTOINCREMENT , " + COLUM_URL + " text NOT NULL UNIQUE," + COLUM_LOCAL_PATH + " text DEFAULT NULL UNIQUE," + COLUM_HASH + " text," + COLUM_STATUS + " int," + COLUM_MIME_TYPE + " text," + COLUM_TIMESTAMP + " long," + COLUM_SIZE + " long," + COLUM_WIDTH + " int," + COLUM_HEIGHT + " int" + ");", "CREATE INDEX " + COLUM_URL + "_idx ON " + DATABASE_THUMBNAILS_TABLE_NAME + "(" + COLUM_URL + ");", "CREATE INDEX " + COLUM_STATUS + "_idx ON " + DATABASE_THUMBNAILS_TABLE_NAME + "(" + COLUM_STATUS + ");", "CREATE INDEX " + COLUM_LOCAL_PATH + "_idx ON " + DATABASE_THUMBNAILS_TABLE_NAME + "(" + COLUM_LOCAL_PATH + ");" }; private final Context context; public void close() { } private static final class DatabaseOpenHelper extends SQLiteOpenHelper { public DatabaseOpenHelper(Context context) { super(context, (new File(context.getCacheDir(), FILE_DATABASE_NAME)).getAbsolutePath(), null, DATABASE_VERSION); } public DatabaseOpenHelper(Context context, String name) { super(context, name, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { for (String sql : SQL_CREATE_TABLES) { sqLiteDatabase.execSQL(sql); } } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i2) { } } public ThumbnailsDatabase(Context context) { this.context = context; } public File getLocalCacheDirectory() { File directory = new File(context.getCacheDir().getAbsolutePath() + DIR_THUMBNAILS_NAME); if (!directory.exists()) { directory.mkdirs(); } return directory; } /** * 增加到缓存列表中 * * @param url * @return */ public boolean add(String url) { if (isCached(url)) { return false; } SQLiteDatabase db = new DatabaseOpenHelper(context).getWritableDatabase(); try { ContentValues contentValues = new ContentValues(); contentValues.put(COLUM_URL, url); long values = db.insertOrThrow(DATABASE_THUMBNAILS_TABLE_NAME, null, contentValues); return values > 1; } catch (SQLiteException e) { return false; } finally { db.close(); } } /** * 获取已缓存的列表 * * @param url * @return */ public String getCachedPath(String url) { SQLiteDatabase db = new DatabaseOpenHelper(context).getReadableDatabase(); Cursor cursor = db.query(DATABASE_THUMBNAILS_TABLE_NAME, new String[]{COLUM_LOCAL_PATH}, COLUM_URL + "=?", new String[]{url}, null, null, null, "1"); try { cursor.moveToFirst(); int count = cursor.getCount(); int index = cursor.getColumnIndex(COLUM_LOCAL_PATH); String result = (count > 0) ? cursor.getString(index) : null; if (result == null) { result = ""; } return result.trim(); } finally { cursor.close(); db.close(); } } /** * 判断是否被缓存 * * @param url * @return */ public boolean isCached(String url) { String path = getCachedPath(url); return path.length() > 0; } /** * 清除数据 * * @return */ public void clearAll() { List<String> cachedThumbnails = getCachedThumbnails(); for (int i = 0, size = cachedThumbnails.size(); i < size; i++) { File thumbnail = new File(cachedThumbnails.get(i)); thumbnail.delete(); } SQLiteDatabase db = new DatabaseOpenHelper(context).getWritableDatabase(); try { db.delete(DATABASE_THUMBNAILS_TABLE_NAME, null, null); } finally { db.close(); } } public boolean markAsCached(String url, String localPath, String mimeType, int status) { File localPathFile = new File(localPath); if (!localPathFile.isFile() || !localPathFile.exists()) { return false; } SQLiteDatabase db = new DatabaseOpenHelper(context).getWritableDatabase(); ContentValues contentValues = new ContentValues(); contentValues.put(COLUM_LOCAL_PATH, localPath); contentValues.put(COLUM_WIDTH, com.gracecode.iZhihu.task.FetchThumbnailTask.DEFAULT_WIDTH); contentValues.put(COLUM_HEIGHT, com.gracecode.iZhihu.task.FetchThumbnailTask.DEFAULT_HEIGHT); contentValues.put(COLUM_SIZE, localPathFile.length()); contentValues.put(COLUM_MIME_TYPE, mimeType); contentValues.put(COLUM_TIMESTAMP, System.currentTimeMillis()); contentValues.put(COLUM_STATUS, status); try { int result = db.update(DATABASE_THUMBNAILS_TABLE_NAME, contentValues, COLUM_URL + " = ?", new String[]{url}); return result >= 1; } finally { db.close(); } } public List<String> getNotCachedThumbnails() { SQLiteDatabase db = new DatabaseOpenHelper(context).getReadableDatabase(); Cursor cursor = db.query(DATABASE_THUMBNAILS_TABLE_NAME, new String[]{COLUM_URL}, COLUM_LOCAL_PATH + " IS NULL AND " + COLUM_STATUS + " IS NULL", null, null, null, COLUM_ID + " DESC", null); int idxUrl = cursor.getColumnIndex(COLUM_URL); List<String> result = new ArrayList<String>(); try { for (int i = 0, count = cursor.getCount(); i < count; i++) { cursor.moveToPosition(i); result.add(cursor.getString(idxUrl)); } return result; } finally { cursor.close(); db.close(); } } public List<String> getCachedThumbnails() { SQLiteDatabase db = new DatabaseOpenHelper(context).getReadableDatabase(); Cursor cursor = db.query(DATABASE_THUMBNAILS_TABLE_NAME, new String[]{COLUM_LOCAL_PATH}, COLUM_LOCAL_PATH + " IS NULL AND " + COLUM_STATUS + "=" + HttpStatus.SC_OK, null, null, null, COLUM_ID + " DESC", null); int idxUrl = cursor.getColumnIndex(COLUM_LOCAL_PATH); List<String> result = new ArrayList<String>(); try { for (int i = 0, count = cursor.getCount(); i < count; i++) { cursor.moveToPosition(i); result.add(cursor.getString(idxUrl)); } return result; } finally { cursor.close(); db.close(); } } public int getTotalCachedCount() { SQLiteDatabase db = new DatabaseOpenHelper(context).getReadableDatabase(); Cursor cursor = db.query(DATABASE_THUMBNAILS_TABLE_NAME, new String[]{"COUNT(" + COLUM_ID + ") AS " + COLUM_ID}, COLUM_LOCAL_PATH + " NOT NULL AND " + COLUM_STATUS + "=" + HttpStatus.SC_OK, null, null, null, null, null); try { cursor.moveToFirst(); return cursor.getInt(cursor.getColumnIndex(COLUM_ID)); } finally { cursor.close(); db.close(); } } public long getTotalCachedSize() { SQLiteDatabase db = new DatabaseOpenHelper(context).getReadableDatabase(); Cursor cursor = db.query(DATABASE_THUMBNAILS_TABLE_NAME, new String[]{"SUM(" + COLUM_SIZE + ") AS " + COLUM_ID}, COLUM_LOCAL_PATH + " NOT NULL AND " + COLUM_STATUS + "=" + HttpStatus.SC_OK, null, null, null, null, null); try { cursor.moveToFirst(); return cursor.getLong(cursor.getColumnIndex(COLUM_ID)); } finally { cursor.close(); db.close(); } } }