Skip to content

Commit 695719d

Browse files
authored
STYLE: Cpp linting (#300)
### Work Item / Issue Reference <!-- IMPORTANT: Please follow the PR template guidelines below. For mssql-python maintainers: Insert your ADO Work Item ID below (e.g. AB#37452) For external contributors: Insert Github Issue number below (e.g. #149) Only one reference is required - either GitHub issue OR ADO Work Item. --> <!-- mssql-python maintainers: ADO Work Item --> > [AB#38478](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/38478) ------------------------------------------------------------------- ### Summary This pull request refactors the `connection.cpp` and `connection.h` files to improve code readability, maintainability, and consistency, while also making minor corrections and clarifications to comments. The changes mainly involve formatting, type usage, and error handling improvements, as well as updating include paths and constructor signatures. **Code Formatting and Readability Improvements** * Reformatted function calls and argument lists for better readability, including breaking up long lines and grouping parameters logically in methods such as `getEnvHandle`, `allocateDbcHandle`, `commit`, `rollback`, and others in `connection.cpp`. * Improved comment formatting and clarity, including updating TODOs and explanatory comments to be more precise and easier to understand. **Type and Variable Usage Updates** * Updated integer types in `setAttribute` from `long long` to `int64_t` for clarity and platform consistency. * Improved buffer management for string and binary attributes by clarifying buffer lifetime logic and using more explicit type casts. **Error Handling Enhancements** * Enhanced error handling in attribute setting and connection attribute application, including more detailed error messages and fallback logic. **Include Path and Constructor Signature Updates** * Updated include paths in both `connection.cpp` and `connection.h` for consistency and to support future platform agnostic changes. * Modified the `ConnectionHandle` constructor signature to improve clarity and maintainability.
1 parent 539461f commit 695719d

File tree

9 files changed

+1137
-316
lines changed

9 files changed

+1137
-316
lines changed

mssql_python/pybind/connection/connection.cpp

Lines changed: 133 additions & 102 deletions
Large diffs are not rendered by default.

mssql_python/pybind/connection/connection.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license.
33

4-
// INFO|TODO - Note that is file is Windows specific right now. Making it arch agnostic will be
5-
// taken up in future.
6-
74
#pragma once
8-
#include "ddbc_bindings.h"
5+
#include <memory>
6+
#include <string>
7+
#include "../ddbc_bindings.h"
98

109
// Represents a single ODBC database connection.
1110
// Manages connection handles.
1211
// Note: This class does NOT implement pooling logic directly.
1312

1413
class Connection {
15-
public:
14+
public:
1615
Connection(const std::wstring& connStr, bool fromPool);
1716

1817
~Connection();
@@ -50,7 +49,7 @@ class Connection {
5049
// Add getter for DBC handle for error reporting
5150
const SqlHandlePtr& getDbcHandle() const { return _dbcHandle; }
5251

53-
private:
52+
private:
5453
void allocateDbcHandle();
5554
void checkError(SQLRETURN ret) const;
5655
void applyAttrsBefore(const py::dict& attrs_before);
@@ -63,8 +62,9 @@ class Connection {
6362
};
6463

6564
class ConnectionHandle {
66-
public:
67-
ConnectionHandle(const std::string& connStr, bool usePool, const py::dict& attrsBefore = py::dict());
65+
public:
66+
ConnectionHandle(const std::string& connStr, bool usePool,
67+
const py::dict& attrsBefore = py::dict());
6868
~ConnectionHandle();
6969

7070
void close();
@@ -78,8 +78,8 @@ class ConnectionHandle {
7878
// Get information about the driver and data source
7979
py::object getInfo(SQLUSMALLINT infoType) const;
8080

81-
private:
81+
private:
8282
std::shared_ptr<Connection> _conn;
8383
bool _usePool;
8484
std::wstring _connStr;
85-
};
85+
};

mssql_python/pybind/connection/connection_pool.cpp

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license.
33

4-
// INFO|TODO - Note that is file is Windows specific right now. Making it arch agnostic will be
5-
// taken up in future.
6-
7-
#include "connection_pool.h"
4+
#include "connection/connection_pool.h"
85
#include <exception>
6+
#include <memory>
7+
#include <vector>
98

109
ConnectionPool::ConnectionPool(size_t max_size, int idle_timeout_secs)
11-
: _max_size(max_size), _idle_timeout_secs(idle_timeout_secs), _current_size(0) {}
10+
: _max_size(max_size), _idle_timeout_secs(idle_timeout_secs),
11+
_current_size(0) {}
1212

13-
std::shared_ptr<Connection> ConnectionPool::acquire(const std::wstring& connStr, const py::dict& attrs_before) {
13+
std::shared_ptr<Connection> ConnectionPool::acquire(
14+
const std::wstring& connStr, const py::dict& attrs_before) {
1415
std::vector<std::shared_ptr<Connection>> to_disconnect;
1516
std::shared_ptr<Connection> valid_conn = nullptr;
1617
{
@@ -21,7 +22,8 @@ std::shared_ptr<Connection> ConnectionPool::acquire(const std::wstring& connStr,
2122
// Phase 1: Remove stale connections, collect for later disconnect
2223
_pool.erase(std::remove_if(_pool.begin(), _pool.end(),
2324
[&](const std::shared_ptr<Connection>& conn) {
24-
auto idle_time = std::chrono::duration_cast<std::chrono::seconds>(now - conn->lastUsed()).count();
25+
auto idle_time = std::chrono::duration_cast<
26+
std::chrono::seconds>(now - conn->lastUsed()).count();
2527
if (idle_time > _idle_timeout_secs) {
2628
to_disconnect.push_back(conn);
2729
return true;
@@ -30,7 +32,8 @@ std::shared_ptr<Connection> ConnectionPool::acquire(const std::wstring& connStr,
3032
}), _pool.end());
3133

3234
size_t pruned = before - _pool.size();
33-
_current_size = (_current_size >= pruned) ? (_current_size - pruned) : 0;
35+
_current_size = (_current_size >= pruned) ?
36+
(_current_size - pruned) : 0;
3437

3538
// Phase 2: Attempt to reuse healthy connections
3639
while (!_pool.empty()) {
@@ -56,7 +59,8 @@ std::shared_ptr<Connection> ConnectionPool::acquire(const std::wstring& connStr,
5659
valid_conn->connect(attrs_before);
5760
++_current_size;
5861
} else if (!valid_conn) {
59-
throw std::runtime_error("ConnectionPool::acquire: pool size limit reached");
62+
throw std::runtime_error(
63+
"ConnectionPool::acquire: pool size limit reached");
6064
}
6165
}
6266

@@ -76,8 +80,7 @@ void ConnectionPool::release(std::shared_ptr<Connection> conn) {
7680
if (_pool.size() < _max_size) {
7781
conn->updateLastUsed();
7882
_pool.push_back(conn);
79-
}
80-
else {
83+
} else {
8184
conn->disconnect();
8285
if (_current_size > 0) --_current_size;
8386
}
@@ -97,7 +100,8 @@ void ConnectionPool::close() {
97100
try {
98101
conn->disconnect();
99102
} catch (const std::exception& ex) {
100-
LOG("ConnectionPool::close: disconnect failed: {}", ex.what());
103+
LOG("ConnectionPool::close: disconnect failed: {}",
104+
ex.what());
101105
}
102106
}
103107
}
@@ -107,18 +111,21 @@ ConnectionPoolManager& ConnectionPoolManager::getInstance() {
107111
return manager;
108112
}
109113

110-
std::shared_ptr<Connection> ConnectionPoolManager::acquireConnection(const std::wstring& connStr, const py::dict& attrs_before) {
114+
std::shared_ptr<Connection> ConnectionPoolManager::acquireConnection(
115+
const std::wstring& connStr, const py::dict& attrs_before) {
111116
std::lock_guard<std::mutex> lock(_manager_mutex);
112117

113118
auto& pool = _pools[connStr];
114119
if (!pool) {
115120
LOG("Creating new connection pool");
116-
pool = std::make_shared<ConnectionPool>(_default_max_size, _default_idle_secs);
121+
pool = std::make_shared<ConnectionPool>(_default_max_size,
122+
_default_idle_secs);
117123
}
118124
return pool->acquire(connStr, attrs_before);
119125
}
120126

121-
void ConnectionPoolManager::returnConnection(const std::wstring& conn_str, const std::shared_ptr<Connection> conn) {
127+
void ConnectionPoolManager::returnConnection(
128+
const std::wstring& conn_str, const std::shared_ptr<Connection> conn) {
122129
std::lock_guard<std::mutex> lock(_manager_mutex);
123130
if (_pools.find(conn_str) != _pools.end()) {
124131
_pools[conn_str]->release((conn));
Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,65 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT license.
33

4-
// INFO|TODO - Note that is file is Windows specific right now. Making it arch agnostic will be
5-
// taken up in future.
4+
#ifndef MSSQL_PYTHON_CONNECTION_POOL_H_
5+
#define MSSQL_PYTHON_CONNECTION_POOL_H_
66

77
#pragma once
8+
#include <chrono>
89
#include <deque>
9-
#include <unordered_map>
1010
#include <memory>
1111
#include <mutex>
1212
#include <string>
13-
#include <chrono>
14-
#include "connection.h"
13+
#include <unordered_map>
14+
#include "connection/connection.h"
1515

16-
// Manages a fixed-size pool of reusable database connections for a single connection string
16+
// Manages a fixed-size pool of reusable database connections for a
17+
// single connection string
1718
class ConnectionPool {
18-
public:
19+
public:
1920
ConnectionPool(size_t max_size, int idle_timeout_secs);
2021

2122
// Acquires a connection from the pool or creates a new one if under limit
22-
std::shared_ptr<Connection> acquire(const std::wstring& connStr, const py::dict& attrs_before = py::dict());
23+
std::shared_ptr<Connection> acquire(
24+
const std::wstring& connStr,
25+
const py::dict& attrs_before = py::dict());
2326

2427
// Returns a connection to the pool for reuse
2528
void release(std::shared_ptr<Connection> conn);
2629

2730
// Closes all connections in the pool, releasing resources
2831
void close();
2932

30-
private:
31-
size_t _max_size; // Maximum number of connections allowed
32-
int _idle_timeout_secs; // Idle time before connections are considered stale
33+
private:
34+
size_t _max_size; // Maximum number of connections allowed
35+
int _idle_timeout_secs; // Idle time before connections are stale
3336
size_t _current_size = 0;
3437
std::deque<std::shared_ptr<Connection>> _pool; // Available connections
35-
std::mutex _mutex; // Mutex for thread-safe access
38+
std::mutex _mutex; // Mutex for thread-safe access
3639
};
3740

3841
// Singleton manager that handles multiple pools keyed by connection string
3942
class ConnectionPoolManager {
40-
public:
43+
public:
4144
// Returns the singleton instance of the manager
4245
static ConnectionPoolManager& getInstance();
4346

4447
void configure(int max_size, int idle_timeout);
4548

4649
// Gets a connection from the appropriate pool (creates one if none exists)
47-
std::shared_ptr<Connection> acquireConnection(const std::wstring& conn_str, const py::dict& attrs_before = py::dict());
50+
std::shared_ptr<Connection> acquireConnection(
51+
const std::wstring& conn_str,
52+
const py::dict& attrs_before = py::dict());
4853

4954
// Returns a connection to its original pool
50-
void returnConnection(const std::wstring& conn_str, std::shared_ptr<Connection> conn);
55+
void returnConnection(const std::wstring& conn_str,
56+
std::shared_ptr<Connection> conn);
5157

5258
// Closes all pools and their connections
5359
void closePools();
5460

55-
private:
56-
ConnectionPoolManager() = default;
61+
private:
62+
ConnectionPoolManager() = default;
5763
~ConnectionPoolManager() = default;
5864

5965
// Map from connection string to connection pool
@@ -63,8 +69,10 @@ class ConnectionPoolManager {
6369
std::mutex _manager_mutex;
6470
size_t _default_max_size = 10;
6571
int _default_idle_secs = 300;
66-
72+
6773
// Prevent copying
6874
ConnectionPoolManager(const ConnectionPoolManager&) = delete;
6975
ConnectionPoolManager& operator=(const ConnectionPoolManager&) = delete;
7076
};
77+
78+
#endif // MSSQL_PYTHON_CONNECTION_POOL_H_

0 commit comments

Comments
 (0)