android_database_SQLiteCommon.cpp revision 25c934533fb81aa08e379ffe60e390dbbd12440c
1e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* 2e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Copyright (C) 2011 The Android Open Source Project 3e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 4e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * you may not use this file except in compliance with the License. 6e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * You may obtain a copy of the License at 7e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 8e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * 10e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Unless required by applicable law or agreed to in writing, software 11e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * See the License for the specific language governing permissions and 14e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * limitations under the License. 15e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */ 16e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 17e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown#include "android_database_SQLiteCommon.h" 18e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 19e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownnamespace android { 20e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 21e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* throw a SQLiteException with a message appropriate for the error in handle */ 22e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception(JNIEnv* env, sqlite3* handle) { 23e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw_sqlite3_exception(env, handle, NULL); 24e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown} 25e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 26e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* throw a SQLiteException with the given message */ 27e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception(JNIEnv* env, const char* message) { 28e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw_sqlite3_exception(env, NULL, message); 29e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown} 30e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 31e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* throw a SQLiteException with a message appropriate for the error in handle 32e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown concatenated with the given message 33e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */ 34e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception(JNIEnv* env, sqlite3* handle, const char* message) { 35e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (handle) { 36e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw_sqlite3_exception(env, sqlite3_errcode(handle), 37e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown sqlite3_errmsg(handle), message); 38e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } else { 39e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // we use SQLITE_OK so that a generic SQLiteException is thrown; 40e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown // any code not specified in the switch statement below would do. 41e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw_sqlite3_exception(env, SQLITE_OK, "unknown error", message); 42e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 43e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown} 44e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 45e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* throw a SQLiteException for a given error code */ 46e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message) { 47e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (errcode == SQLITE_DONE) { 48e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw_sqlite3_exception(env, errcode, NULL, message); 49e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } else { 50e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown char temp[21]; 51e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown sprintf(temp, "error code %d", errcode); 52e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown throw_sqlite3_exception(env, errcode, temp, message); 53e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 54e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown} 55e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 56e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* throw a SQLiteException for a given error code, sqlite3message, and 57e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown user message 58e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */ 59e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception(JNIEnv* env, int errcode, 60e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown const char* sqlite3Message, const char* message) { 61e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown const char* exceptionClass; 62e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown switch (errcode) { 63e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_IOERR: 64e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown exceptionClass = "android/database/sqlite/SQLiteDiskIOException"; 65e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown break; 66e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_CORRUPT: 67e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_NOTADB: // treat "unsupported file format" error as corruption also 68e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown exceptionClass = "android/database/sqlite/SQLiteDatabaseCorruptException"; 69e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown break; 70e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_CONSTRAINT: 7175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteConstraintException"; 7275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 73e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_ABORT: 7475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteAbortException"; 7575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 76e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_DONE: 7775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteDoneException"; 7875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 79e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_FULL: 8075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteFullException"; 8175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 82e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_MISUSE: 8375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteMisuseException"; 8475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 85e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_PERM: 8675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteAccessPermException"; 8775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 88e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_BUSY: 8975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException"; 9075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 91e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_LOCKED: 9275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteTableLockedException"; 9375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 94e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_READONLY: 9575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException"; 9675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 97e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_CANTOPEN: 9875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException"; 9975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 100e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_TOOBIG: 10175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException"; 10275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 103e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_RANGE: 10475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException"; 10575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 106e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_NOMEM: 10775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException"; 10875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 109e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown case SQLITE_MISMATCH: 11075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException"; 11175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 11275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown case SQLITE_INTERRUPT: 11325c934533fb81aa08e379ffe60e390dbbd12440cJeff Brown exceptionClass = "android/os/OperationCanceledException"; 11475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 115e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown default: 11675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown exceptionClass = "android/database/sqlite/SQLiteException"; 11775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown break; 118e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 119e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 120e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (sqlite3Message != NULL && message != NULL) { 121e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown char* fullMessage = (char *)malloc(strlen(sqlite3Message) + strlen(message) + 3); 122e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown if (fullMessage != NULL) { 123e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown strcpy(fullMessage, sqlite3Message); 124e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown strcat(fullMessage, ": "); 125e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown strcat(fullMessage, message); 126e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown jniThrowException(env, exceptionClass, fullMessage); 127e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown free(fullMessage); 128e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } else { 129e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown jniThrowException(env, exceptionClass, sqlite3Message); 130e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 131e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } else if (sqlite3Message != NULL) { 132e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown jniThrowException(env, exceptionClass, sqlite3Message); 133e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } else { 134e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown jniThrowException(env, exceptionClass, message); 135e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown } 136e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown} 137e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 138e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown 139e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown} // namespace android 140