u
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user