Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 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 | |
| 19 | namespace android { |
| 20 | |
| 21 | /* throw a SQLiteException with a message appropriate for the error in handle */ |
| 22 | void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle) { |
| 23 | throw_sqlite3_exception(env, handle, NULL); |
| 24 | } |
| 25 | |
| 26 | /* throw a SQLiteException with the given message */ |
| 27 | void 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 | */ |
| 34 | void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle, const char* message) { |
| 35 | if (handle) { |
| 36 | throw_sqlite3_exception(env, sqlite3_errcode(handle), |
| 37 | sqlite3_errmsg(handle), message); |
| 38 | } else { |
| 39 | // we use SQLITE_OK so that a generic SQLiteException is thrown; |
| 40 | // any code not specified in the switch statement below would do. |
| 41 | throw_sqlite3_exception(env, SQLITE_OK, "unknown error", message); |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | /* throw a SQLiteException for a given error code */ |
| 46 | void throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message) { |
| 47 | if (errcode == SQLITE_DONE) { |
| 48 | throw_sqlite3_exception(env, errcode, NULL, message); |
| 49 | } else { |
| 50 | char temp[21]; |
| 51 | sprintf(temp, "error code %d", errcode); |
| 52 | throw_sqlite3_exception(env, errcode, temp, message); |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | /* throw a SQLiteException for a given error code, sqlite3message, and |
| 57 | user message |
| 58 | */ |
| 59 | void throw_sqlite3_exception(JNIEnv* env, int errcode, |
| 60 | const char* sqlite3Message, const char* message) { |
| 61 | const char* exceptionClass; |
| 62 | switch (errcode) { |
| 63 | case SQLITE_IOERR: |
| 64 | exceptionClass = "android/database/sqlite/SQLiteDiskIOException"; |
| 65 | break; |
| 66 | case SQLITE_CORRUPT: |
| 67 | case SQLITE_NOTADB: // treat "unsupported file format" error as corruption also |
| 68 | exceptionClass = "android/database/sqlite/SQLiteDatabaseCorruptException"; |
| 69 | break; |
| 70 | case SQLITE_CONSTRAINT: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 71 | exceptionClass = "android/database/sqlite/SQLiteConstraintException"; |
| 72 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 73 | case SQLITE_ABORT: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 74 | exceptionClass = "android/database/sqlite/SQLiteAbortException"; |
| 75 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 76 | case SQLITE_DONE: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 77 | exceptionClass = "android/database/sqlite/SQLiteDoneException"; |
| 78 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 79 | case SQLITE_FULL: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 80 | exceptionClass = "android/database/sqlite/SQLiteFullException"; |
| 81 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 82 | case SQLITE_MISUSE: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 83 | exceptionClass = "android/database/sqlite/SQLiteMisuseException"; |
| 84 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 85 | case SQLITE_PERM: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 86 | exceptionClass = "android/database/sqlite/SQLiteAccessPermException"; |
| 87 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 88 | case SQLITE_BUSY: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 89 | exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException"; |
| 90 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 91 | case SQLITE_LOCKED: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 92 | exceptionClass = "android/database/sqlite/SQLiteTableLockedException"; |
| 93 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 94 | case SQLITE_READONLY: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 95 | exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException"; |
| 96 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 97 | case SQLITE_CANTOPEN: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 98 | exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException"; |
| 99 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 100 | case SQLITE_TOOBIG: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 101 | exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException"; |
| 102 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 103 | case SQLITE_RANGE: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 104 | exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException"; |
| 105 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 106 | case SQLITE_NOMEM: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 107 | exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException"; |
| 108 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 109 | case SQLITE_MISMATCH: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 110 | exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException"; |
| 111 | break; |
| 112 | case SQLITE_INTERRUPT: |
Jeff Brown | 25c9345 | 2012-05-09 18:04:34 -0700 | [diff] [blame^] | 113 | exceptionClass = "android/os/OperationCanceledException"; |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 114 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 115 | default: |
Jeff Brown | 75ea64f | 2012-01-25 19:37:13 -0800 | [diff] [blame] | 116 | exceptionClass = "android/database/sqlite/SQLiteException"; |
| 117 | break; |
Jeff Brown | e5360fb | 2011-10-31 17:48:13 -0700 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | if (sqlite3Message != NULL && message != NULL) { |
| 121 | char* fullMessage = (char *)malloc(strlen(sqlite3Message) + strlen(message) + 3); |
| 122 | if (fullMessage != NULL) { |
| 123 | strcpy(fullMessage, sqlite3Message); |
| 124 | strcat(fullMessage, ": "); |
| 125 | strcat(fullMessage, message); |
| 126 | jniThrowException(env, exceptionClass, fullMessage); |
| 127 | free(fullMessage); |
| 128 | } else { |
| 129 | jniThrowException(env, exceptionClass, sqlite3Message); |
| 130 | } |
| 131 | } else if (sqlite3Message != NULL) { |
| 132 | jniThrowException(env, exceptionClass, sqlite3Message); |
| 133 | } else { |
| 134 | jniThrowException(env, exceptionClass, message); |
| 135 | } |
| 136 | } |
| 137 | |
| 138 | |
| 139 | } // namespace android |