101 line
3.7 KiB
C
101 line
3.7 KiB
C
|
#pragma once
|
||
|
|
||
|
#include <string>
|
||
|
#include <stdexcept>
|
||
|
|
||
|
#include <sqlite3.h>
|
||
|
|
||
|
namespace sqlite
|
||
|
{
|
||
|
|
||
|
class sqlite_exception : public std::runtime_error
|
||
|
{
|
||
|
public:
|
||
|
sqlite_exception(const char *msg, std::string sql, int code = -1) : runtime_error(msg), code(code), sql(sql)
|
||
|
{
|
||
|
}
|
||
|
sqlite_exception(int code, std::string sql) : runtime_error(sqlite3_errstr(code)), code(code), sql(sql)
|
||
|
{
|
||
|
}
|
||
|
int get_code() const
|
||
|
{
|
||
|
return code & 0xFF;
|
||
|
}
|
||
|
int get_extended_code() const
|
||
|
{
|
||
|
return code;
|
||
|
}
|
||
|
std::string get_sql() const
|
||
|
{
|
||
|
return sql;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
int code;
|
||
|
std::string sql;
|
||
|
};
|
||
|
|
||
|
namespace errors
|
||
|
{
|
||
|
// One more or less trivial derived error class for each SQLITE error.
|
||
|
// Note the following are not errors so have no classes:
|
||
|
// SQLITE_OK, SQLITE_NOTICE, SQLITE_WARNING, SQLITE_ROW, SQLITE_DONE
|
||
|
//
|
||
|
// Note these names are exact matches to the names of the SQLITE error codes.
|
||
|
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME, name, derived) \
|
||
|
class name : public sqlite_exception \
|
||
|
{ \
|
||
|
using sqlite_exception::sqlite_exception; \
|
||
|
}; \
|
||
|
derived
|
||
|
#define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE, SUB, base, sub) \
|
||
|
class base##_##sub : public base \
|
||
|
{ \
|
||
|
using base::base; \
|
||
|
};
|
||
|
#include "lists/error_codes.h"
|
||
|
#undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED
|
||
|
#undef SQLITE_MODERN_CPP_ERROR_CODE
|
||
|
|
||
|
// Some additional errors are here for the C++ interface
|
||
|
class more_rows : public sqlite_exception
|
||
|
{
|
||
|
using sqlite_exception::sqlite_exception;
|
||
|
};
|
||
|
class no_rows : public sqlite_exception
|
||
|
{
|
||
|
using sqlite_exception::sqlite_exception;
|
||
|
};
|
||
|
class more_statements : public sqlite_exception
|
||
|
{
|
||
|
using sqlite_exception::sqlite_exception;
|
||
|
}; // Prepared statements can only contain one statement
|
||
|
class invalid_utf16 : public sqlite_exception
|
||
|
{
|
||
|
using sqlite_exception::sqlite_exception;
|
||
|
};
|
||
|
|
||
|
static void throw_sqlite_error(const int &error_code, const std::string &sql = "")
|
||
|
{
|
||
|
switch(error_code & 0xFF)
|
||
|
{
|
||
|
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME, name, derived) \
|
||
|
case SQLITE_##NAME: \
|
||
|
switch(error_code) \
|
||
|
{ \
|
||
|
derived default : throw name(error_code, sql); \
|
||
|
}
|
||
|
#define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE, SUB, base, sub) \
|
||
|
case SQLITE_##BASE##_##SUB: \
|
||
|
throw base##_##sub(error_code, sql);
|
||
|
#include "lists/error_codes.h"
|
||
|
#undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED
|
||
|
#undef SQLITE_MODERN_CPP_ERROR_CODE
|
||
|
default:
|
||
|
throw sqlite_exception(error_code, sql);
|
||
|
}
|
||
|
}
|
||
|
} // namespace errors
|
||
|
namespace exceptions = errors;
|
||
|
} // namespace sqlite
|