android_database_SQLiteCommon.cpp revision 9d25fa67a9291d469fa4006b2a373c8429132536
1/* 2 * Copyright (C) 2011 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#include "android_database_SQLiteCommon.h" 18 19namespace android { 20 21/* throw a SQLiteException with a message appropriate for the error in handle */ 22void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle) { 23 throw_sqlite3_exception(env, handle, NULL); 24} 25 26/* throw a SQLiteException with the given message */ 27void throw_sqlite3_exception(JNIEnv* env, const char* message) { 28 throw_sqlite3_exception(env, NULL, message); 29} 30 31/* throw a SQLiteException with a message appropriate for the error in handle 32 concatenated with the given message 33 */ 34void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle, const char* message) { 35 if (handle) { 36 // get the error code and message from the SQLite connection 37 // the error message may contain more information than the error code 38 // because it is based on the extended error code rather than the simplified 39 // error code that SQLite normally returns. 40 throw_sqlite3_exception(env, sqlite3_errcode(handle), sqlite3_errmsg(handle), message); 41 } else { 42 // we use SQLITE_OK so that a generic SQLiteException is thrown; 43 // any code not specified in the switch statement below would do. 44 throw_sqlite3_exception(env, SQLITE_OK, "unknown error", message); 45 } 46} 47 48/* throw a SQLiteException for a given error code 49 * should only be used when the database connection is not available because the 50 * error information will not be quite as rich */ 51void throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message) { 52 char temp[21]; 53 sprintf(temp, "error code %d", errcode); 54 throw_sqlite3_exception(env, errcode, temp, message); 55} 56 57/* throw a SQLiteException for a given error code, sqlite3message, and 58 user message 59 */ 60void throw_sqlite3_exception(JNIEnv* env, int errcode, 61 const char* sqlite3Message, const char* message) { 62 const char* exceptionClass; 63 switch (errcode) { 64 case SQLITE_IOERR: 65 exceptionClass = "android/database/sqlite/SQLiteDiskIOException"; 66 break; 67 case SQLITE_CORRUPT: 68 case SQLITE_NOTADB: // treat "unsupported file format" error as corruption also 69 exceptionClass = "android/database/sqlite/SQLiteDatabaseCorruptException"; 70 break; 71 case SQLITE_CONSTRAINT: 72 exceptionClass = "android/database/sqlite/SQLiteConstraintException"; 73 break; 74 case SQLITE_ABORT: 75 exceptionClass = "android/database/sqlite/SQLiteAbortException"; 76 break; 77 case SQLITE_DONE: 78 exceptionClass = "android/database/sqlite/SQLiteDoneException"; 79 sqlite3Message = NULL; // SQLite error message is irrelevant in this case 80 break; 81 case SQLITE_FULL: 82 exceptionClass = "android/database/sqlite/SQLiteFullException"; 83 break; 84 case SQLITE_MISUSE: 85 exceptionClass = "android/database/sqlite/SQLiteMisuseException"; 86 break; 87 case SQLITE_PERM: 88 exceptionClass = "android/database/sqlite/SQLiteAccessPermException"; 89 break; 90 case SQLITE_BUSY: 91 exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException"; 92 break; 93 case SQLITE_LOCKED: 94 exceptionClass = "android/database/sqlite/SQLiteTableLockedException"; 95 break; 96 case SQLITE_READONLY: 97 exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException"; 98 break; 99 case SQLITE_CANTOPEN: 100 exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException"; 101 break; 102 case SQLITE_TOOBIG: 103 exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException"; 104 break; 105 case SQLITE_RANGE: 106 exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException"; 107 break; 108 case SQLITE_NOMEM: 109 exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException"; 110 break; 111 case SQLITE_MISMATCH: 112 exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException"; 113 break; 114 case SQLITE_INTERRUPT: 115 exceptionClass = "android/os/OperationCanceledException"; 116 break; 117 default: 118 exceptionClass = "android/database/sqlite/SQLiteException"; 119 break; 120 } 121 122 if (sqlite3Message != NULL && message != NULL) { 123 char* fullMessage = (char *)malloc(strlen(sqlite3Message) + strlen(message) + 3); 124 if (fullMessage != NULL) { 125 strcpy(fullMessage, sqlite3Message); 126 strcat(fullMessage, ": "); 127 strcat(fullMessage, message); 128 jniThrowException(env, exceptionClass, fullMessage); 129 free(fullMessage); 130 } else { 131 jniThrowException(env, exceptionClass, sqlite3Message); 132 } 133 } else if (sqlite3Message != NULL) { 134 jniThrowException(env, exceptionClass, sqlite3Message); 135 } else { 136 jniThrowException(env, exceptionClass, message); 137 } 138} 139 140 141} // namespace android 142