@@ -671,134 +671,6 @@ void SqlHandle::free() {
671671 }
672672}
673673
674- // Wrap SQLAllocHandle
675- SQLRETURN SQLAllocHandle_wrap (SQLSMALLINT HandleType, SqlHandlePtr InputHandle, SqlHandlePtr& OutputHandle) {
676- LOG (" Allocate SQL Handle" );
677- if (!SQLAllocHandle_ptr) {
678- LOG (" Function pointer not initialized. Loading the driver." );
679- DriverLoader::getInstance ().loadDriver (); // Load the driver
680- }
681-
682- SQLHANDLE rawOutputHandle = nullptr ;
683- SQLRETURN ret = SQLAllocHandle_ptr (HandleType, InputHandle ? InputHandle->get () : nullptr , &rawOutputHandle);
684- if (!SQL_SUCCEEDED (ret)) {
685- LOG (" Failed to allocate handle" );
686- return ret;
687- }
688- OutputHandle = std::make_shared<SqlHandle>(HandleType, rawOutputHandle);
689- return ret;
690- }
691-
692- // Wrap SQLSetEnvAttr
693- SQLRETURN SQLSetEnvAttr_wrap (SqlHandlePtr EnvHandle, SQLINTEGER Attribute, intptr_t ValuePtr,
694- SQLINTEGER StringLength) {
695- LOG (" Set SQL environment Attribute" );
696- if (!SQLSetEnvAttr_ptr) {
697- LOG (" Function pointer not initialized. Loading the driver." );
698- DriverLoader::getInstance ().loadDriver (); // Load the driver
699- }
700-
701- // TODO: Does ValuePtr need to be converted from Python to C++ object?
702- SQLRETURN ret = SQLSetEnvAttr_ptr (EnvHandle->get (), Attribute, reinterpret_cast <SQLPOINTER>(ValuePtr), StringLength);
703- if (!SQL_SUCCEEDED (ret)) {
704- LOG (" Failed to set environment attribute" );
705- }
706- return ret;
707- }
708-
709- // Wrap SQLSetConnectAttr
710- SQLRETURN SQLSetConnectAttr_wrap (SqlHandlePtr ConnectionHandle, SQLINTEGER Attribute,
711- py::object ValuePtr) {
712- LOG (" Set SQL Connection Attribute" );
713- if (!SQLSetConnectAttr_ptr) {
714- LOG (" Function pointer not initialized. Loading the driver." );
715- DriverLoader::getInstance ().loadDriver (); // Load the driver
716- }
717-
718- // Print the type of ValuePtr and attribute value - helpful for debugging
719- LOG (" Type of ValuePtr: {}, Attribute: {}" , py::type::of (ValuePtr).attr (" __name__" ).cast <std::string>(), Attribute);
720-
721- SQLPOINTER value = 0 ;
722- SQLINTEGER length = 0 ;
723-
724- if (py::isinstance<py::int_>(ValuePtr)) {
725- // Handle integer values
726- int intValue = ValuePtr.cast <int >();
727- value = reinterpret_cast <SQLPOINTER>(intValue);
728- length = SQL_IS_INTEGER; // Integer values don't require a length
729- // } else if (py::isinstance<py::str>(ValuePtr)) {
730- // // Handle Unicode string values
731- // static std::wstring unicodeValueBuffer;
732- // unicodeValueBuffer = ValuePtr.cast<std::wstring>();
733- // value = const_cast<SQLWCHAR*>(unicodeValueBuffer.c_str());
734- // length = SQL_NTS; // Indicates null-terminated string
735- } else if (py::isinstance<py::bytes>(ValuePtr) || py::isinstance<py::bytearray>(ValuePtr)) {
736- // Handle byte or bytearray values (like access tokens)
737- // Store in static buffer to ensure memory remains valid during connection
738- static std::vector<std::string> bytesBuffers;
739- bytesBuffers.push_back (ValuePtr.cast <std::string>());
740- value = const_cast <char *>(bytesBuffers.back ().c_str ());
741- length = SQL_IS_POINTER; // Indicates we're passing a pointer (required for token)
742- // } else if (py::isinstance<py::list>(ValuePtr) || py::isinstance<py::tuple>(ValuePtr)) {
743- // // Handle list or tuple values
744- // LOG("ValuePtr is a sequence (list or tuple)");
745- // for (py::handle item : ValuePtr) {
746- // LOG("Processing item in sequence");
747- // SQLRETURN ret = SQLSetConnectAttr_wrap(ConnectionHandle, Attribute, py::reinterpret_borrow<py::object>(item));
748- // if (!SQL_SUCCEEDED(ret)) {
749- // LOG("Failed to set attribute for item in sequence");
750- // return ret;
751- // }
752- // }
753- } else {
754- LOG (" Unsupported ValuePtr type" );
755- return SQL_ERROR;
756- }
757-
758- SQLRETURN ret = SQLSetConnectAttr_ptr (ConnectionHandle->get (), Attribute, value, length);
759- if (!SQL_SUCCEEDED (ret)) {
760- LOG (" Failed to set Connection attribute" );
761- }
762- LOG (" Set Connection attribute successfully" );
763- return ret;
764- }
765-
766- // Wrap SQLSetStmtAttr
767- SQLRETURN SQLSetStmtAttr_wrap (SqlHandlePtr StatementHandle, SQLINTEGER Attribute, intptr_t ValuePtr,
768- SQLINTEGER StringLength) {
769- LOG (" Set SQL Statement Attribute" );
770- if (!SQLSetConnectAttr_ptr) {
771- LOG (" Function pointer not initialized. Loading the driver." );
772- DriverLoader::getInstance ().loadDriver (); // Load the driver
773- }
774-
775- // TODO: Does ValuePtr need to be converted from Python to C++ object?
776- SQLRETURN ret = SQLSetStmtAttr_ptr (StatementHandle->get (), Attribute, reinterpret_cast <SQLPOINTER>(ValuePtr), StringLength);
777- if (!SQL_SUCCEEDED (ret)) {
778- LOG (" Failed to set Statement attribute" );
779- }
780- return ret;
781- }
782-
783- // Wrap SQLGetConnectionAttrA
784- // Currently only supports retrieval of int-valued attributes
785- // TODO: add support to retrieve all types of attributes
786- SQLINTEGER SQLGetConnectionAttr_wrap (SqlHandlePtr ConnectionHandle, SQLINTEGER attribute) {
787- LOG (" Get SQL COnnection Attribute" );
788- if (!SQLGetConnectAttr_ptr) {
789- LOG (" Function pointer not initialized. Loading the driver." );
790- DriverLoader::getInstance ().loadDriver (); // Load the driver
791- }
792-
793- SQLINTEGER stringLength;
794- SQLINTEGER intValue;
795-
796- // Try to get the attribute as an integer
797- SQLGetConnectAttr_ptr (ConnectionHandle->get (), attribute, &intValue,
798- sizeof (SQLINTEGER), &stringLength);
799- return intValue;
800- }
801-
802674// Helper function to check for driver errors
803675ErrorInfo SQLCheckError_Wrap (SQLSMALLINT handleType, SqlHandlePtr handle, SQLRETURN retcode) {
804676 LOG (" Checking errors for retcode - {}" , retcode);
@@ -832,23 +704,6 @@ ErrorInfo SQLCheckError_Wrap(SQLSMALLINT handleType, SqlHandlePtr handle, SQLRET
832704 return errorInfo;
833705}
834706
835- // Wrap SQLDriverConnect
836- SQLRETURN SQLDriverConnect_wrap (SqlHandlePtr ConnectionHandle, intptr_t WindowHandle, const std::wstring& ConnectionString) {
837- LOG (" Driver Connect to MSSQL" );
838- if (!SQLDriverConnect_ptr) {
839- LOG (" Function pointer not initialized. Loading the driver." );
840- DriverLoader::getInstance ().loadDriver (); // Load the driver
841- }
842- SQLRETURN ret = SQLDriverConnect_ptr (ConnectionHandle->get (),
843- reinterpret_cast <SQLHWND>(WindowHandle),
844- const_cast <SQLWCHAR*>(ConnectionString.c_str ()), SQL_NTS, nullptr ,
845- 0 , nullptr , SQL_DRIVER_NOPROMPT);
846- if (!SQL_SUCCEEDED (ret)) {
847- LOG (" Failed to connect to DB" );
848- }
849- return ret;
850- }
851-
852707// Wrap SQLExecDirect
853708SQLRETURN SQLExecDirect_wrap (SqlHandlePtr StatementHandle, const std::wstring& Query) {
854709 LOG (" Execute SQL query directly - {}" , Query.c_str ());
@@ -2004,17 +1859,6 @@ SQLRETURN SQLMoreResults_wrap(SqlHandlePtr StatementHandle) {
20041859 return SQLMoreResults_ptr (StatementHandle->get ());
20051860}
20061861
2007- // Wrap SQLEndTran
2008- SQLRETURN SQLEndTran_wrap (SQLSMALLINT HandleType, SqlHandlePtr Handle, SQLSMALLINT CompletionType) {
2009- LOG (" End SQL Transaction" );
2010- if (!SQLEndTran_ptr) {
2011- LOG (" Function pointer not initialized. Loading the driver." );
2012- DriverLoader::getInstance ().loadDriver (); // Load the driver
2013- }
2014-
2015- return SQLEndTran_ptr (HandleType, Handle->get (), CompletionType);
2016- }
2017-
20181862// Wrap SQLFreeHandle
20191863SQLRETURN SQLFreeHandle_wrap (SQLSMALLINT HandleType, SqlHandlePtr Handle) {
20201864 LOG (" Free SQL handle" );
@@ -2030,17 +1874,6 @@ SQLRETURN SQLFreeHandle_wrap(SQLSMALLINT HandleType, SqlHandlePtr Handle) {
20301874 return ret;
20311875}
20321876
2033- // Wrap SQLDisconnect
2034- SQLRETURN SQLDisconnect_wrap (SqlHandlePtr ConnectionHandle) {
2035- LOG (" Disconnect from MSSQL" );
2036- if (!SQLDisconnect_ptr) {
2037- LOG (" Function pointer not initialized. Loading the driver." );
2038- DriverLoader::getInstance ().loadDriver (); // Load the driver
2039- }
2040-
2041- return SQLDisconnect_ptr (ConnectionHandle->get ());
2042- }
2043-
20441877// Wrap SQLRowCount
20451878SQLLEN SQLRowCount_wrap (SqlHandlePtr StatementHandle) {
20461879 LOG (" Get number of row affected by last execute" );
@@ -2102,22 +1935,21 @@ PYBIND11_MODULE(ddbc_bindings, m) {
21021935
21031936 py::class_<SqlHandle, SqlHandlePtr>(m, " SqlHandle" )
21041937 .def (" free" , &SqlHandle::free);
2105-
2106- m.def (" DDBCSQLAllocHandle" , [](SQLSMALLINT HandleType, SqlHandlePtr InputHandle = nullptr ) {
2107- SqlHandlePtr OutputHandle;
2108- SQLRETURN rc = SQLAllocHandle_wrap (HandleType, InputHandle, OutputHandle);
2109- return py::make_tuple (rc, OutputHandle);
2110- }, " Allocate an environment, connection, statement, or descriptor handle" );
2111- m.def (" DDBCSQLSetEnvAttr" , &SQLSetEnvAttr_wrap,
2112- " Set an attribute that governs aspects of environments" );
1938+ py::class_<Connection>(m, " Connection" )
1939+ .def (py::init<const std::wstring&, bool >(), py::arg (" conn_str" ))
1940+ .def (" connect" , &Connection::connect, " Establish a connection to the database" )
1941+ .def (" close" , &Connection::close, " Close the connection" )
1942+ .def (" commit" , [](Connection& self) {
1943+ self.end_transaction (SQL_COMMIT);
1944+ })
1945+ .def (" rollback" , [](Connection& self) {
1946+ self.end_transaction (SQL_ROLLBACK)})
1947+ .def (" set_autocommit" , &Connection::set_autocommit)
1948+ .def (" get_autocommit" , &Connection::get_autocommit)
1949+ .def (" set_attribute" , &Connection::set_attribute);
1950+ .def (" alloc_statement_handle" , &Connection::alloc_statement_handle);
21131951 m.def (" DDBCSQLSetConnectAttr" , &SQLSetConnectAttr_wrap,
21141952 " Set an attribute that governs aspects of connections" );
2115- m.def (" DDBCSQLSetStmtAttr" , &SQLSetStmtAttr_wrap,
2116- " Set an attribute that governs aspects of statements" );
2117- m.def (" DDBCSQLGetConnectionAttr" , &SQLGetConnectionAttr_wrap,
2118- " Get an attribute that governs aspects of connections" );
2119- m.def (" DDBCSQLDriverConnect" , &SQLDriverConnect_wrap,
2120- " Connect to a data source with a connection string" );
21211953 m.def (" DDBCSQLExecDirect" , &SQLExecDirect_wrap, " Execute a SQL query directly" );
21221954 m.def (" DDBCSQLExecute" , &SQLExecute_wrap, " Prepare and execute T-SQL statements" );
21231955 m.def (" DDBCSQLRowCount" , &SQLRowCount_wrap,
@@ -2135,7 +1967,6 @@ PYBIND11_MODULE(ddbc_bindings, m) {
21351967 m.def (" DDBCSQLFetchAll" , &FetchAll_wrap, " Fetch all rows from the result set" );
21361968 m.def (" DDBCSQLEndTran" , &SQLEndTran_wrap, " End a transaction" );
21371969 m.def (" DDBCSQLFreeHandle" , &SQLFreeHandle_wrap, " Free a handle" );
2138- m.def (" DDBCSQLDisconnect" , &SQLDisconnect_wrap, " Disconnect from a data source" );
21391970 m.def (" DDBCSQLCheckError" , &SQLCheckError_Wrap, " Check for driver errors" );
21401971
21411972 // Add a version attribute
0 commit comments