ブログ@kaorun55

HoloLensやKinectなどのDepthセンサーを中心に書いています。

SQLite 例外クラス

手始めに例外クラスを作成。
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:例外クラス作成