FileDocCategorySizeDatePackage
LocalStore.javaAPI DocAndroid 1.5 API50454Wed May 06 22:42:46 BST 2009com.android.email.mail.store

LocalStore

public class LocalStore extends com.android.email.mail.Store
Implements a SQLite database backed local store for Messages.

Fields Summary
private static final int
DB_VERSION
History of database revisions. db version Shipped in Notes ---------- ---------- ----- 18 pre-1.0 Development versions. No upgrade path. 18 1.0, 1.1 1.0 Release version. 19 - Added message_id column to messages table. 20 1.5 Added content_id column to attachments table.
private static final com.android.email.mail.Flag[]
PERMANENT_FLAGS
private String
mPath
private android.database.sqlite.SQLiteDatabase
mDb
private File
mAttachmentsDir
private android.content.Context
mContext
Constructors Summary
public LocalStore(String _uri, android.content.Context context)

param
uri local://localhost/path/to/database/uuid.db


            
           
        mContext = context;
        URI uri = null;
        try {
            uri = new URI(_uri);
        } catch (Exception e) {
            throw new MessagingException("Invalid uri for LocalStore");
        }
        if (!uri.getScheme().equals("local")) {
            throw new MessagingException("Invalid scheme");
        }
        mPath = uri.getPath();

        File parentDir = new File(mPath).getParentFile();
        if (!parentDir.exists()) {
            parentDir.mkdirs();
        }
        mDb = SQLiteDatabase.openOrCreateDatabase(mPath, null);
        int oldVersion = mDb.getVersion();
  
        /*
         *  TODO we should have more sophisticated way to upgrade database.
         */
        if (oldVersion != DB_VERSION) {
            if (Config.LOGV) {
                Log.v(Email.LOG_TAG, String.format("Upgrading database from %d to %d", 
                        oldVersion, DB_VERSION));
            }
            if (oldVersion < 18) {
                /**
                 * Missing or old:  Create up-to-date tables
                 */
                mDb.execSQL("DROP TABLE IF EXISTS folders");
                mDb.execSQL("CREATE TABLE folders (id INTEGER PRIMARY KEY, name TEXT, "
                        + "last_updated INTEGER, unread_count INTEGER, visible_limit INTEGER)");

                mDb.execSQL("DROP TABLE IF EXISTS messages");
                mDb.execSQL("CREATE TABLE messages (id INTEGER PRIMARY KEY, folder_id INTEGER, " +
                        "uid TEXT, subject TEXT, date INTEGER, flags TEXT, sender_list TEXT, " +
                        "to_list TEXT, cc_list TEXT, bcc_list TEXT, reply_to_list TEXT, " +
                        "html_content TEXT, text_content TEXT, attachment_count INTEGER, " +
                        "internal_date INTEGER, message_id TEXT)");

                mDb.execSQL("DROP TABLE IF EXISTS attachments");
                mDb.execSQL("CREATE TABLE attachments (id INTEGER PRIMARY KEY, message_id INTEGER,"
                        + "store_data TEXT, content_uri TEXT, size INTEGER, name TEXT,"
                        + "mime_type TEXT, content_id TEXT)");

                mDb.execSQL("DROP TABLE IF EXISTS pending_commands");
                mDb.execSQL("CREATE TABLE pending_commands " +
                        "(id INTEGER PRIMARY KEY, command TEXT, arguments TEXT)");

                mDb.execSQL("DROP TRIGGER IF EXISTS delete_folder");
                mDb.execSQL("CREATE TRIGGER delete_folder BEFORE DELETE ON folders BEGIN DELETE FROM messages WHERE old.id = folder_id; END;");

                mDb.execSQL("DROP TRIGGER IF EXISTS delete_message");
                mDb.execSQL("CREATE TRIGGER delete_message BEFORE DELETE ON messages BEGIN DELETE FROM attachments WHERE old.id = message_id; END;");
                mDb.setVersion(DB_VERSION);
            }
            else {
                if (oldVersion < 19) {
                    /**
                     * Upgrade 18 to 19:  add message_id to messages table
                     */ 
                    mDb.execSQL("ALTER TABLE messages ADD COLUMN message_id TEXT;");
                    mDb.setVersion(19);
                }
                if (oldVersion < 20) {
                    /**
                     * Upgrade 19 to 20:  add content_id to attachments table
                     */ 
                    mDb.execSQL("ALTER TABLE attachments ADD COLUMN content_id TEXT;");
                    mDb.setVersion(20);
                }
            }

            if (mDb.getVersion() != DB_VERSION) {
                throw new Error("Database upgrade failed!");
            }
        }
        mAttachmentsDir = new File(mPath + "_att");
        if (!mAttachmentsDir.exists()) {
            mAttachmentsDir.mkdirs();
        }
    
