139 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * 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.
 | |
|  */
 | |
| /*
 | |
| ** Modified to support SQLite extensions by the SQLite developers: 
 | |
| ** sqlite-dev@sqlite.org.
 | |
| */
 | |
| 
 | |
| #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) {
 | |
|         // get the error code and message from the SQLite connection
 | |
|         // the error message may contain more information than the error code
 | |
|         // because it is based on the extended error code rather than the simplified
 | |
|         // error code that SQLite normally returns.
 | |
|         throw_sqlite3_exception(env, sqlite3_extended_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
 | |
|  * should only be used when the database connection is not available because the
 | |
|  * error information will not be quite as rich */
 | |
| void throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message) {
 | |
|     throw_sqlite3_exception(env, errcode, "unknown error", 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 & 0xff) { /* mask off extended error code */
 | |
|         case SQLITE_IOERR:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteDiskIOException";
 | |
|             break;
 | |
|         case SQLITE_CORRUPT:
 | |
|         case SQLITE_NOTADB: // treat "unsupported file format" error as corruption also
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteDatabaseCorruptException";
 | |
|             break;
 | |
|         case SQLITE_CONSTRAINT:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteConstraintException";
 | |
|             break;
 | |
|         case SQLITE_ABORT:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteAbortException";
 | |
|             break;
 | |
|         case SQLITE_DONE:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteDoneException";
 | |
|             sqlite3Message = NULL; // SQLite error message is irrelevant in this case
 | |
|             break;
 | |
|         case SQLITE_FULL:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteFullException";
 | |
|             break;
 | |
|         case SQLITE_MISUSE:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteMisuseException";
 | |
|             break;
 | |
|         case SQLITE_PERM:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteAccessPermException";
 | |
|             break;
 | |
|         case SQLITE_BUSY:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteDatabaseLockedException";
 | |
|             break;
 | |
|         case SQLITE_LOCKED:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteTableLockedException";
 | |
|             break;
 | |
|         case SQLITE_READONLY:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteReadOnlyDatabaseException";
 | |
|             break;
 | |
|         case SQLITE_CANTOPEN:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteCantOpenDatabaseException";
 | |
|             break;
 | |
|         case SQLITE_TOOBIG:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteBlobTooBigException";
 | |
|             break;
 | |
|         case SQLITE_RANGE:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
 | |
|             break;
 | |
|         case SQLITE_NOMEM:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteOutOfMemoryException";
 | |
|             break;
 | |
|         case SQLITE_MISMATCH:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteDatatypeMismatchException";
 | |
|             break;
 | |
|         case SQLITE_INTERRUPT:
 | |
|             exceptionClass = "android/os/OperationCanceledException";
 | |
|             break;
 | |
|         default:
 | |
|             exceptionClass = "org/sqlite/database/sqlite/SQLiteException";
 | |
|             break;
 | |
|     }
 | |
| 
 | |
|     if (sqlite3Message) {
 | |
|         char *zFullmsg = sqlite3_mprintf(
 | |
|             "%s (code %d)%s%s", sqlite3Message, errcode, 
 | |
|             (message ? ": " : ""), (message ? message : "")
 | |
|         );
 | |
|         jniThrowException(env, exceptionClass, zFullmsg);
 | |
|         sqlite3_free(zFullmsg);
 | |
|     } else {
 | |
|         jniThrowException(env, exceptionClass, message);
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| } // namespace android
 |