5#if defined(_WIN32) || defined(_WIN64)
13#include <source_location>
15#include <system_error>
44 return FromHandle(SQL_HANDLE_DBC, hDbc);
50 return FromHandle(SQL_HANDLE_STMT, hStmt);
56 return FromHandle(SQL_HANDLE_ENV, hEnv);
63 LIGHTWEIGHT_API
static SqlErrorInfo FromHandle(SQLSMALLINT handleType, SQLHANDLE handle);
107class SqlException: public std::runtime_error
110 LIGHTWEIGHT_API
explicit SqlException(
SqlErrorInfo info,
111 std::source_location location = std::source_location::current());
114 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
SqlErrorInfo const& info() const noexcept
123enum class SqlError : std::int16_t
125 SUCCESS = SQL_SUCCESS,
126 SUCCESS_WITH_INFO = SQL_SUCCESS_WITH_INFO,
127 NODATA = SQL_NO_DATA,
129 INVALID_HANDLE = SQL_INVALID_HANDLE,
130 STILL_EXECUTING = SQL_STILL_EXECUTING,
131 NEED_DATA = SQL_NEED_DATA,
132 PARAM_DATA_AVAILABLE = SQL_PARAM_DATA_AVAILABLE,
133 NO_DATA_FOUND = SQL_NO_DATA_FOUND,
134 UNSUPPORTED_TYPE = 1'000,
135 INVALID_ARGUMENT = 1'001,
136 TRANSACTION_ERROR = 1'002,
139struct SqlErrorCategory: std::error_category
142 static SqlErrorCategory
const& get() noexcept
144 static SqlErrorCategory
const category;
148 [[nodiscard]]
char const* name() const noexcept
override
150 return "Lightweight";
153 [[nodiscard]] std::string message(
int code)
const override
155 using namespace std::string_literals;
156 switch (
static_cast<SqlError
>(code))
158 case SqlError::SUCCESS:
159 return "SQL_SUCCESS"s;
160 case SqlError::SUCCESS_WITH_INFO:
161 return "SQL_SUCCESS_WITH_INFO"s;
162 case SqlError::NODATA:
163 return "SQL_NO_DATA"s;
164 case SqlError::FAILURE:
166 case SqlError::INVALID_HANDLE:
167 return "SQL_INVALID_HANDLE"s;
168 case SqlError::STILL_EXECUTING:
169 return "SQL_STILL_EXECUTING"s;
170 case SqlError::NEED_DATA:
171 return "SQL_NEED_DATA"s;
172 case SqlError::PARAM_DATA_AVAILABLE:
173 return "SQL_PARAM_DATA_AVAILABLE"s;
174 case SqlError::UNSUPPORTED_TYPE:
175 return "SQL_UNSUPPORTED_TYPE"s;
176 case SqlError::INVALID_ARGUMENT:
177 return "SQL_INVALID_ARGUMENT"s;
178 case SqlError::TRANSACTION_ERROR:
179 return "SQL_TRANSACTION_ERROR"s;
181 return std::format(
"SQL error code {}", code);
189struct std::is_error_code_enum<Lightweight::SqlError>:
public std::true_type
195inline std::error_code make_error_code(Lightweight::SqlError e)
197 return {
static_cast<int>(e), Lightweight::SqlErrorCategory::get() };
201struct std::formatter<Lightweight::SqlError>: formatter<std::string>
203 auto format(Lightweight::SqlError value, format_context& ctx)
const -> format_context::iterator
207 return formatter<std::string>::format(Lightweight::SqlErrorCategory::get().message(
static_cast<int>(value)), ctx);
212struct std::formatter<Lightweight::SqlErrorInfo>: formatter<std::string>
216 return formatter<std::string>::format(std::format(
"{} ({}) - {}", info.sqlState, info.nativeErrorCode, info.message),
Supplies diagnostics for an ODBC handle.
virtual SqlErrorInfo Diagnose(SQLSMALLINT handleType, SQLHANDLE handle)=0
Returns the diagnostics for the given handle.
Represents an ODBC SQL error.
SQLINTEGER nativeErrorCode
The native ODBC error code.
std::string message
The human-readable error message.
static void RequireStatementSuccess(SQLRETURN result, SQLHSTMT hStmt, std::string_view message)
Asserts that the given result is a success code, otherwise throws an exception.
std::string sqlState
The SQLSTATE diagnostic code (5 characters).
static SqlErrorInfo FromStatementHandle(SQLHSTMT hStmt)
Constructs an ODBC error info object from the given ODBC statement handle.
static SqlErrorInfo FromEnvironmentHandle(SQLHENV hEnv)
Constructs an ODBC error info object from the given ODBC environment handle.
static SqlErrorInfo FromConnectionHandle(SQLHDBC hDbc)
Constructs an ODBC error info object from the given ODBC connection handle.