手始めに例外クラスを作成。
SQLiteのライブラリ使ってる過程でエラーが出たら片っ端から例外なげます。
クラス作成の時はいつもここ*1から始めるくらい、例外大好き(笑)
#毎度のことですが、ご使用は自己責任で☆
まずはヘッダ(の一部)
/// SQLite ラッパークラス namespace sqlite { /// SQLite ライブラリ例外 class SQLiteException : public std::runtime_error { public: // コンストラクタ SQLiteException( int errorCode ); SQLiteException( int errorCode, char* errorMessage ); // エラーメッセージの取得 const char* what() const { return errorMessage_.c_str(); } // エラーコードとエラーメッセージの取得 int getErrorCode() const { return errorCode_; } const std::string& getErrorMessage() const { return errorMessage_; } // エラーコードからエラーメッセージを取得 static std::string getErrorMessage( int errorCode ); private: int errorCode_; ///< エラーコード std::string errorMessage_; ///< エラーメッセージ }; } // namespace sqlite
次に、例外メッセージの構造体(ソースファイルの一部)
namespace { /// エラーメッセージテーブル const struct { int errorCode; const char* errorMessage; } errorMap[] = { { SQLITE_OK, "Successful result" }, { SQLITE_ERROR, "SQL error or missing database" }, { SQLITE_INTERNAL, "Internal logic error in SQLite" }, { SQLITE_PERM, "Access permission denied" }, { SQLITE_ABORT, "Callback routine requested an abort" }, { SQLITE_BUSY, "The database file is locked" }, { SQLITE_LOCKED, "A table in the database is locked" }, { SQLITE_NOMEM, "A malloc() failed" }, { SQLITE_READONLY, "Attempt to write a readonly database" }, { SQLITE_INTERRUPT, "Operation terminated by sqlite3_interrupt()" }, { SQLITE_IOERR, "Some kind of disk I/O error occurred" }, { SQLITE_CORRUPT, "The database disk image is malformed" }, { SQLITE_NOTFOUND, "NOT USED. Table or record not found" }, { SQLITE_FULL, "Insertion failed because database is full" }, { SQLITE_CANTOPEN, "Unable to open the database file" }, { SQLITE_PROTOCOL, "NOT USED. Database lock protocol error" }, { SQLITE_EMPTY, "Database is empty" }, { SQLITE_SCHEMA, "The database schema changed" }, { SQLITE_TOOBIG, "String or BLOB exceeds size limit" }, { SQLITE_CONSTRAINT, "Abort due to constraint violation" }, { SQLITE_MISMATCH, "Data type mismatch" }, { SQLITE_MISUSE, "Library used incorrectly" }, { SQLITE_NOLFS, "Uses OS features not supported on host" }, { SQLITE_AUTH, "Authorization denied" }, { SQLITE_FORMAT, "Auxiliary database format error" }, { SQLITE_RANGE, "2nd parameter to sqlite3_bind out of range" }, { SQLITE_NOTADB, "File opened that is not a database file" }, { SQLITE_ROW, "sqlite3_step() has another row ready" }, { SQLITE_DONE, "sqlite3_step() has finished executing" }, }; /// エラーメッセージテーブルサイズ const int errorMapCount = sizeof(errorMap) / sizeof(errorMap[0]); } // namespace
最後に、例外クラスの実装(ソースファイルの一部)
/// SQLite ラッパークラス namespace sqlite { // コンストラクタ SQLiteException::SQLiteException( int errorCode ) : std::runtime_error( "" ) , errorCode_( errorCode ) , errorMessage_( getErrorMessage( errorCode ) ) { } SQLiteException::SQLiteException( int errorCode, char* errorMessage ) : std::runtime_error( "" ) , errorCode_( errorCode ) , errorMessage_( errorMessage ) { } // エラーコードからエラーメッセージを取得 /*static*/ std::string SQLiteException::getErrorMessage( int errorCode ) { int i; for ( i = 0; i < errorMapCount; ++i ) { if ( errorCode == errorMap[i].errorCode ) { break; } } return (i < errorMapCount) ? errorMap[i].errorMessage : "Unknown error code"; } } // namespace sqlite
お次は、メインのSQLiteデータベースクラス
*1:例外クラス作成