| /* |
| * Copyright (C) 2011 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "android_database_SQLiteCommon.h" |
| |
| namespace android { |
| |
| /* throw a SQLiteException with a message appropriate for the error in handle */ |
| void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle) { |
| throw_sqlite3_exception(env, handle, NULL); |
| } |
| |
| /* throw a SQLiteException with the given message */ |
| void throw_sqlite3_exception(JNIEnv* env, const char* message) { |
| throw_sqlite3_exception(env, NULL, message); |
| } |
| |
| /* throw a SQLiteException with a message appropriate for the error in handle |
| concatenated with the given message |
| */ |
| void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle, const char* message) { |
| if (handle) { |
| throw_sqlite3_exception(env, sqlite3_errcode(handle), |
| sqlite3_errmsg(handle), message); |
| } else { |
| // we use SQLITE_OK so that a generic SQLiteException is thrown; |
| // any code not specified in the switch statement below would do. |
| throw_sqlite3_exception(env, SQLITE_OK, "unknown error", message); |
| } |
| } |
| |
| /* throw a SQLiteException for a given error code */ |
| void throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message) { |
| if (errcode == SQLITE_DONE) { |
| throw_sqlite3_exception(env, errcode, NULL, message); |
| } else { |
| char temp[21]; |
| sprintf(temp, "error code %d", errcode); |
| throw_sqlite3_exception(env, errcode, temp, message); |
| } |
| } |
| |
| /* throw a SQLiteException for a given error code, sqlite3message, and |
| user message |
| */ |
| void throw_sqlite3_exception(JNIEnv* env, int errcode, |
| const char* sqlite3Message, const char* message) { |
| const char* exceptionClass; |
| switch (errcode) { |
| case SQLITE_IOERR: |
| exceptionClass = "android/database/sqlite/SQLiteDiskIOException"; |
| break; |
| case SQLITE_CORRUPT: |
| case SQLITE_NOTADB: // treat "unsupported file format" error as corruption also |
| exceptionClass = "android/database/sqlite/SQLiteDatabaseCorruptException"; |
| break; |
| case SQLITE_CONSTRAINT: |
| exceptionClass = "android/database/sqlite/SQLiteConstraintException"; |
| break; |
| case SQLITE_ABORT: |
| exceptionClass = "android/database/sqlite/SQLiteAbortException"; |
| break; |
| case SQLITE_DONE: |
| exceptionClass = "android/database/sqlite/SQLiteDoneException"; |
| break; |
| case SQLITE_FULL: |
| exceptionClass = "android/database/sqlite/SQLiteFullException"; |
| break; |
| case SQLITE_MISUSE: |
| exceptionClass = "android/database/sqlite/SQLiteMisuseException"; |
| break; |
| case SQLITE_PERM: |
| exceptionClass = "android/database/sqlite/SQLiteAccessPermException"; |
| break; |
| case SQLITE_BUSY: |
| exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException"; |
| break; |
| case SQLITE_LOCKED: |
| exceptionClass = "android/database/sqlite/SQLiteTableLockedException"; |
| break; |
| case SQLITE_READONLY: |
| exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException"; |
| break; |
| case SQLITE_CANTOPEN: |
| exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException"; |
| break; |
| case SQLITE_TOOBIG: |
| exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException"; |
| break; |
| case SQLITE_RANGE: |
| exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException"; |
| break; |
| case SQLITE_NOMEM: |
| exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException"; |
| break; |
| case SQLITE_MISMATCH: |
| exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException"; |
| break; |
| case SQLITE_INTERRUPT: |
| exceptionClass = "android/content/OperationCanceledException"; |
| break; |
| default: |
| exceptionClass = "android/database/sqlite/SQLiteException"; |
| break; |
| } |
| |
| if (sqlite3Message != NULL && message != NULL) { |
| char* fullMessage = (char *)malloc(strlen(sqlite3Message) + strlen(message) + 3); |
| if (fullMessage != NULL) { |
| strcpy(fullMessage, sqlite3Message); |
| strcat(fullMessage, ": "); |
| strcat(fullMessage, message); |
| jniThrowException(env, exceptionClass, fullMessage); |
| free(fullMessage); |
| } else { |
| jniThrowException(env, exceptionClass, sqlite3Message); |
| } |
| } else if (sqlite3Message != NULL) { |
| jniThrowException(env, exceptionClass, sqlite3Message); |
| } else { |
| jniThrowException(env, exceptionClass, message); |
| } |
| } |
| |
| |
| } // namespace android |