private static RuntimeException getSqliteException(final String message, final int baseErrorCode) { // Mapping is from throw_sqlite3_exception in android_database_SQLiteCommon.cpp switch (baseErrorCode) { case SQLiteConstants.SQLITE_ABORT: return new SQLiteAbortException(message); case SQLiteConstants.SQLITE_PERM: return new SQLiteAccessPermException(message); case SQLiteConstants.SQLITE_RANGE: return new SQLiteBindOrColumnIndexOutOfRangeException(message); case SQLiteConstants.SQLITE_TOOBIG: return new SQLiteBlobTooBigException(message); case SQLiteConstants.SQLITE_CANTOPEN: return new SQLiteCantOpenDatabaseException(message); case SQLiteConstants.SQLITE_CONSTRAINT: return new SQLiteConstraintException(message); case SQLiteConstants.SQLITE_NOTADB: // fall through case SQLiteConstants.SQLITE_CORRUPT: return new SQLiteDatabaseCorruptException(message); case SQLiteConstants.SQLITE_BUSY: return new SQLiteDatabaseLockedException(message); case SQLiteConstants.SQLITE_MISMATCH: return new SQLiteDatatypeMismatchException(message); case SQLiteConstants.SQLITE_IOERR: return new SQLiteDiskIOException(message); case SQLiteConstants.SQLITE_DONE: return new SQLiteDoneException(message); case SQLiteConstants.SQLITE_FULL: return new SQLiteFullException(message); case SQLiteConstants.SQLITE_MISUSE: return new SQLiteMisuseException(message); case SQLiteConstants.SQLITE_NOMEM: return new SQLiteOutOfMemoryException(message); case SQLiteConstants.SQLITE_READONLY: return new SQLiteReadOnlyDatabaseException(message); case SQLiteConstants.SQLITE_LOCKED: return new SQLiteTableLockedException(message); case SQLiteConstants.SQLITE_INTERRUPT: return new OperationCanceledException(message); default: return new android.database.sqlite.SQLiteException(message + ", base error code: " + baseErrorCode); } } }
private void handleSQLiteFullException(final SQLiteFullException sqLiteFullException) { final int id = model.getId(); if (FileDownloadLog.NEED_LOG) { FileDownloadLog.d(this, "the data of the task[%d] is dirty, because the SQLite " + "full exception[%s], so remove it from the database directly.", id, sqLiteFullException.toString()); } model.setErrMsg(sqLiteFullException.toString()); model.setStatus(FileDownloadStatus.error); database.remove(id); database.removeConnections(id); }
@Test public void cursorFailsToCloseAfterPut() { /* Mocking instances. */ Context contextMock = mock(Context.class); SQLiteOpenHelper helperMock = mock(SQLiteOpenHelper.class); SQLiteDatabase sqLiteDatabase = mock(SQLiteDatabase.class); when(helperMock.getWritableDatabase()).thenReturn(sqLiteDatabase); /* Mock the select cursor we are using to find logs to evict to fail. */ mockStatic(SQLiteUtils.class); Cursor cursor = mock(Cursor.class); SQLiteDiskIOException exception = new SQLiteDiskIOException(); doThrow(exception).when(cursor).close(); when(cursor.moveToNext()).thenReturn(true).thenReturn(false); SQLiteQueryBuilder sqLiteQueryBuilder = mock(SQLiteQueryBuilder.class, new Returns(cursor)); when(SQLiteUtils.newSQLiteQueryBuilder()).thenReturn(sqLiteQueryBuilder); /* Simulate that database is full only once (will work after purging 1 log). */ when(sqLiteDatabase.insertOrThrow(anyString(), anyString(), any(ContentValues.class))).thenThrow(new SQLiteFullException()).thenReturn(1L); /* Instantiate real instance for DatabaseManager. */ DatabaseManager databaseManager = spy(new DatabaseManager(contextMock, "database", "table", 1, null, null)); databaseManager.setSQLiteOpenHelper(helperMock); /* When we put a log, it succeeds even if a problem occurred while closing purge cursor. */ long id = databaseManager.put(mock(ContentValues.class), "priority"); assertEquals(1, id); } }
@Test public void failsToDeleteLogDuringPutWhenFull() { /* Mocking instances. */ Context contextMock = mock(Context.class); SQLiteOpenHelper helperMock = mock(SQLiteOpenHelper.class); SQLiteDatabase sqLiteDatabase = mock(SQLiteDatabase.class); when(helperMock.getWritableDatabase()).thenReturn(sqLiteDatabase); /* Mock the select cursor we are using to find logs to evict to fail. */ mockStatic(SQLiteUtils.class); Cursor cursor = mock(Cursor.class); SQLiteDiskIOException fatalException = new SQLiteDiskIOException(); when(cursor.moveToNext()).thenThrow(fatalException); SQLiteQueryBuilder sqLiteQueryBuilder = mock(SQLiteQueryBuilder.class, new Returns(cursor)); when(SQLiteUtils.newSQLiteQueryBuilder()).thenReturn(sqLiteQueryBuilder); /* Simulate that database is full and that deletes fail because of the cursor. */ when(sqLiteDatabase.insertOrThrow(anyString(), anyString(), any(ContentValues.class))).thenThrow(new SQLiteFullException()); /* Instantiate real instance for DatabaseManager. */ DatabaseManager databaseManager = spy(new DatabaseManager(contextMock, "database", "table", 1, null, null)); databaseManager.setSQLiteOpenHelper(helperMock); /* When we put a log, it will fail to purge. */ assertEquals(-1, databaseManager.put(mock(ContentValues.class), "priority")); }
private RuntimeException getSqliteException(String message, int baseErrorCode) { // Mapping is from throw_sqlite3_exception in android_database_SQLiteCommon.cpp switch (baseErrorCode) { case SQLiteConstants.SQLITE_ABORT: return new SQLiteAbortException(message); case SQLiteConstants.SQLITE_PERM: return new SQLiteAccessPermException(message); case SQLiteConstants.SQLITE_RANGE: return new SQLiteBindOrColumnIndexOutOfRangeException(message); case SQLiteConstants.SQLITE_TOOBIG: return new SQLiteBlobTooBigException(message); case SQLiteConstants.SQLITE_CANTOPEN: return new SQLiteCantOpenDatabaseException(message); case SQLiteConstants.SQLITE_CONSTRAINT: return new SQLiteConstraintException(message); case SQLiteConstants.SQLITE_NOTADB: // fall through case SQLiteConstants.SQLITE_CORRUPT: return new SQLiteDatabaseCorruptException(message); case SQLiteConstants.SQLITE_BUSY: return new SQLiteDatabaseLockedException(message); case SQLiteConstants.SQLITE_MISMATCH: return new SQLiteDatatypeMismatchException(message); case SQLiteConstants.SQLITE_IOERR: return new SQLiteDiskIOException(message); case SQLiteConstants.SQLITE_DONE: return new SQLiteDoneException(message); case SQLiteConstants.SQLITE_FULL: return new SQLiteFullException(message); case SQLiteConstants.SQLITE_MISUSE: return new SQLiteMisuseException(message); case SQLiteConstants.SQLITE_NOMEM: return new SQLiteOutOfMemoryException(message); case SQLiteConstants.SQLITE_READONLY: return new SQLiteReadOnlyDatabaseException(message); case SQLiteConstants.SQLITE_LOCKED: return new SQLiteTableLockedException(message); case SQLiteConstants.SQLITE_INTERRUPT: return new OperationCanceledException(message); default: return new android.database.sqlite.SQLiteException(message + ", base error code: " + baseErrorCode); } } }
private RuntimeException getSqliteException(String message, int baseErrorCode) { // Mapping is from throw_sqlite3_exception in android_database_SQLiteCommon.cpp switch (baseErrorCode) { case SQLiteConstants.SQLITE_ABORT: return new SQLiteAbortException(message); case SQLiteConstants.SQLITE_PERM: return new SQLiteAccessPermException(message); case SQLiteConstants.SQLITE_RANGE: return new SQLiteBindOrColumnIndexOutOfRangeException(message); case SQLiteConstants.SQLITE_TOOBIG: return new SQLiteBlobTooBigException(message); case SQLiteConstants.SQLITE_CANTOPEN: return new SQLiteCantOpenDatabaseException(message); case SQLiteConstants.SQLITE_CONSTRAINT: return new SQLiteConstraintException(message); case SQLiteConstants.SQLITE_NOTADB: // fall through case SQLiteConstants.SQLITE_CORRUPT: return new SQLiteDatabaseCorruptException(message); case SQLiteConstants.SQLITE_BUSY: return new SQLiteDatabaseLockedException(message); case SQLiteConstants.SQLITE_MISMATCH: return new SQLiteDatatypeMismatchException(message); case SQLiteConstants.SQLITE_IOERR: return new SQLiteDiskIOException(message); case SQLiteConstants.SQLITE_DONE: return new SQLiteDoneException(message); case SQLiteConstants.SQLITE_FULL: return new SQLiteFullException(message); case SQLiteConstants.SQLITE_MISUSE: return new SQLiteMisuseException(message); case SQLiteConstants.SQLITE_NOMEM: return new SQLiteOutOfMemoryException(message); case SQLiteConstants.SQLITE_READONLY: return new SQLiteReadOnlyDatabaseException(message); case SQLiteConstants.SQLITE_LOCKED: return new SQLiteTableLockedException(message); case SQLiteConstants.SQLITE_INTERRUPT: return new OperationCanceledException(message); default: return new android.database.sqlite.SQLiteException(message + ", base error code: " + baseErrorCode); } } }
private static RuntimeException getSqliteException(final String message, final int baseErrorCode) { // Mapping is from throw_sqlite3_exception in android_database_SQLiteCommon.cpp switch (baseErrorCode) { case SQLiteConstants.SQLITE_ABORT: return new SQLiteAbortException(message); case SQLiteConstants.SQLITE_PERM: return new SQLiteAccessPermException(message); case SQLiteConstants.SQLITE_RANGE: return new SQLiteBindOrColumnIndexOutOfRangeException(message); case SQLiteConstants.SQLITE_TOOBIG: return new SQLiteBlobTooBigException(message); case SQLiteConstants.SQLITE_CANTOPEN: return new SQLiteCantOpenDatabaseException(message); case SQLiteConstants.SQLITE_CONSTRAINT: return new SQLiteConstraintException(message); case SQLiteConstants.SQLITE_NOTADB: // fall through case SQLiteConstants.SQLITE_CORRUPT: return new SQLiteDatabaseCorruptException(message); case SQLiteConstants.SQLITE_BUSY: return new SQLiteDatabaseLockedException(message); case SQLiteConstants.SQLITE_MISMATCH: return new SQLiteDatatypeMismatchException(message); case SQLiteConstants.SQLITE_IOERR: return new SQLiteDiskIOException(message); case SQLiteConstants.SQLITE_DONE: return new SQLiteDoneException(message); case SQLiteConstants.SQLITE_FULL: return new SQLiteFullException(message); case SQLiteConstants.SQLITE_MISUSE: return new SQLiteMisuseException(message); case SQLiteConstants.SQLITE_NOMEM: return new SQLiteOutOfMemoryException(message); case SQLiteConstants.SQLITE_READONLY: return new SQLiteReadOnlyDatabaseException(message); case SQLiteConstants.SQLITE_LOCKED: return new SQLiteTableLockedException(message); case SQLiteConstants.SQLITE_INTERRUPT: return new OperationCanceledException(message); default: return new android.database.sqlite.SQLiteException(message + ", base error code: " + baseErrorCode); } } }
private static RuntimeException getSqliteException(final String message, final int baseErrorCode) { // Mapping is from throw_sqlite3_exception in android_database_SQLiteCommon.cpp switch (baseErrorCode) { case SQLiteConstants.SQLITE_ABORT: return new SQLiteAbortException(message); case SQLiteConstants.SQLITE_PERM: return new SQLiteAccessPermException(message); case SQLiteConstants.SQLITE_RANGE: return new SQLiteBindOrColumnIndexOutOfRangeException(message); case SQLiteConstants.SQLITE_TOOBIG: return new SQLiteBlobTooBigException(message); case SQLiteConstants.SQLITE_CANTOPEN: return new SQLiteCantOpenDatabaseException(message); case SQLiteConstants.SQLITE_CONSTRAINT: return new SQLiteConstraintException(message); case SQLiteConstants.SQLITE_NOTADB: // fall through case SQLiteConstants.SQLITE_CORRUPT: return new SQLiteDatabaseCorruptException(message); case SQLiteConstants.SQLITE_BUSY: return new SQLiteDatabaseLockedException(message); case SQLiteConstants.SQLITE_MISMATCH: return new SQLiteDatatypeMismatchException(message); case SQLiteConstants.SQLITE_IOERR: return new SQLiteDiskIOException(message); case SQLiteConstants.SQLITE_DONE: return new SQLiteDoneException(message); case SQLiteConstants.SQLITE_FULL: return new SQLiteFullException(message); case SQLiteConstants.SQLITE_MISUSE: return new SQLiteMisuseException(message); case SQLiteConstants.SQLITE_NOMEM: return new SQLiteOutOfMemoryException(message); case SQLiteConstants.SQLITE_READONLY: return new SQLiteReadOnlyDatabaseException(message); case SQLiteConstants.SQLITE_LOCKED: return new SQLiteTableLockedException(message); case SQLiteConstants.SQLITE_INTERRUPT: return new OperationCanceledException(message); default: return new android.database.sqlite.SQLiteException(message + ", base error code: " + baseErrorCode); } } }