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
 |