blob: 46009bde75a884fbef4a737e7af5f4814dece7fe [file] [log] [blame]
Jeff Browne5360fb2011-10-31 17:48:13 -07001/*
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) {
Jeff Brown9d25fa62012-06-05 14:29:02 -070036 // 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);
Jeff Browne5360fb2011-10-31 17:48:13 -070041 } 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
Jeff Brown9d25fa62012-06-05 14:29:02 -070048/* 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 */
Jeff Browne5360fb2011-10-31 17:48:13 -070051void throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message) {
Jeff Brown9d25fa62012-06-05 14:29:02 -070052 char temp[21];
53 sprintf(temp, "error code %d", errcode);
54 throw_sqlite3_exception(env, errcode, temp, message);
Jeff Browne5360fb2011-10-31 17:48:13 -070055}
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:
Jeff Brown75ea64f2012-01-25 19:37:13 -080072 exceptionClass = "android/database/sqlite/SQLiteConstraintException";
73 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070074 case SQLITE_ABORT:
Jeff Brown75ea64f2012-01-25 19:37:13 -080075 exceptionClass = "android/database/sqlite/SQLiteAbortException";
76 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070077 case SQLITE_DONE:
Jeff Brown75ea64f2012-01-25 19:37:13 -080078 exceptionClass = "android/database/sqlite/SQLiteDoneException";
Jeff Brown9d25fa62012-06-05 14:29:02 -070079 sqlite3Message = NULL; // SQLite error message is irrelevant in this case
Jeff Brown75ea64f2012-01-25 19:37:13 -080080 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070081 case SQLITE_FULL:
Jeff Brown75ea64f2012-01-25 19:37:13 -080082 exceptionClass = "android/database/sqlite/SQLiteFullException";
83 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070084 case SQLITE_MISUSE:
Jeff Brown75ea64f2012-01-25 19:37:13 -080085 exceptionClass = "android/database/sqlite/SQLiteMisuseException";
86 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070087 case SQLITE_PERM:
Jeff Brown75ea64f2012-01-25 19:37:13 -080088 exceptionClass = "android/database/sqlite/SQLiteAccessPermException";
89 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070090 case SQLITE_BUSY:
Jeff Brown75ea64f2012-01-25 19:37:13 -080091 exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException";
92 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070093 case SQLITE_LOCKED:
Jeff Brown75ea64f2012-01-25 19:37:13 -080094 exceptionClass = "android/database/sqlite/SQLiteTableLockedException";
95 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070096 case SQLITE_READONLY:
Jeff Brown75ea64f2012-01-25 19:37:13 -080097 exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException";
98 break;
Jeff Browne5360fb2011-10-31 17:48:13 -070099 case SQLITE_CANTOPEN:
Jeff Brown75ea64f2012-01-25 19:37:13 -0800100 exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException";
101 break;
Jeff Browne5360fb2011-10-31 17:48:13 -0700102 case SQLITE_TOOBIG:
Jeff Brown75ea64f2012-01-25 19:37:13 -0800103 exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException";
104 break;
Jeff Browne5360fb2011-10-31 17:48:13 -0700105 case SQLITE_RANGE:
Jeff Brown75ea64f2012-01-25 19:37:13 -0800106 exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
107 break;
Jeff Browne5360fb2011-10-31 17:48:13 -0700108 case SQLITE_NOMEM:
Jeff Brown75ea64f2012-01-25 19:37:13 -0800109 exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException";
110 break;
Jeff Browne5360fb2011-10-31 17:48:13 -0700111 case SQLITE_MISMATCH:
Jeff Brown75ea64f2012-01-25 19:37:13 -0800112 exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
113 break;
114 case SQLITE_INTERRUPT:
Jeff Brown25c93452012-05-09 18:04:34 -0700115 exceptionClass = "android/os/OperationCanceledException";
Jeff Brown75ea64f2012-01-25 19:37:13 -0800116 break;
Jeff Browne5360fb2011-10-31 17:48:13 -0700117 default:
Jeff Brown75ea64f2012-01-25 19:37:13 -0800118 exceptionClass = "android/database/sqlite/SQLiteException";
119 break;
Jeff Browne5360fb2011-10-31 17:48:13 -0700120 }
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