#include <stdexcept>
#include <sqlite3.h>

namespace myapp::persistence {

class sqlite3_error : public std::runtime_error
{
public:
    explicit sqlite3_error(::sqlite3* db)
        : std::runtime_error(::sqlite3_errmsg(db))
        , errcode(::sqlite3_errcode(db))
        , extended_errcode(::sqlite3_extended_errcode(db))
    {
    }

    explicit sqlite3_error(int errcode)
        : std::runtime_error(::sqlite3_errstr(errcode))
        , errcode(errcode)
        , extended_errcode(0)
    {
    }

    explicit sqlite3_error(int errcode, char*& errmsg)
        : std::runtime_error(errmsg)
        , errcode(errcode)
        , extended_errcode(0)
    {
        ::sqlite3_free(errmsg);
        errmsg = nullptr;
    }

    using std::runtime_error::runtime_error;

    int error_code() const
    {
        return errcode;
    }

    int extended_error_code() const
    {
        return extended_errcode;
    }

private:
    int errcode;
    int extended_errcode;
};

static void throw_if_failed(int errcode)
{
    if (SQLITE_OK != errcode)
        throw sqlite3_error(errcode);
}

static void throw_if_failed(int errcode, char*& errmsg)
{
    if (SQLITE_OK != errcode)
        throw sqlite3_error(errcode, errmsg);
}

} /* namespace myapp::persistence */
