1ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio/* 2ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * Copyright (C) 2010 The Android Open Source Project 3ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * 4ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License"); 5ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * you may not use this file except in compliance with the License. 6ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * You may obtain a copy of the License at 7ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * 8ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * http://www.apache.org/licenses/LICENSE-2.0 9ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * 10ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software 11ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS, 12ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * See the License for the specific language governing permissions and 14ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * limitations under the License. 15ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio */ 16ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 17ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Megliopackage com.android.providers.calendar; 18ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 19ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglioimport android.content.ContentValues; 20ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglioimport android.database.Cursor; 21ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglioimport android.database.sqlite.SQLiteDatabase; 22ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglioimport android.database.sqlite.SQLiteOpenHelper; 23ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglioimport android.util.Log; 24a637bc824d92888eec9c6d2da0d5f1e594bebebaFabrice Di Meglioimport com.google.common.annotations.VisibleForTesting; 25ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 26315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglioimport java.util.TimeZone; 27315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 28ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio/** 29ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * Class for managing a persistent Cache of (key, value) pairs. The persistent storage used is 30ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * a SQLite database. 31ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio */ 32ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Megliopublic class CalendarCache { 33ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio private static final String TAG = "CalendarCache"; 34ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 35ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public static final String DATABASE_NAME = "CalendarCache"; 36ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 37ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public static final String KEY_TIMEZONE_DATABASE_VERSION = "timezoneDatabaseVersion"; 38ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public static final String DEFAULT_TIMEZONE_DATABASE_VERSION = "2009s"; 39ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 40315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public static final String KEY_TIMEZONE_TYPE = "timezoneType"; 41315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public static final String TIMEZONE_TYPE_AUTO = "auto"; 42315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public static final String TIMEZONE_TYPE_HOME = "home"; 43315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 44315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public static final String KEY_TIMEZONE_INSTANCES = "timezoneInstances"; 45315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public static final String KEY_TIMEZONE_INSTANCES_PREVIOUS = "timezoneInstancesPrevious"; 46315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 477cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String COLUMN_NAME_ID = "_id"; 487cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String COLUMN_NAME_KEY = "key"; 497cb72fa3ea680dce378d8dac71f878e52e03f83aFabrice Di Meglio public static final String COLUMN_NAME_VALUE = "value"; 50ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 51ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio private static final String[] sProjection = { 52ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio COLUMN_NAME_KEY, 53ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio COLUMN_NAME_VALUE 54ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio }; 55ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 56ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio private static final int COLUMN_INDEX_KEY = 0; 57ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio private static final int COLUMN_INDEX_VALUE = 1; 58ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 59ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio private final SQLiteOpenHelper mOpenHelper; 60ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 61ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio /** 62ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * This exception is thrown when the cache encounter a null key or a null database reference 63ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio */ 64ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public static class CacheException extends Exception { 65ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public CacheException() { 66ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 67ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 68ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public CacheException(String detailMessage) { 69ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio super(detailMessage); 70ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 71ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 72ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 73ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public CalendarCache(SQLiteOpenHelper openHelper) { 74ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio mOpenHelper = openHelper; 75ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 76ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 77ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public void writeTimezoneDatabaseVersion(String timezoneDatabaseVersion) throws CacheException { 78315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio writeData(KEY_TIMEZONE_DATABASE_VERSION, timezoneDatabaseVersion); 79315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 80315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 81315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public String readTimezoneDatabaseVersion() { 82315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio try { 83315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio return readData(KEY_TIMEZONE_DATABASE_VERSION); 84315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } catch (CacheException e) { 85315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio Log.e(TAG, "Could not read timezone database version from CalendarCache"); 86315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 87315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio return null; 88ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 89ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 90a637bc824d92888eec9c6d2da0d5f1e594bebebaFabrice Di Meglio @VisibleForTesting 91315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public void writeTimezoneType(String timezoneType) throws CacheException { 92315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio writeData(KEY_TIMEZONE_TYPE, timezoneType); 93315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 94315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 95315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public String readTimezoneType() { 96315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio try { 97315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio return readData(KEY_TIMEZONE_TYPE); 98315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } catch (CacheException e) { 99315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio Log.e(TAG, "Cannot read timezone type from CalendarCache - using AUTO as default", e); 100315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 101315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio return TIMEZONE_TYPE_AUTO; 102315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 103315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 104315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public void writeTimezoneInstances(String timezone) { 105315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio try { 106315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio writeData(KEY_TIMEZONE_INSTANCES, timezone); 107315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } catch (CacheException e) { 108315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio Log.e(TAG, "Cannot write instances timezone to CalendarCache"); 109315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 110315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 111315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 112315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public String readTimezoneInstances() { 113315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio try { 114315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio return readData(KEY_TIMEZONE_INSTANCES); 115315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } catch (CacheException e) { 116315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio String localTimezone = TimeZone.getDefault().getID(); 117315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio Log.e(TAG, "Cannot read instances timezone from CalendarCache - using device one: " + 118315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio localTimezone, e); 119315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio return localTimezone; 120315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 121315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 122315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 123315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public void writeTimezoneInstancesPrevious(String timezone) { 124315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio try { 125315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio writeData(KEY_TIMEZONE_INSTANCES_PREVIOUS, timezone); 126315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } catch (CacheException e) { 127315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio Log.e(TAG, "Cannot write previous instance timezone to CalendarCache"); 128315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 129315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 130315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio 131315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio public String readTimezoneInstancesPrevious() { 132315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio try { 133315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio return readData(KEY_TIMEZONE_INSTANCES_PREVIOUS); 134315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } catch (CacheException e) { 135315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio Log.e(TAG, "Cannot read previous instances timezone from CalendarCache", e); 136315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio } 137315d9326acd39566959f3c547225483f1fb6aefcFabrice Di Meglio return null; 138ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 139ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 140ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio /** 141ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * Write a (key, value) pair in the Cache. 142ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * 143ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @param key the key (must not be null) 144ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @param value the value (can be null) 145ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @throws CacheException when key is null 146ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio */ 147ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public void writeData(String key, String value) throws CacheException { 148ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 149ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio db.beginTransaction(); 150ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio try { 151ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio writeDataLocked(db, key, value); 152ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio db.setTransactionSuccessful(); 153ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio if (Log.isLoggable(TAG, Log.VERBOSE)) { 154ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio Log.i(TAG, "Wrote (key, value) = [ " + key + ", " + value + "] "); 155ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 156ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } finally { 157ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio db.endTransaction(); 158ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 159ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 160ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 161ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio /** 162cad6bc946434363f6ba6fed58bfa818cd6736d21Andy McFadden * Write a (key, value) pair in the database used by the cache. This method should be called in 163ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * a transaction. 164ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * 165ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @param db the database (must not be null) 166ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @param key the key (must not be null) 167ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @param value the value 168ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @throws CacheException when key or database are null 169ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio */ 170ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio protected void writeDataLocked(SQLiteDatabase db, String key, String value) 171ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio throws CacheException { 172ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio if (null == db) { 173ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio throw new CacheException("Database cannot be null"); 174ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 175ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio if (null == key) { 176ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio throw new CacheException("Cannot use null key for write"); 177ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 178ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 179cad6bc946434363f6ba6fed58bfa818cd6736d21Andy McFadden /* 180cad6bc946434363f6ba6fed58bfa818cd6736d21Andy McFadden * Storing the hash code of a String into the _id column carries a (very) small risk 181cad6bc946434363f6ba6fed58bfa818cd6736d21Andy McFadden * of weird behavior, because we're using it as a unique key, but hash codes aren't 182cad6bc946434363f6ba6fed58bfa818cd6736d21Andy McFadden * guaranteed to be unique. CalendarCache has a small set of keys that are known 183cad6bc946434363f6ba6fed58bfa818cd6736d21Andy McFadden * ahead of time, so we should be okay. 184cad6bc946434363f6ba6fed58bfa818cd6736d21Andy McFadden */ 185ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio ContentValues values = new ContentValues(); 186ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio values.put(COLUMN_NAME_ID, key.hashCode()); 187ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio values.put(COLUMN_NAME_KEY, key); 188ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio values.put(COLUMN_NAME_VALUE, value); 189ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 190ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio db.replace(DATABASE_NAME, null /* null column hack */, values); 191ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 192ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 193ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio /** 194ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * Read a value from the database used by the cache and depending on a key. 195ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * 196ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @param key the key from which we want the value (must not be null) 197ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @return the value that was found for the key. Can be null if no key has been found 198ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @throws CacheException when key is null 199ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio */ 200ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio public String readData(String key) throws CacheException { 201ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 202ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio return readDataLocked(db, key); 203ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 204ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 205ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio /** 206ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * Read a value from the database used by the cache and depending on a key. The database should 207ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * be "readable" at minimum 208ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * 209ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @param db the database (must not be null) 210ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @param key the key from which we want the value (must not be null) 211ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @return the value that was found for the key. Can be null if no value has been found for the 212ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * key. 213ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio * @throws CacheException when key or database are null 214ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio */ 215ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio protected String readDataLocked(SQLiteDatabase db, String key) throws CacheException { 216ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio if (null == db) { 217ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio throw new CacheException("Database cannot be null"); 218ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 219ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio if (null == key) { 220ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio throw new CacheException("Cannot use null key for read"); 221ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 222ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 223ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio String rowValue = null; 224ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio 225ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio Cursor cursor = db.query(DATABASE_NAME, sProjection, 226ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio COLUMN_NAME_KEY + "=?", new String[] { key }, null, null, null); 227ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio try { 228ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio if (cursor.moveToNext()) { 229ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio rowValue = cursor.getString(COLUMN_INDEX_VALUE); 230ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 231ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio else { 232ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio if (Log.isLoggable(TAG, Log.VERBOSE)) { 233ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio Log.i(TAG, "Could not find key = [ " + key + " ]"); 234ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 235ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 236ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } finally { 237ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio cursor.close(); 238ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio cursor = null; 239ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 240ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio return rowValue; 241ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio } 242ae270e35e14b5c7a756050cb8dcccf5771743850Fabrice Di Meglio} 243