This commit is contained in:
seb
2026-07-14 23:30:16 +02:00
parent 245fb047d7
commit 262fa63f1b
109 changed files with 21566 additions and 367 deletions

View File

@@ -21,35 +21,75 @@ struct Cell {
using Row = std::vector<Cell>;
using ResultSet = std::vector<Row>;
enum class ParamType { Int, BigInt, Float, Double, NVarChar, Bit };
enum class ParamType { Int, BigInt, Float, Double, NVarChar, Bit, DateTime };
struct Param {
ParamType type;
std::string str_val;
int64_t int_val = 0;
double dbl_val = 0.0;
bool is_null = false;
static Param null_int() { Param p; p.type = ParamType::Int; p.is_null = true; return p; }
static Param null_bigint() { Param p; p.type = ParamType::BigInt; p.is_null = true; return p; }
static Param null_nvarchar() { Param p; p.type = ParamType::NVarChar; p.is_null = true; return p; }
};
class OdbcPool {
public:
~OdbcPool();
int connect();
void disconnect();
bool execute(const std::string& sql, const std::vector<Param>& params, ResultSet& out);
bool execute(const std::string& sql, ResultSet& out);
int64_t execute_scalar(const std::string& sql, const std::vector<Param>& params = {}, int64_t fallback = 0);
private:
struct Connection {
SQLHDBC hdbc = SQL_NULL_HDBC;
SQLHSTMT hstmt = SQL_NULL_HSTMT;
bool in_use = false;
bool in_transaction = false;
};
// RAII checkout guard. Returned by checkout().
struct ConnGuard {
Connection* conn = nullptr;
OdbcPool* pool = nullptr;
ConnGuard() = default;
ConnGuard(Connection* c, OdbcPool* p) : conn(c), pool(p) {}
~ConnGuard() { if (conn && pool) pool->release(conn); }
ConnGuard(const ConnGuard&) = delete;
ConnGuard(ConnGuard&& other) noexcept : conn(other.conn), pool(other.pool) { other.conn = nullptr; }
ConnGuard& operator=(ConnGuard&& other) noexcept {
if (this != &other) {
if (conn && pool) pool->release(conn);
conn = other.conn;
pool = other.pool;
other.conn = nullptr;
}
return *this;
}
Connection* operator->() const { return conn; }
Connection* get() const { return conn; }
explicit operator bool() const { return conn != nullptr; }
};
~OdbcPool();
int connect();
void disconnect();
bool execute(const std::string& sql, const std::vector<Param>& params, ResultSet& out);
bool execute(const std::string& sql, ResultSet& out);
int64_t execute_scalar(const std::string& sql, const std::vector<Param>& params = {}, int64_t fallback = 0);
// Transactional execution on an explicitly checked-out connection.
ConnGuard checkout();
bool execute(Connection* conn, const std::string& sql, const std::vector<Param>& params, ResultSet& out);
bool execute(Connection* conn, const std::string& sql, ResultSet& out);
bool begin(Connection* conn);
bool commit(Connection* conn);
bool rollback(Connection* conn);
void release(Connection* c);
private:
SQLHENV henv_ = SQL_NULL_HENV;
std::vector<Connection> conns_;
std::mutex mutex_;
Connection* checkout();
void release(Connection* c);
Connection* checkout_raw();
};
OdbcPool& get_pool();