android_database_SQLiteCommon.cpp revision 48a4789686412390f9efd3bad0bfcaa3efbf9bfc
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        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 */
46void 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 */
59void 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:
71           exceptionClass = "android/database/sqlite/SQLiteConstraintException";
72           break;
73        case SQLITE_ABORT:
74           exceptionClass = "android/database/sqlite/SQLiteAbortException";
75           break;
76        case SQLITE_DONE:
77           exceptionClass = "android/database/sqlite/SQLiteDoneException";
78           break;
79        case SQLITE_FULL:
80           exceptionClass = "android/database/sqlite/SQLiteFullException";
81           break;
82        case SQLITE_MISUSE:
83           exceptionClass = "android/database/sqlite/SQLiteMisuseException";
84           break;
85        case SQLITE_PERM:
86           exceptionClass = "android/database/sqlite/SQLiteAccessPermException";
87           break;
88        case SQLITE_BUSY:
89           exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException";
90           break;
91        case SQLITE_LOCKED:
92           exceptionClass = "android/database/sqlite/SQLiteTableLockedException";
93           break;
94        case SQLITE_READONLY:
95           exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException";
96           break;
97        case SQLITE_CANTOPEN:
98           exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException";
99           break;
100        case SQLITE_TOOBIG:
101           exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException";
102           break;
103        case SQLITE_RANGE:
104           exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
105           break;
106        case SQLITE_NOMEM:
107           exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException";
108           break;
109        case SQLITE_MISMATCH:
110           exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
111           break;
112        default:
113           exceptionClass = "android/database/sqlite/SQLiteException";
114           break;
115    }
116
117    if (sqlite3Message != NULL && message != NULL) {
118        char* fullMessage = (char *)malloc(strlen(sqlite3Message) + strlen(message) + 3);
119        if (fullMessage != NULL) {
120            strcpy(fullMessage, sqlite3Message);
121            strcat(fullMessage, ": ");
122            strcat(fullMessage, message);
123            jniThrowException(env, exceptionClass, fullMessage);
124            free(fullMessage);
125        } else {
126            jniThrowException(env, exceptionClass, sqlite3Message);
127        }
128    } else if (sqlite3Message != NULL) {
129        jniThrowException(env, exceptionClass, sqlite3Message);
130    } else {
131        jniThrowException(env, exceptionClass, message);
132    }
133}
134
135
136} // namespace android
137