5#if defined(_WIN32) || defined(_WIN64)
13#include <source_location>
15#include <system_error>
34 SQLINTEGER nativeErrorCode {};
35 std::string sqlState =
" ";
41 return FromHandle(SQL_HANDLE_DBC, hDbc);
47 return FromHandle(SQL_HANDLE_STMT, hStmt);
54 static SqlErrorInfo FromHandle(SQLSMALLINT handleType, SQLHANDLE handle)
57 info.message = std::string(1024,
'\0');
59 SQLSMALLINT msgLen {};
60 SQLGetDiagRecA(handleType,
63 (SQLCHAR*) info.sqlState.data(),
64 &info.nativeErrorCode,
65 (SQLCHAR*) info.message.data(),
66 (SQLSMALLINT) info.message.capacity(),
68 info.message.resize(msgLen);
73class SqlException:
public std::runtime_error
76 LIGHTWEIGHT_API
explicit SqlException(SqlErrorInfo info,
77 std::source_location location = std::source_location::current());
80 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE SqlErrorInfo
const& info() const noexcept
89enum class SqlError : std::int16_t
91 SUCCESS = SQL_SUCCESS,
92 SUCCESS_WITH_INFO = SQL_SUCCESS_WITH_INFO,
95 INVALID_HANDLE = SQL_INVALID_HANDLE,
96 STILL_EXECUTING = SQL_STILL_EXECUTING,
97 NEED_DATA = SQL_NEED_DATA,
98 PARAM_DATA_AVAILABLE = SQL_PARAM_DATA_AVAILABLE,
99 NO_DATA_FOUND = SQL_NO_DATA_FOUND,
100 UNSUPPORTED_TYPE = 1'000,
101 INVALID_ARGUMENT = 1'001,
102 TRANSACTION_ERROR = 1'002,
105struct SqlErrorCategory: std::error_category
108 static SqlErrorCategory
const& get() noexcept
110 static SqlErrorCategory
const category;
114 [[nodiscard]]
char const* name() const noexcept
override
116 return "Lightweight";
119 [[nodiscard]] std::string message(
int code)
const override
121 using namespace std::string_literals;
122 switch (
static_cast<SqlError
>(code))
124 case SqlError::SUCCESS:
125 return "SQL_SUCCESS"s;
126 case SqlError::SUCCESS_WITH_INFO:
127 return "SQL_SUCCESS_WITH_INFO"s;
128 case SqlError::NODATA:
129 return "SQL_NO_DATA"s;
130 case SqlError::FAILURE:
132 case SqlError::INVALID_HANDLE:
133 return "SQL_INVALID_HANDLE"s;
134 case SqlError::STILL_EXECUTING:
135 return "SQL_STILL_EXECUTING"s;
136 case SqlError::NEED_DATA:
137 return "SQL_NEED_DATA"s;
138 case SqlError::PARAM_DATA_AVAILABLE:
139 return "SQL_PARAM_DATA_AVAILABLE"s;
140 case SqlError::UNSUPPORTED_TYPE:
141 return "SQL_UNSUPPORTED_TYPE"s;
142 case SqlError::INVALID_ARGUMENT:
143 return "SQL_INVALID_ARGUMENT"s;
144 case SqlError::TRANSACTION_ERROR:
145 return "SQL_TRANSACTION_ERROR"s;
147 return std::format(
"SQL error code {}", code);
155struct std::is_error_code_enum<Lightweight::SqlError>:
public std::true_type
161inline std::error_code make_error_code(Lightweight::SqlError e)
163 return {
static_cast<int>(e), Lightweight::SqlErrorCategory::get() };
167struct std::formatter<Lightweight::SqlError>: formatter<std::string>
169 auto format(Lightweight::SqlError value, format_context& ctx)
const -> format_context::iterator
171 return formatter<std::string>::format(
172 std::format(
"{}", Lightweight::SqlErrorCategory().message(
static_cast<int>(value))), ctx);
177struct std::formatter<Lightweight::SqlErrorInfo>: formatter<std::string>
181 return formatter<std::string>::format(std::format(
"{} ({}) - {}", info.sqlState, info.nativeErrorCode, info.message),
Represents an ODBC SQL error.
static void RequireStatementSuccess(SQLRETURN result, SQLHSTMT hStmt, std::string_view message)
Asserts that the given result is a success code, otherwise throws an exception.
static SqlErrorInfo FromStatementHandle(SQLHSTMT hStmt)
Constructs an ODBC error info object from the given ODBC statement handle.
static SqlErrorInfo FromConnectionHandle(SQLHDBC hDbc)
Constructs an ODBC error info object from the given ODBC connection handle.