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);
66class SqlException:
public std::runtime_error
70 std::source_location location = std::source_location::current());
73 [[nodiscard]] LIGHTWEIGHT_FORCE_INLINE
SqlErrorInfo const& info() const noexcept
82enum class SqlError : std::int16_t
84 SUCCESS = SQL_SUCCESS,
85 SUCCESS_WITH_INFO = SQL_SUCCESS_WITH_INFO,
88 INVALID_HANDLE = SQL_INVALID_HANDLE,
89 STILL_EXECUTING = SQL_STILL_EXECUTING,
90 NEED_DATA = SQL_NEED_DATA,
91 PARAM_DATA_AVAILABLE = SQL_PARAM_DATA_AVAILABLE,
92 NO_DATA_FOUND = SQL_NO_DATA_FOUND,
93 UNSUPPORTED_TYPE = 1'000,
94 INVALID_ARGUMENT = 1'001,
95 TRANSACTION_ERROR = 1'002,
98struct SqlErrorCategory: std::error_category
101 static SqlErrorCategory
const& get() noexcept
103 static SqlErrorCategory
const category;
107 [[nodiscard]]
char const* name() const noexcept
override
109 return "Lightweight";
112 [[nodiscard]] std::string message(
int code)
const override
114 using namespace std::string_literals;
115 switch (
static_cast<SqlError
>(code))
117 case SqlError::SUCCESS:
118 return "SQL_SUCCESS"s;
119 case SqlError::SUCCESS_WITH_INFO:
120 return "SQL_SUCCESS_WITH_INFO"s;
121 case SqlError::NODATA:
122 return "SQL_NO_DATA"s;
123 case SqlError::FAILURE:
125 case SqlError::INVALID_HANDLE:
126 return "SQL_INVALID_HANDLE"s;
127 case SqlError::STILL_EXECUTING:
128 return "SQL_STILL_EXECUTING"s;
129 case SqlError::NEED_DATA:
130 return "SQL_NEED_DATA"s;
131 case SqlError::PARAM_DATA_AVAILABLE:
132 return "SQL_PARAM_DATA_AVAILABLE"s;
133 case SqlError::UNSUPPORTED_TYPE:
134 return "SQL_UNSUPPORTED_TYPE"s;
135 case SqlError::INVALID_ARGUMENT:
136 return "SQL_INVALID_ARGUMENT"s;
137 case SqlError::TRANSACTION_ERROR:
138 return "SQL_TRANSACTION_ERROR"s;
140 return std::format(
"SQL error code {}", code);
148struct std::is_error_code_enum<Lightweight::SqlError>:
public std::true_type
154inline std::error_code make_error_code(Lightweight::SqlError e)
156 return {
static_cast<int>(e), Lightweight::SqlErrorCategory::get() };
160struct std::formatter<Lightweight::SqlError>: formatter<std::string>
162 auto format(Lightweight::SqlError value, format_context& ctx)
const -> format_context::iterator
164 return formatter<std::string>::format(
165 std::format(
"{}", Lightweight::SqlErrorCategory().message(
static_cast<int>(value))), ctx);
170struct std::formatter<Lightweight::SqlErrorInfo>: formatter<std::string>
174 return formatter<std::string>::format(std::format(
"{} ({}) - {}", info.sqlState, info.nativeErrorCode, info.message),
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.