| /* |
| * Copyright (C) 2010 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.providers.calendar; |
| |
| import android.content.ContentValues; |
| import android.database.Cursor; |
| import android.database.sqlite.SQLiteDatabase; |
| import android.database.sqlite.SQLiteOpenHelper; |
| import android.util.Log; |
| |
| /** |
| * Class for managing a persistent Cache of (key, value) pairs. The persistent storage used is |
| * a SQLite database. |
| */ |
| public class CalendarCache { |
| private static final String TAG = "CalendarCache"; |
| |
| public static final String DATABASE_NAME = "CalendarCache"; |
| |
| public static final String KEY_TIMEZONE_DATABASE_VERSION = "timezoneDatabaseVersion"; |
| public static final String DEFAULT_TIMEZONE_DATABASE_VERSION = "2009s"; |
| |
| private static final String COLUMN_NAME_ID = "_id"; |
| private static final String COLUMN_NAME_KEY = "key"; |
| private static final String COLUMN_NAME_VALUE = "value"; |
| |
| private static final String[] sProjection = { |
| COLUMN_NAME_KEY, |
| COLUMN_NAME_VALUE |
| }; |
| |
| private static final int COLUMN_INDEX_KEY = 0; |
| private static final int COLUMN_INDEX_VALUE = 1; |
| |
| private final SQLiteOpenHelper mOpenHelper; |
| |
| /** |
| * This exception is thrown when the cache encounter a null key or a null database reference |
| */ |
| public static class CacheException extends Exception { |
| public CacheException() { |
| } |
| |
| public CacheException(String detailMessage) { |
| super(detailMessage); |
| } |
| } |
| |
| public CalendarCache(SQLiteOpenHelper openHelper) { |
| mOpenHelper = openHelper; |
| } |
| |
| public void writeTimezoneDatabaseVersion(String timezoneDatabaseVersion) throws CacheException { |
| writeData(KEY_TIMEZONE_DATABASE_VERSION, |
| timezoneDatabaseVersion); |
| } |
| |
| public String readTimezoneDatabaseVersion() throws CacheException { |
| return readData(KEY_TIMEZONE_DATABASE_VERSION); |
| } |
| |
| /** |
| * Write a (key, value) pair in the Cache. |
| * |
| * @param key the key (must not be null) |
| * @param value the value (can be null) |
| * @throws CacheException when key is null |
| */ |
| public void writeData(String key, String value) throws CacheException { |
| SQLiteDatabase db = mOpenHelper.getReadableDatabase(); |
| db.beginTransaction(); |
| try { |
| writeDataLocked(db, key, value); |
| db.setTransactionSuccessful(); |
| if (Log.isLoggable(TAG, Log.VERBOSE)) { |
| Log.i(TAG, "Wrote (key, value) = [ " + key + ", " + value + "] "); |
| } |
| } finally { |
| db.endTransaction(); |
| } |
| } |
| |
| /** |
| * Write a (key, value) pair in the database used by the cache. This call should be called into |
| * a transaction. |
| * |
| * @param db the database (must not be null) |
| * @param key the key (must not be null) |
| * @param value the value |
| * @throws CacheException when key or database are null |
| */ |
| protected void writeDataLocked(SQLiteDatabase db, String key, String value) |
| throws CacheException { |
| if (null == db) { |
| throw new CacheException("Database cannot be null"); |
| } |
| if (null == key) { |
| throw new CacheException("Cannot use null key for write"); |
| } |
| |
| ContentValues values = new ContentValues(); |
| values.put(COLUMN_NAME_ID, key.hashCode()); |
| values.put(COLUMN_NAME_KEY, key); |
| values.put(COLUMN_NAME_VALUE, value); |
| |
| db.replace(DATABASE_NAME, null /* null column hack */, values); |
| } |
| |
| /** |
| * Read a value from the database used by the cache and depending on a key. |
| * |
| * @param key the key from which we want the value (must not be null) |
| * @return the value that was found for the key. Can be null if no key has been found |
| * @throws CacheException when key is null |
| */ |
| public String readData(String key) throws CacheException { |
| SQLiteDatabase db = mOpenHelper.getReadableDatabase(); |
| return readDataLocked(db, key); |
| } |
| |
| /** |
| * Read a value from the database used by the cache and depending on a key. The database should |
| * be "readable" at minimum |
| * |
| * @param db the database (must not be null) |
| * @param key the key from which we want the value (must not be null) |
| * @return the value that was found for the key. Can be null if no value has been found for the |
| * key. |
| * @throws CacheException when key or database are null |
| */ |
| protected String readDataLocked(SQLiteDatabase db, String key) throws CacheException { |
| if (null == db) { |
| throw new CacheException("Database cannot be null"); |
| } |
| if (null == key) { |
| throw new CacheException("Cannot use null key for read"); |
| } |
| |
| String rowValue = null; |
| |
| Cursor cursor = db.query(DATABASE_NAME, sProjection, |
| COLUMN_NAME_KEY + "=?", new String[] { key }, null, null, null); |
| try { |
| if (cursor.moveToNext()) { |
| rowValue = cursor.getString(COLUMN_INDEX_VALUE); |
| } |
| else { |
| if (Log.isLoggable(TAG, Log.VERBOSE)) { |
| Log.i(TAG, "Could not find key = [ " + key + " ]"); |
| } |
| } |
| } finally { |
| cursor.close(); |
| cursor = null; |
| } |
| return rowValue; |
| } |
| } |