1212// This class wraps low-level ODBC operations like connect/disconnect,
1313// transaction control, and autocommit configuration.
1414// -------------------------------------------------------------------------------------------------
15- Connection::Connection (const std::wstring& conn_str) : _conn_str(conn_str) {}
15+ Connection::Connection (const std::wstring& conn_str, bool autocommit ) : _conn_str(conn_str) , _autocommit(autocommit ) {}
1616
1717Connection::~Connection () {
18- LOG (" Connection destructor called" );
19- close (); // Ensure the connection is closed when the object is destroyed.
18+ close (); // Ensure the connection is closed when the object is destroyed.
2019}
2120
2221SQLRETURN Connection::connect () {
23- LOG (" Connecting to MSSQL" );
24- // to be added
22+ SQLHANDLE env = nullptr ;
23+ SQLHANDLE dbc = nullptr ;
24+
25+ LOG (" Allocate SQL Handle" );
26+ if (!SQLAllocHandle_ptr) {
27+ LOG (" Function pointer not initialized. Loading the driver." );
28+ DriverLoader::getInstance ().loadDriver ();
29+ }
30+ SQLRETURN ret = SQLAllocHandle_ptr (SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
31+ if (!SQL_SUCCEEDED (ret)) {
32+ LOG (" Failed to allocate environment handle" );
33+ throw std::runtime_error (" Failed to allocate environment handle" );
34+ }
35+ _env_handle = std::make_shared<SqlHandle>(SQL_HANDLE_ENV, env);
36+
37+ ret = SQLSetEnvAttr_ptr (env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3_80, 0 );
38+ if (!SQL_SUCCEEDED (ret)) {
39+ LOG (" Failed to set environment attribute" );
40+ throw std::runtime_error (" Failed to set environment attribute" );
41+ }
42+
43+ LOG (" Allocate SQL Connection Handle" );
44+ ret = SQLAllocHandle_ptr (SQL_HANDLE_DBC, env, &dbc);
45+ if (!SQL_SUCCEEDED (ret)) {
46+ LOG (" Failed to allocate connection handle" );
47+ throw std::runtime_error (" Failed to allocate connection handle" );
48+ }
49+ _dbc_handle = std::make_shared<SqlHandle>(SQL_HANDLE_DBC, dbc);
50+
51+ ret = SQLDriverConnect_ptr (dbc, nullptr ,
52+ (SQLWCHAR*)_conn_str.c_str (), SQL_NTS,
53+ nullptr , 0 , nullptr , SQL_DRIVER_NOPROMPT);
54+ if (!SQL_SUCCEEDED (ret)) {
55+ LOG (" Failed to connect to database" );
56+ }
57+ else {
58+ LOG (" Connected to database successfully" );
59+ }
60+ return ret;
2561}
2662
2763SQLRETURN Connection::close () {
2864 LOG (" Disconnect from MSSQL" );
29- // to be added
30- }
31-
32- SQLRETURN Connection::commit () {
33- LOG (" Committing transaction" );
34- // to be added
35- }
65+ if (!SQLDisconnect_ptr) {
66+ LOG (" Function pointer not initialized. Loading the driver." );
67+ DriverLoader::getInstance ().loadDriver ();
68+ }
3669
37- SQLRETURN Connection::rollback () {
38- LOG (" Rolling back transaction" );
39- // to be added
70+ return SQLDisconnect_ptr (_dbc_handle->get ());
4071}
4172
4273SQLRETURN Connection::end_transaction (SQLSMALLINT completion_type) {
43- // to be added
74+ LOG (completion_type == SQL_COMMIT ? " End SQL Transaction (Commit)" : " End SQL Transaction (Rollback)" );
75+ if (!SQLEndTran_ptr) {
76+ LOG (" Function pointer not initialized. Loading the driver." );
77+ DriverLoader::getInstance ().loadDriver ();
78+ }
79+ return SQLEndTran_ptr (_dbc_handle->type (), _dbc_handle->get (), completion_type);
4480}
4581
4682SQLRETURN Connection::set_autocommit (bool enable) {
47- LOG (" Setting autocommit mode" );
48- // to be added
83+ SQLINTEGER value = enable ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
84+ LOG (" Set SQL Connection Attribute" );
85+ SQLRETURN ret = SQLSetConnectAttr_ptr (_dbc_handle->get (), SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)value, 0 );
86+ if (!SQL_SUCCEEDED (ret)) {
87+ throw std::runtime_error (" Failed to set autocommit mode." );
88+ }
89+ return ret;
4990}
5091
5192bool Connection::get_autocommit () const {
52- LOG (" Getting autocommit mode" );
53- // to be added
93+ LOG (" Get SQL Connection Attribute" );
94+ SQLINTEGER value;
95+ SQLINTEGER string_length;
96+ SQLGetConnectAttr_ptr (_dbc_handle->get (), SQL_ATTR_AUTOCOMMIT, &value, sizeof (value), &string_length);
97+
98+ return value == SQL_AUTOCOMMIT_ON;
5499}
100+
101+ SqlHandlePtr Connection::alloc_statement_handle () {
102+ LOG (" Allocating statement handle" );
103+ SQLHANDLE stmt = nullptr ;
104+ SQLRETURN ret = SQLAllocHandle_ptr (SQL_HANDLE_STMT, _dbc_handle->get (), &stmt);
105+ if (!SQL_SUCCEEDED (ret)) {
106+ throw std::runtime_error (" Failed to allocate statement handle" );
107+ }
108+ return std::make_shared<SqlHandle>(SQL_HANDLE_STMT, stmt);
109+ }
0 commit comments