Search in sources :

Example 6 with LockableDatabase

use of com.fsck.k9.mailstore.LockableDatabase in project k-9 by k9mail.

the class StoreSchemaDefinitionTest method createStoreSchemaDefinition.

private StoreSchemaDefinition createStoreSchemaDefinition() throws MessagingException {
    Context context = createContext();
    Account account = createAccount();
    LockableDatabase lockableDatabase = createLockableDatabase();
    LocalStore localStore = mock(LocalStore.class);
    localStore.database = lockableDatabase;
    when(localStore.getContext()).thenReturn(context);
    when(localStore.getAccount()).thenReturn(account);
    return new StoreSchemaDefinition(localStore);
}
Also used : Context(android.content.Context) Account(com.fsck.k9.Account)

Example 7 with LockableDatabase

use of com.fsck.k9.mailstore.LockableDatabase in project k-9 by k9mail.

the class LockableDatabase method execute.

/**
     * Execute a DB callback in a shared context (doesn't prevent concurrent
     * shared executions), taking care of locking the DB storage.
     *
     * <p>
     * Can be instructed to start a transaction if none is currently active in
     * the current thread. Callback will participate in any active transaction (no
     * inner transaction created).
     * </p>
     *
     * @param transactional
     *            <code>true</code> the callback must be executed in a
     *            transactional context.
     * @param callback
     *            Never <code>null</code>.
     * @return Whatever {@link DbCallback#doDbWork(SQLiteDatabase)} returns.
     * @throws UnavailableStorageException
     */
public <T> T execute(final boolean transactional, final DbCallback<T> callback) throws MessagingException {
    lockRead();
    final boolean doTransaction = transactional && inTransaction.get() == null;
    try {
        final boolean debug = K9.isDebug();
        if (doTransaction) {
            inTransaction.set(Boolean.TRUE);
            mDb.beginTransaction();
        }
        try {
            final T result = callback.doDbWork(mDb);
            if (doTransaction) {
                mDb.setTransactionSuccessful();
            }
            return result;
        } finally {
            if (doTransaction) {
                final long begin;
                if (debug) {
                    begin = System.currentTimeMillis();
                } else {
                    begin = 0L;
                }
                // not doing endTransaction in the same 'finally' block of unlockRead() because endTransaction() may throw an exception
                mDb.endTransaction();
                if (debug) {
                    Timber.v("LockableDatabase: Transaction ended, took %d ms / %s", currentTimeMillis() - begin, new Exception().getStackTrace()[1]);
                }
            }
        }
    } finally {
        if (doTransaction) {
            inTransaction.set(null);
        }
        unlockRead();
    }
}
Also used : SQLiteException(android.database.sqlite.SQLiteException) MessagingException(com.fsck.k9.mail.MessagingException)

Example 8 with LockableDatabase

use of com.fsck.k9.mailstore.LockableDatabase in project k-9 by k9mail.

the class EmailProvider method getThreadedMessages.

protected Cursor getThreadedMessages(String accountUuid, final String[] projection, final String selection, final String[] selectionArgs, final String sortOrder) {
    Account account = getAccount(accountUuid);
    LockableDatabase database = getDatabase(account);
    try {
        return database.execute(false, new DbCallback<Cursor>() {

            @Override
            public Cursor doDbWork(SQLiteDatabase db) throws WrappedException, UnavailableStorageException {
                StringBuilder query = new StringBuilder();
                query.append("SELECT ");
                boolean first = true;
                for (String columnName : projection) {
                    if (!first) {
                        query.append(",");
                    } else {
                        first = false;
                    }
                    final String aggregationFunc = THREAD_AGGREGATION_FUNCS.get(columnName);
                    if (MessageColumns.ID.equals(columnName)) {
                        query.append("m." + MessageColumns.ID + " AS " + MessageColumns.ID);
                    } else if (aggregationFunc != null) {
                        query.append("a.");
                        query.append(columnName);
                        query.append(" AS ");
                        query.append(columnName);
                    } else {
                        query.append(columnName);
                    }
                }
                query.append(" FROM (");
                createThreadedSubQuery(projection, selection, query);
                query.append(") a ");
                query.append("JOIN " + THREADS_TABLE + " t " + "ON (t." + ThreadColumns.ROOT + " = a.thread_root) " + "JOIN " + MESSAGES_TABLE + " m " + "ON (m." + MessageColumns.ID + " = t." + ThreadColumns.MESSAGE_ID + " AND " + "m." + InternalMessageColumns.EMPTY + "=0 AND " + "m." + InternalMessageColumns.DELETED + "=0 AND " + "m." + MessageColumns.DATE + " = a." + MessageColumns.DATE + ") ");
                if (Utility.arrayContainsAny(projection, (Object[]) FOLDERS_COLUMNS)) {
                    query.append("JOIN " + FOLDERS_TABLE + " f " + "ON (m." + MessageColumns.FOLDER_ID + " = f." + FolderColumns.ID + ") ");
                }
                query.append(" GROUP BY " + ThreadColumns.ROOT);
                if (!TextUtils.isEmpty(sortOrder)) {
                    query.append(" ORDER BY ");
                    query.append(SqlQueryBuilder.addPrefixToSelection(FIXUP_AGGREGATED_MESSAGES_COLUMNS, "a.", sortOrder));
                }
                return db.rawQuery(query.toString(), selectionArgs);
            }
        });
    } catch (UnavailableStorageException e) {
        throw new RuntimeException("Storage not available", e);
    } catch (MessagingException e) {
        throw new RuntimeException("messaging exception", e);
    }
}
Also used : Account(com.fsck.k9.Account) WrappedException(com.fsck.k9.mailstore.LockableDatabase.WrappedException) LockableDatabase(com.fsck.k9.mailstore.LockableDatabase) SQLiteDatabase(android.database.sqlite.SQLiteDatabase) MessagingException(com.fsck.k9.mail.MessagingException) UnavailableStorageException(com.fsck.k9.mailstore.UnavailableStorageException) EmailProviderCacheCursor(com.fsck.k9.cache.EmailProviderCacheCursor) Cursor(android.database.Cursor)

Aggregations

MessagingException (com.fsck.k9.mail.MessagingException)7 Account (com.fsck.k9.Account)5 Cursor (android.database.Cursor)4 SQLiteDatabase (android.database.sqlite.SQLiteDatabase)4 EmailProviderCacheCursor (com.fsck.k9.cache.EmailProviderCacheCursor)4 LockableDatabase (com.fsck.k9.mailstore.LockableDatabase)4 WrappedException (com.fsck.k9.mailstore.LockableDatabase.WrappedException)4 UnavailableStorageException (com.fsck.k9.mailstore.UnavailableStorageException)4 SQLiteException (android.database.sqlite.SQLiteException)3 File (java.io.File)2 Context (android.content.Context)1