99#include < vector>
1010#include < pybind11/pybind11.h>
1111
12+ #define SQL_COPT_SS_ACCESS_TOKEN 1256 // Custom attribute ID for access token
13+
1214// -------------------------------------------------------------------------------------------------
1315// Implements the Connection class declared in connection.h.
1416// This class wraps low-level ODBC operations like connect/disconnect,
@@ -21,8 +23,16 @@ Connection::~Connection() {
2123 close (); // Ensure the connection is closed when the object is destroyed.
2224}
2325
24- SQLRETURN Connection::connect () {
26+ SQLRETURN Connection::connect (const py::dict& attrs_before ) {
2527 allocDbcHandle ();
28+ // Apply access token before connect
29+ if (!attrs_before.is_none () && py::len (attrs_before) > 0 ) {
30+ LOG (" Apply attributes before connect" );
31+ applyAttrsBefore (attrs_before);
32+ if (_autocommit) {
33+ setAutocommit (_autocommit);
34+ }
35+ }
2636 return connectToDb ();
2737}
2838
@@ -91,11 +101,8 @@ SQLRETURN Connection::rollback() {
91101}
92102
93103SQLRETURN Connection::setAutocommit (bool enable) {
94- if (!_dbc_handle) {
95- throw std::runtime_error (" Connection handle not allocated" );
96- }
97104 SQLINTEGER value = enable ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
98- LOG (" Set SQL Connection Attribute - Autocommit" );
105+ LOG (" Set SQL Connection Attribute - Autocommit" );
99106 SQLRETURN ret = SQLSetConnectAttr_ptr (_dbc_handle->get (), SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)value, 0 );
100107 if (!SQL_SUCCEEDED (ret)) {
101108 throw std::runtime_error (" Failed to set autocommit mode." );
@@ -117,6 +124,9 @@ bool Connection::getAutocommit() const {
117124}
118125
119126SqlHandlePtr Connection::allocStatementHandle () {
127+ if (!_dbc_handle) {
128+ throw std::runtime_error (" Connection handle not allocated" );
129+ }
120130 LOG (" Allocating statement handle" );
121131 SQLHANDLE stmt = nullptr ;
122132 SQLRETURN ret = SQLAllocHandle_ptr (SQL_HANDLE_STMT, _dbc_handle->get (), &stmt);
@@ -126,7 +136,7 @@ SqlHandlePtr Connection::allocStatementHandle() {
126136 return std::make_shared<SqlHandle>(SQL_HANDLE_STMT, stmt);
127137}
128138
129- SQLRETURN Connection::set_attribute (SQLINTEGER attribute, py::object value) {
139+ SQLRETURN Connection::setAttribute (SQLINTEGER attribute, py::object value) {
130140 LOG (" Setting SQL attribute" );
131141
132142 SQLPOINTER ptr = nullptr ;
@@ -156,7 +166,7 @@ SQLRETURN Connection::set_attribute(SQLINTEGER attribute, py::object value) {
156166 return ret;
157167}
158168
159- void Connection::apply_attrs_before (const py::dict& attrs) {
169+ void Connection::applyAttrsBefore (const py::dict& attrs) {
160170 for (const auto & item : attrs) {
161171 int key;
162172 try {
@@ -166,7 +176,7 @@ void Connection::apply_attrs_before(const py::dict& attrs) {
166176 }
167177
168178 if (key == SQL_COPT_SS_ACCESS_TOKEN) {
169- SQLRETURN ret = set_attribute (key, py::reinterpret_borrow<py::object>(item.second ));
179+ SQLRETURN ret = setAttribute (key, py::reinterpret_borrow<py::object>(item.second ));
170180 if (!SQL_SUCCEEDED (ret)) {
171181 throw std::runtime_error (" Failed to set access token before connect" );
172182 }
0 commit comments