Methods Summary
public voidaddPendingCommand(com.android.email.mail.store.LocalStore$PendingCommand command)

        try {
            for (int i = 0; i < command.arguments.length; i++) {
                command.arguments[i] = URLEncoder.encode(command.arguments[i], "UTF-8");
            }
            ContentValues cv = new ContentValues();
            cv.put("command", command.command);
            cv.put("arguments", Utility.combine(command.arguments, ',"));
            mDb.insert("pending_commands", "command", cv);
        }
        catch (UnsupportedEncodingException usee) {
            throw new Error("Aparently UTF-8 has been lost to the annals of history.");
        }
    
public voidcheckSettings()

    
public voiddelete()
Delete the entire Store and it's backing database.

        try {
            mDb.close();
        } catch (Exception e) {

        }
        try{
            File[] attachments = mAttachmentsDir.listFiles();
            for (File attachment : attachments) {
                if (attachment.exists()) {
                    attachment.delete();
                }
            }
            if (mAttachmentsDir.exists()) {
                mAttachmentsDir.delete();
            }
        }
        catch (Exception e) {
        }
        try {
            new File(mPath).delete();
        }
        catch (Exception e) {

        }
    
public com.android.email.mail.FoldergetFolder(java.lang.String name)

        return new LocalFolder(name);
    
public java.util.ArrayListgetPendingCommands()

        Cursor cursor = null;
        try {
            cursor = mDb.query("pending_commands",
                    new String[] { "id", "command", "arguments" },
                    null,
                    null,
                    null,
                    null,
                    "id ASC");
            ArrayList<PendingCommand> commands = new ArrayList<PendingCommand>();
            while (cursor.moveToNext()) {
                PendingCommand command = new PendingCommand();
                command.mId = cursor.getLong(0);
                command.command = cursor.getString(1);
                String arguments = cursor.getString(2);
                command.arguments = arguments.split(",");
                for (int i = 0; i < command.arguments.length; i++) {
                    command.arguments[i] = Utility.fastUrlDecode(command.arguments[i]);
                }
                commands.add(command);
            }
            return commands;
        }
        finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    
public com.android.email.mail.Folder[]getPersonalNamespaces()

        ArrayList<Folder> folders = new ArrayList<Folder>();
        Cursor cursor = null;
        try {
            cursor = mDb.rawQuery("SELECT name FROM folders", null);
            while (cursor.moveToNext()) {
                folders.add(new LocalFolder(cursor.getString(0)));
            }
        }
        finally {
            if (cursor != null) {
                cursor.close();
            }
        }
        return folders.toArray(new Folder[] {});
    
public voidpruneCachedAttachments()
Deletes all cached attachments for the entire store.

        File[] files = mAttachmentsDir.listFiles();
        for (File file : files) {
            if (file.exists()) {
                try {
                    Cursor cursor = null;
                    try {
                        cursor = mDb.query(
                            "attachments",
                            new String[] { "store_data" },
                            "id = ?",
                            new String[] { file.getName() },
                            null,
                            null,
                            null);
                        if (cursor.moveToNext()) {
                            if (cursor.getString(0) == null) {
                                /*
                                 * If the attachment has no store data it is not recoverable, so
                                 * we won't delete it.
                                 */
                                continue;
                            }
                        }
                    }
                    finally {
                        if (cursor != null) {
                            cursor.close();
                        }
                    }
                    ContentValues cv = new ContentValues();
                    cv.putNull("content_uri");
                    mDb.update("attachments", cv, "id = ?", new String[] { file.getName() });
                }
                catch (Exception e) {
                    /*
                     * If the row has gone away before we got to mark it not-downloaded that's
                     * okay.
                     */
                }
                if (!file.delete()) {
                    file.deleteOnExit();
                }
            }
        }
    
public voidremovePendingCommand(com.android.email.mail.store.LocalStore$PendingCommand command)

        mDb.delete("pending_commands", "id = ?", new String[] { Long.toString(command.mId) });
    
public voidresetVisibleLimits()

        ContentValues cv = new ContentValues();
        cv.put("visible_limit", Integer.toString(Email.DEFAULT_VISIBLE_LIMIT));
        mDb.update("folders", cv, null, null);