Skip to content

Commit 80063a5

Browse files
committed
minor updates
1 parent 7cd9679 commit 80063a5

2 files changed

Lines changed: 70 additions & 101 deletions

File tree

mssql_python/pybind/connection/connection.cpp

Lines changed: 56 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -7,148 +7,120 @@
77
#include "connection.h"
88
#include <iostream>
99

10+
SqlHandlePtr Connection::_envHandle = nullptr;
1011
//-------------------------------------------------------------------------------------------------
1112
// Implements the Connection class declared in connection.h.
1213
// This class wraps low-level ODBC operations like connect/disconnect,
1314
// transaction control, and autocommit configuration.
1415
//-------------------------------------------------------------------------------------------------
1516
Connection::Connection(const std::wstring& conn_str, bool autocommit)
16-
: _conn_str(conn_str) , _autocommit(autocommit) {}
17+
: _connStr(conn_str) , _autocommit(autocommit) {
18+
if (!_envHandle) {
19+
LOG("Allocating environment handle");
20+
SQLHANDLE env = nullptr;
21+
if (!SQLAllocHandle_ptr) {
22+
LOG("Function pointers not initialized, loading driver");
23+
DriverLoader::getInstance().loadDriver();
24+
}
25+
SQLRETURN ret = SQLAllocHandle_ptr(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
26+
if (!SQL_SUCCEEDED(ret)) {
27+
throw std::runtime_error("Failed to allocate environment handle");
28+
}
29+
_envHandle = std::make_shared<SqlHandle>(SQL_HANDLE_ENV, env);
1730

18-
Connection::~Connection() {
19-
close(); // Ensure the connection is closed when the object is destroyed.
31+
LOG("Setting environment attributes");
32+
ret = SQLSetEnvAttr_ptr(_envHandle->get(), SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3_80, 0);
33+
if (!SQL_SUCCEEDED(ret)) {
34+
throw std::runtime_error("Failed to set environment attribute");
35+
}
36+
}
37+
allocateDbcHandle();
2038
}
2139

22-
SQLRETURN Connection::connect() {
23-
allocDbcHandle();
24-
return connectToDb();
40+
Connection::~Connection() {
41+
disconnect();
2542
}
2643

2744
// Allocates DBC handle
28-
void Connection::allocDbcHandle() {
45+
void Connection::allocateDbcHandle() {
2946
SQLHANDLE dbc = nullptr;
3047
LOG("Allocate SQL Connection Handle");
31-
SQLRETURN ret = SQLAllocHandle_ptr(SQL_HANDLE_DBC, getSharedEnvHandle()->get(), &dbc);
48+
SQLRETURN ret = SQLAllocHandle_ptr(SQL_HANDLE_DBC, _envHandle->get(), &dbc);
3249
if (!SQL_SUCCEEDED(ret)) {
3350
throw std::runtime_error("Failed to allocate connection handle");
3451
}
35-
_dbc_handle = std::make_shared<SqlHandle>(SQL_HANDLE_DBC, dbc);
52+
_dbcHandle = std::make_shared<SqlHandle>(SQL_HANDLE_DBC, dbc);
3653
}
3754

38-
// Connects to the database
39-
SQLRETURN Connection::connectToDb() {
55+
void Connection::connect() {
4056
LOG("Connecting to database");
41-
SQLRETURN ret = SQLDriverConnect_ptr(_dbc_handle->get(), nullptr,
42-
(SQLWCHAR*)_conn_str.c_str(), SQL_NTS,
43-
nullptr, 0, nullptr, SQL_DRIVER_NOPROMPT);
44-
if (!SQL_SUCCEEDED(ret)) {
45-
throw std::runtime_error("Failed to connect to database");
46-
}
47-
LOG("Connected to database successfully");
48-
return ret;
57+
SQLRETURN ret = SQLDriverConnect_ptr(
58+
_dbcHandle->get(), nullptr,
59+
(SQLWCHAR*)_connStr.c_str(), SQL_NTS,
60+
nullptr, 0, nullptr, SQL_DRIVER_NOPROMPT);
61+
checkError(ret, "SQLDriverConnect failed");
62+
setAutocommit(_autocommit);
4963
}
5064

51-
SQLRETURN Connection::close() {
52-
if (!_dbc_handle) {
53-
LOG("No connection handle to close");
54-
return SQL_SUCCESS;
55-
}
56-
LOG("Disconnect from MSSQL");
57-
if (!SQLDisconnect_ptr) {
58-
LOG("Function pointer not initialized. Loading the driver.");
59-
DriverLoader::getInstance().loadDriver();
65+
void Connection::disconnect() {
66+
if (_dbcHandle) {
67+
SQLDisconnect_ptr(_dbcHandle->get());
6068
}
61-
62-
SQLRETURN ret = SQLDisconnect_ptr(_dbc_handle->get());
63-
_dbc_handle.reset();
64-
return ret;
6569
}
6670

67-
SQLRETURN Connection::commit() {
68-
if (!_dbc_handle) {
69-
throw std::runtime_error("Connection handle not allocated");
71+
void Connection::checkError(SQLRETURN ret, const std::string& msg) {
72+
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
73+
throw std::runtime_error("[ODBC Error] " + msg);
7074
}
75+
}
76+
77+
void Connection::commit() {
7178
LOG("Committing transaction");
72-
SQLRETURN ret = SQLEndTran_ptr(SQL_HANDLE_DBC, _dbc_handle->get(), SQL_COMMIT);
73-
if (!SQL_SUCCEEDED(ret)) {
74-
throw std::runtime_error("Failed to commit transaction");
75-
}
76-
return ret;
79+
SQLRETURN ret = SQLEndTran_ptr(SQL_HANDLE_DBC, _dbcHandle->get(), SQL_COMMIT);
80+
checkError(ret, "Failed to commit transaction");
7781
}
7882

79-
SQLRETURN Connection::rollback() {
80-
if (!_dbc_handle) {
83+
void Connection::rollback() {
84+
if (!_dbcHandle) {
8185
throw std::runtime_error("Connection handle not allocated");
8286
}
8387
LOG("Rolling back transaction");
84-
SQLRETURN ret = SQLEndTran_ptr(SQL_HANDLE_DBC, _dbc_handle->get(), SQL_ROLLBACK);
85-
if (!SQL_SUCCEEDED(ret)) {
86-
throw std::runtime_error("Failed to rollback transaction");
87-
}
88-
return ret;
88+
SQLRETURN ret = SQLEndTran_ptr(SQL_HANDLE_DBC, _dbcHandle->get(), SQL_ROLLBACK);
89+
checkError(ret, "Failed to rollback transaction");
8990
}
9091

91-
SQLRETURN Connection::setAutocommit(bool enable) {
92-
if (!_dbc_handle) {
92+
void Connection::setAutocommit(bool enable) {
93+
if (!_dbcHandle) {
9394
throw std::runtime_error("Connection handle not allocated");
9495
}
9596
SQLINTEGER value = enable ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
9697
LOG("Set SQL Connection Attribute");
97-
SQLRETURN ret = SQLSetConnectAttr_ptr(_dbc_handle->get(), SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)value, 0);
98-
if (!SQL_SUCCEEDED(ret)) {
99-
throw std::runtime_error("Failed to set autocommit mode.");
100-
}
98+
SQLRETURN ret = SQLSetConnectAttr_ptr(_dbcHandle->get(), SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)value, 0);
99+
checkError(ret, "Failed to set autocommit attribute");
101100
_autocommit = enable;
102-
return ret;
103101
}
104102

105103
bool Connection::getAutocommit() const {
106-
if (!_dbc_handle) {
104+
if (!_dbcHandle) {
107105
throw std::runtime_error("Connection handle not allocated");
108106
}
109107
LOG("Get SQL Connection Attribute");
110108
SQLINTEGER value;
111109
SQLINTEGER string_length;
112-
SQLGetConnectAttr_ptr(_dbc_handle->get(), SQL_ATTR_AUTOCOMMIT, &value, sizeof(value), &string_length);
110+
SQLGetConnectAttr_ptr(_dbcHandle->get(), SQL_ATTR_AUTOCOMMIT, &value, sizeof(value), &string_length);
113111

114112
return value == SQL_AUTOCOMMIT_ON;
115113
}
116114

117115
SqlHandlePtr Connection::allocStatementHandle() {
118-
if (!_dbc_handle) {
116+
if (!_dbcHandle) {
119117
throw std::runtime_error("Connection handle not allocated");
120118
}
121119
LOG("Allocating statement handle");
122120
SQLHANDLE stmt = nullptr;
123-
SQLRETURN ret = SQLAllocHandle_ptr(SQL_HANDLE_STMT, _dbc_handle->get(), &stmt);
121+
SQLRETURN ret = SQLAllocHandle_ptr(SQL_HANDLE_STMT, _dbcHandle->get(), &stmt);
124122
if (!SQL_SUCCEEDED(ret)) {
125123
throw std::runtime_error("Failed to allocate statement handle");
126124
}
127125
return std::make_shared<SqlHandle>(SQL_HANDLE_STMT, stmt);
128126
}
129-
130-
SqlHandlePtr Connection::getSharedEnvHandle() {
131-
static std::once_flag flag;
132-
static SqlHandlePtr env_handle;
133-
134-
std::call_once(flag, []() {
135-
LOG("Allocating environment handle");
136-
SQLHANDLE env = nullptr;
137-
if (!SQLAllocHandle_ptr) {
138-
LOG("Function pointers not initialized, loading driver");
139-
DriverLoader::getInstance().loadDriver();
140-
}
141-
SQLRETURN ret = SQLAllocHandle_ptr(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
142-
if (!SQL_SUCCEEDED(ret)) {
143-
throw std::runtime_error("Failed to allocate environment handle");
144-
}
145-
env_handle = std::make_shared<SqlHandle>(SQL_HANDLE_ENV, env);
146-
147-
LOG("Setting environment attributes");
148-
ret = SQLSetEnvAttr_ptr(env_handle->get(), SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3_80, 0);
149-
if (!SQL_SUCCEEDED(ret)) {
150-
throw std::runtime_error("Failed to set environment attribute");
151-
}
152-
});
153-
return env_handle;
154-
}

mssql_python/pybind/connection/connection.h

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
// INFO|TODO - Note that is file is Windows specific right now. Making it arch agnostic will be
55
// taken up in future.
66

7-
#ifndef CONNECTION_H
8-
#define CONNECTION_H
9-
7+
#pragma once
108
#include "ddbc_bindings.h"
119

1210
// Represents a single ODBC database connection.
@@ -19,19 +17,19 @@ class Connection {
1917
~Connection();
2018

2119
// Establish the connection using the stored connection string.
22-
SQLRETURN connect();
20+
void connect();
2321

24-
// Close the connection and free resources.
25-
SQLRETURN close();
22+
// Disconnect and free the connection handle.
23+
void disconnect();
2624

2725
// Commit the current transaction.
28-
SQLRETURN commit();
26+
void commit();
2927

3028
// Rollback the current transaction.
31-
SQLRETURN rollback();
29+
void rollback();
3230

3331
// Enable or disable autocommit mode.
34-
SQLRETURN setAutocommit(bool value);
32+
void setAutocommit(bool value);
3533

3634
// Check whether autocommit is enabled.
3735
bool getAutocommit() const;
@@ -40,14 +38,13 @@ class Connection {
4038
SqlHandlePtr allocStatementHandle();
4139

4240
private:
43-
void allocDbcHandle();
44-
SQLRETURN connectToDb();
41+
void allocateDbcHandle();
42+
void checkError(SQLRETURN ret, const std::string& msg);
4543

46-
std::wstring _conn_str;
47-
SqlHandlePtr _dbc_handle;
48-
bool _autocommit = false;
44+
std::wstring _connStr;
45+
bool _usePool = false;
46+
bool _autocommit = true;
47+
SqlHandlePtr _dbcHandle;
4948

50-
static SqlHandlePtr getSharedEnvHandle();
49+
static SqlHandlePtr _envHandle;
5150
};
52-
53-
#endif // CONNECTION_H

0 commit comments

Comments
 (0)