1e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/*
2e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Copyright (C) 2011 The Android Open Source Project
3e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown *
4e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
5e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * you may not use this file except in compliance with the License.
6e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * You may obtain a copy of the License at
7e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown *
8e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
9e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown *
10e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * Unless required by applicable law or agreed to in writing, software
11e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
12e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * See the License for the specific language governing permissions and
14e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown * limitations under the License.
15e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */
16e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
17e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown#include "android_database_SQLiteCommon.h"
18e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
19ca309f212d560673276aec0f4168a6c56131260cJeff Brown#include <utils/String8.h>
20ca309f212d560673276aec0f4168a6c56131260cJeff Brown
216e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov#include <map>
226e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov
23e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownnamespace android {
24e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
256e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolovstatic const std::map<int, std::string> sErrorCodesMap = {
266e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    // Primary Result Code List
276e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {4,     "SQLITE_ABORT"},
286e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {23,    "SQLITE_AUTH"},
296e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {5,     "SQLITE_BUSY"},
306e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {14,    "SQLITE_CANTOPEN"},
316e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {19,    "SQLITE_CONSTRAINT"},
326e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {11,    "SQLITE_CORRUPT"},
336e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {101,   "SQLITE_DONE"},
346e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {16,    "SQLITE_EMPTY"},
356e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1,     "SQLITE_ERROR"},
366e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {24,    "SQLITE_FORMAT"},
376e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {13,    "SQLITE_FULL"},
386e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {2,     "SQLITE_INTERNAL"},
396e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {9,     "SQLITE_INTERRUPT"},
406e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {10,    "SQLITE_IOERR"},
416e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {6,     "SQLITE_LOCKED"},
426e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {20,    "SQLITE_MISMATCH"},
436e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {21,    "SQLITE_MISUSE"},
446e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {22,    "SQLITE_NOLFS"},
456e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {7,     "SQLITE_NOMEM"},
466e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {26,    "SQLITE_NOTADB"},
476e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {12,    "SQLITE_NOTFOUND"},
486e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {27,    "SQLITE_NOTICE"},
496e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {0,     "SQLITE_OK"},
506e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {3,     "SQLITE_PERM"},
516e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {15,    "SQLITE_PROTOCOL"},
526e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {25,    "SQLITE_RANGE"},
536e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {8,     "SQLITE_READONLY"},
546e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {100,   "SQLITE_ROW"},
556e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {17,    "SQLITE_SCHEMA"},
566e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {18,    "SQLITE_TOOBIG"},
576e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {28,    "SQLITE_WARNING"},
586e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    // Extended Result Code List
596e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {516,   "SQLITE_ABORT_ROLLBACK"},
606e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {261,   "SQLITE_BUSY_RECOVERY"},
616e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {517,   "SQLITE_BUSY_SNAPSHOT"},
626e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1038,  "SQLITE_CANTOPEN_CONVPATH"},
636e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {782,   "SQLITE_CANTOPEN_FULLPATH"},
646e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {526,   "SQLITE_CANTOPEN_ISDIR"},
656e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {270,   "SQLITE_CANTOPEN_NOTEMPDIR"},
666e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {275,   "SQLITE_CONSTRAINT_CHECK"},
676e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {531,   "SQLITE_CONSTRAINT_COMMITHOOK"},
686e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {787,   "SQLITE_CONSTRAINT_FOREIGNKEY"},
696e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1043,  "SQLITE_CONSTRAINT_FUNCTION"},
706e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1299,  "SQLITE_CONSTRAINT_NOTNULL"},
716e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1555,  "SQLITE_CONSTRAINT_PRIMARYKEY"},
726e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {2579,  "SQLITE_CONSTRAINT_ROWID"},
736e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1811,  "SQLITE_CONSTRAINT_TRIGGER"},
746e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {2067,  "SQLITE_CONSTRAINT_UNIQUE"},
756e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {2323,  "SQLITE_CONSTRAINT_VTAB"},
766e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {267,   "SQLITE_CORRUPT_VTAB"},
776e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {3338,  "SQLITE_IOERR_ACCESS"},
786e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {2826,  "SQLITE_IOERR_BLOCKED"},
796e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {3594,  "SQLITE_IOERR_CHECKRESERVEDLOCK"},
806e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {4106,  "SQLITE_IOERR_CLOSE"},
816e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {6666,  "SQLITE_IOERR_CONVPATH"},
826e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {2570,  "SQLITE_IOERR_DELETE"},
836e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {5898,  "SQLITE_IOERR_DELETE_NOENT"},
846e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {4362,  "SQLITE_IOERR_DIR_CLOSE"},
856e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1290,  "SQLITE_IOERR_DIR_FSYNC"},
866e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1802,  "SQLITE_IOERR_FSTAT"},
876e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1034,  "SQLITE_IOERR_FSYNC"},
886e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {6410,  "SQLITE_IOERR_GETTEMPPATH"},
896e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {3850,  "SQLITE_IOERR_LOCK"},
906e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {6154,  "SQLITE_IOERR_MMAP"},
916e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {3082,  "SQLITE_IOERR_NOMEM"},
926e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {2314,  "SQLITE_IOERR_RDLOCK"},
936e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {266,   "SQLITE_IOERR_READ"},
946e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {5642,  "SQLITE_IOERR_SEEK"},
956e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {5130,  "SQLITE_IOERR_SHMLOCK"},
966e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {5386,  "SQLITE_IOERR_SHMMAP"},
976e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {4618,  "SQLITE_IOERR_SHMOPEN"},
986e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {4874,  "SQLITE_IOERR_SHMSIZE"},
996e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {522,   "SQLITE_IOERR_SHORT_READ"},
1006e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1546,  "SQLITE_IOERR_TRUNCATE"},
1016e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {2058,  "SQLITE_IOERR_UNLOCK"},
1026e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {778,   "SQLITE_IOERR_WRITE"},
1036e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {262,   "SQLITE_LOCKED_SHAREDCACHE"},
1046e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {539,   "SQLITE_NOTICE_RECOVER_ROLLBACK"},
1056e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {283,   "SQLITE_NOTICE_RECOVER_WAL"},
1066e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {256,   "SQLITE_OK_LOAD_PERMANENTLY"},
1076e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {520,   "SQLITE_READONLY_CANTLOCK"},
1086e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {1032,  "SQLITE_READONLY_DBMOVED"},
1096e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {264,   "SQLITE_READONLY_RECOVERY"},
1106e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {776,   "SQLITE_READONLY_ROLLBACK"},
1116e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    {284,   "SQLITE_WARNING_AUTOINDEX"},
1126e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov};
1136e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov
1146e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolovstatic std::string sqlite3_error_code_to_msg(int errcode) {
1156e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    auto it = sErrorCodesMap.find(errcode);
1166e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    if (it != sErrorCodesMap.end()) {
1176e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov        return std::to_string(errcode) + " " + it->second;
1186e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    } else {
1196e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov        return std::to_string(errcode);
1206e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov    }
1216e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov}
1226e98f468cda75aea95cebc173cd1ad9def1af315Fyodor Kupolov
123e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* throw a SQLiteException with a message appropriate for the error in handle */
124e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception(JNIEnv* env, sqlite3* handle) {
125e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    throw_sqlite3_exception(env, handle, NULL);
126e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown}
127e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
128e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* throw a SQLiteException with the given message */
129e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception(JNIEnv* env, const char* message) {
130e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    throw_sqlite3_exception(env, NULL, message);
131e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown}
132e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
133e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* throw a SQLiteException with a message appropriate for the error in handle
134e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown   concatenated with the given message
135e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */
136e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception(JNIEnv* env, sqlite3* handle, const char* message) {
137e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    if (handle) {
1389d25fa67a9291d469fa4006b2a373c8429132536Jeff Brown        // get the error code and message from the SQLite connection
1399d25fa67a9291d469fa4006b2a373c8429132536Jeff Brown        // the error message may contain more information than the error code
1409d25fa67a9291d469fa4006b2a373c8429132536Jeff Brown        // because it is based on the extended error code rather than the simplified
1419d25fa67a9291d469fa4006b2a373c8429132536Jeff Brown        // error code that SQLite normally returns.
142ca309f212d560673276aec0f4168a6c56131260cJeff Brown        throw_sqlite3_exception(env, sqlite3_extended_errcode(handle),
143ca309f212d560673276aec0f4168a6c56131260cJeff Brown                sqlite3_errmsg(handle), message);
144e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    } else {
145e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        // we use SQLITE_OK so that a generic SQLiteException is thrown;
146e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        // any code not specified in the switch statement below would do.
147e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        throw_sqlite3_exception(env, SQLITE_OK, "unknown error", message);
148e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    }
149e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown}
150e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
1519d25fa67a9291d469fa4006b2a373c8429132536Jeff Brown/* throw a SQLiteException for a given error code
1529d25fa67a9291d469fa4006b2a373c8429132536Jeff Brown * should only be used when the database connection is not available because the
1539d25fa67a9291d469fa4006b2a373c8429132536Jeff Brown * error information will not be quite as rich */
154e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message) {
155ca309f212d560673276aec0f4168a6c56131260cJeff Brown    throw_sqlite3_exception(env, errcode, "unknown error", message);
156e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown}
157e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
158e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown/* throw a SQLiteException for a given error code, sqlite3message, and
159e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown   user message
160e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown */
161e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brownvoid throw_sqlite3_exception(JNIEnv* env, int errcode,
162e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown                             const char* sqlite3Message, const char* message) {
163e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    const char* exceptionClass;
164ca309f212d560673276aec0f4168a6c56131260cJeff Brown    switch (errcode & 0xff) { /* mask off extended error code */
165e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_IOERR:
166e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            exceptionClass = "android/database/sqlite/SQLiteDiskIOException";
167e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            break;
168e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_CORRUPT:
169e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_NOTADB: // treat "unsupported file format" error as corruption also
170e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            exceptionClass = "android/database/sqlite/SQLiteDatabaseCorruptException";
171e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown            break;
172e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_CONSTRAINT:
17375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteConstraintException";
17475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
175e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_ABORT:
17675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteAbortException";
17775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
178e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_DONE:
17975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteDoneException";
1809d25fa67a9291d469fa4006b2a373c8429132536Jeff Brown            sqlite3Message = NULL; // SQLite error message is irrelevant in this case
18175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
182e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_FULL:
18375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteFullException";
18475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
185e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_MISUSE:
18675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteMisuseException";
18775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
188e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_PERM:
18975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteAccessPermException";
19075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
191e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_BUSY:
19275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException";
19375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
194e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_LOCKED:
19575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteTableLockedException";
19675ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
197e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_READONLY:
19875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException";
19975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
200e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_CANTOPEN:
20175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException";
20275ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
203e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_TOOBIG:
20475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException";
20575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
206e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_RANGE:
20775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
20875ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
209e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_NOMEM:
21075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException";
21175ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
212e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        case SQLITE_MISMATCH:
21375ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
21475ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
21575ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown        case SQLITE_INTERRUPT:
21625c934533fb81aa08e379ffe60e390dbbd12440cJeff Brown            exceptionClass = "android/os/OperationCanceledException";
21775ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
218e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        default:
21975ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            exceptionClass = "android/database/sqlite/SQLiteException";
22075ea64fc54f328d37b115cfb1ded1e45c30380edJeff Brown            break;
221e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    }
222e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
223ca309f212d560673276aec0f4168a6c56131260cJeff Brown    if (sqlite3Message) {
224ca309f212d560673276aec0f4168a6c56131260cJeff Brown        String8 fullMessage;
225ca309f212d560673276aec0f4168a6c56131260cJeff Brown        fullMessage.append(sqlite3Message);
226f02798b9f833469869c2642ce73f8d660c9c8ddfAndreas Gampe        std::string errcode_msg = sqlite3_error_code_to_msg(errcode);
227f02798b9f833469869c2642ce73f8d660c9c8ddfAndreas Gampe        fullMessage.appendFormat(" (code %s)", errcode_msg.c_str()); // print extended error code
228ca309f212d560673276aec0f4168a6c56131260cJeff Brown        if (message) {
229ca309f212d560673276aec0f4168a6c56131260cJeff Brown            fullMessage.append(": ");
230ca309f212d560673276aec0f4168a6c56131260cJeff Brown            fullMessage.append(message);
231e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        }
232ca309f212d560673276aec0f4168a6c56131260cJeff Brown        jniThrowException(env, exceptionClass, fullMessage.string());
233e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    } else {
234e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown        jniThrowException(env, exceptionClass, message);
235e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown    }
236e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown}
237e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
238e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown
239e5360fbf3efe85427f7e7f59afe7bbeddb4949acJeff Brown} // namespace android
240