Home | History | Annotate | Download | only in calendar
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.providers.calendar;
     18 
     19 import android.content.ContentValues;
     20 import android.database.Cursor;
     21 import android.database.sqlite.SQLiteDatabase;
     22 import android.database.sqlite.SQLiteOpenHelper;
     23 import android.util.Log;
     24 
     25 /**
     26  * Class for managing a persistent Cache of (key, value) pairs. The persistent storage used is
     27  * a SQLite database.
     28  */
     29 public class CalendarCache {
     30     private static final String TAG = "CalendarCache";
     31 
     32     public static final String DATABASE_NAME = "CalendarCache";
     33 
     34     public static final String KEY_TIMEZONE_DATABASE_VERSION = "timezoneDatabaseVersion";
     35     public static final String DEFAULT_TIMEZONE_DATABASE_VERSION = "2009s";
     36 
     37     private static final String COLUMN_NAME_ID = "_id";
     38     private static final String COLUMN_NAME_KEY = "key";
     39     private static final String COLUMN_NAME_VALUE = "value";
     40 
     41     private static final String[] sProjection = {
     42         COLUMN_NAME_KEY,
     43         COLUMN_NAME_VALUE
     44     };
     45 
     46     private static final int COLUMN_INDEX_KEY = 0;
     47     private static final int COLUMN_INDEX_VALUE = 1;
     48 
     49     private final SQLiteOpenHelper mOpenHelper;
     50 
     51     /**
     52      * This exception is thrown when the cache encounter a null key or a null database reference
     53      */
     54     public static class CacheException extends Exception {
     55         public CacheException() {
     56         }
     57 
     58         public CacheException(String detailMessage) {
     59             super(detailMessage);
     60         }
     61     }
     62 
     63     public CalendarCache(SQLiteOpenHelper openHelper) {
     64         mOpenHelper = openHelper;
     65     }
     66 
     67     public void writeTimezoneDatabaseVersion(String timezoneDatabaseVersion) throws CacheException {
     68         writeData(KEY_TIMEZONE_DATABASE_VERSION,
     69                 timezoneDatabaseVersion);
     70     }
     71 
     72     public String readTimezoneDatabaseVersion() throws CacheException {
     73         return readData(KEY_TIMEZONE_DATABASE_VERSION);
     74     }
     75 
     76     /**
     77      * Write a (key, value) pair in the Cache.
     78      *
     79      * @param key the key (must not be null)
     80      * @param value the value (can be null)
     81      * @throws CacheException when key is null
     82      */
     83     public void writeData(String key, String value) throws CacheException {
     84         SQLiteDatabase db = mOpenHelper.getReadableDatabase();
     85         db.beginTransaction();
     86         try {
     87             writeDataLocked(db, key, value);
     88             db.setTransactionSuccessful();
     89             if (Log.isLoggable(TAG, Log.VERBOSE)) {
     90                 Log.i(TAG, "Wrote (key, value) = [ " + key + ", " + value + "] ");
     91             }
     92         } finally {
     93             db.endTransaction();
     94         }
     95     }
     96 
     97     /**
     98      * Write a (key, value) pair in the database used by the cache. This call should be called into
     99      * a transaction.
    100      *
    101      * @param db the database (must not be null)
    102      * @param key the key (must not be null)
    103      * @param value the value
    104      * @throws CacheException when key or database are null
    105      */
    106     protected void writeDataLocked(SQLiteDatabase db, String key, String value)
    107             throws CacheException {
    108         if (null == db) {
    109             throw new CacheException("Database cannot be null");
    110         }
    111         if (null == key) {
    112             throw new CacheException("Cannot use null key for write");
    113         }
    114 
    115         ContentValues values = new ContentValues();
    116         values.put(COLUMN_NAME_ID, key.hashCode());
    117         values.put(COLUMN_NAME_KEY, key);
    118         values.put(COLUMN_NAME_VALUE, value);
    119 
    120         db.replace(DATABASE_NAME, null /* null column hack */, values);
    121     }
    122 
    123     /**
    124      * Read a value from the database used by the cache and depending on a key.
    125      *
    126      * @param key the key from which we want the value (must not be null)
    127      * @return the value that was found for the key. Can be null if no key has been found
    128      * @throws CacheException when key is null
    129      */
    130     public String readData(String key) throws CacheException {
    131         SQLiteDatabase db = mOpenHelper.getReadableDatabase();
    132         return readDataLocked(db, key);
    133     }
    134 
    135     /**
    136      * Read a value from the database used by the cache and depending on a key. The database should
    137      * be "readable" at minimum
    138      *
    139      * @param db the database (must not be null)
    140      * @param key the key from which we want the value (must not be null)
    141      * @return the value that was found for the key. Can be null if no value has been found for the
    142      * key.
    143      * @throws CacheException when key or database are null
    144      */
    145     protected String readDataLocked(SQLiteDatabase db, String key) throws CacheException {
    146         if (null == db) {
    147             throw new CacheException("Database cannot be null");
    148         }
    149         if (null == key) {
    150             throw new CacheException("Cannot use null key for read");
    151         }
    152 
    153         String rowValue = null;
    154 
    155         Cursor cursor = db.query(DATABASE_NAME, sProjection,
    156                 COLUMN_NAME_KEY + "=?", new String[] { key }, null, null, null);
    157         try {
    158             if (cursor.moveToNext()) {
    159                 rowValue = cursor.getString(COLUMN_INDEX_VALUE);
    160             }
    161             else {
    162                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
    163                     Log.i(TAG, "Could not find key = [ " + key + " ]");
    164                 }
    165             }
    166         } finally {
    167             cursor.close();
    168             cursor = null;
    169         }
    170         return rowValue;
    171     }
    172 }
    173