diff --git a/mssql_python/__init__.py b/mssql_python/__init__.py index dda59176..348ddd38 100644 --- a/mssql_python/__init__.py +++ b/mssql_python/__init__.py @@ -53,3 +53,18 @@ apilevel = "2.0" paramstyle = "qmark" threadsafety = 1 + +from .pooling import PoolingManager +def pooling(max_size=100, idle_timeout=600): +# """ +# Enable connection pooling with the specified parameters. + +# Args: +# max_size (int): Maximum number of connections in the pool. +# idle_timeout (int): Time in seconds before idle connections are closed. + +# Returns: +# None +# """ + PoolingManager.enable(max_size, idle_timeout) + \ No newline at end of file diff --git a/mssql_python/connection.py b/mssql_python/connection.py index 7c73a6df..857496d8 100644 --- a/mssql_python/connection.py +++ b/mssql_python/connection.py @@ -11,6 +11,7 @@ from mssql_python.constants import ConstantsDDBC as ddbc_sql_const from mssql_python.helpers import add_driver_to_connection_str, check_error from mssql_python import ddbc_bindings +from mssql_python.pooling import PoolingManager logger = get_logger() @@ -57,7 +58,8 @@ def __init__(self, connection_str: str = "", autocommit: bool = False, attrs_bef connection_str, **kwargs ) self._attrs_before = attrs_before or {} - self._conn = ddbc_bindings.Connection(self.connection_str, autocommit) + self._pooling = PoolingManager.is_enabled() + self._conn = ddbc_bindings.Connection(self.connection_str, autocommit, self._pooling) self._conn.connect(self._attrs_before) self.setautocommit(autocommit) diff --git a/mssql_python/pooling.py b/mssql_python/pooling.py new file mode 100644 index 00000000..fe6ebd82 --- /dev/null +++ b/mssql_python/pooling.py @@ -0,0 +1,29 @@ +# mssql_python/pooling.py +from mssql_python import ddbc_bindings +import threading + +class PoolingManager: + _enabled = False + _lock = threading.Lock() + _config = { + "max_size": 100, + "idle_timeout": 600 + } + + @classmethod + def enable(cls, max_size=100, idle_timeout=600): + with cls._lock: + if cls._enabled: + return + + if max_size <= 0 or idle_timeout < 0: + raise ValueError("Invalid pooling parameters") + + ddbc_bindings.enable_pooling(max_size, idle_timeout) + cls._config["max_size"] = max_size + cls._config["idle_timeout"] = idle_timeout + cls._enabled = True + + @classmethod + def is_enabled(cls): + return cls._enabled diff --git a/mssql_python/pybind/connection/connection.cpp b/mssql_python/pybind/connection/connection.cpp index e87e5daf..8073c249 100644 --- a/mssql_python/pybind/connection/connection.cpp +++ b/mssql_python/pybind/connection/connection.cpp @@ -16,8 +16,8 @@ SqlHandlePtr Connection::_envHandle = nullptr; // This class wraps low-level ODBC operations like connect/disconnect, // transaction control, and autocommit configuration. //------------------------------------------------------------------------------------------------- -Connection::Connection(const std::wstring& conn_str, bool autocommit) - : _connStr(conn_str) , _autocommit(autocommit) { +Connection::Connection(const std::wstring& conn_str, bool autocommit, bool use_pooling) + : _connStr(conn_str) , _autocommit(autocommit), _usePool(use_pooling) { if (!_envHandle) { LOG("Allocating environment handle"); SQLHANDLE env = nullptr; diff --git a/mssql_python/pybind/connection/connection.h b/mssql_python/pybind/connection/connection.h index afdeaecb..24e07e0a 100644 --- a/mssql_python/pybind/connection/connection.h +++ b/mssql_python/pybind/connection/connection.h @@ -13,7 +13,7 @@ class Connection { public: - Connection(const std::wstring& conn_str, bool autocommit = false); + Connection(const std::wstring& conn_str, bool autocommit = false, bool use_pooling = false); ~Connection(); // Establish the connection using the stored connection string. diff --git a/mssql_python/pybind/ddbc_bindings.cpp b/mssql_python/pybind/ddbc_bindings.cpp index b6d6b7e7..06fb8cfe 100644 --- a/mssql_python/pybind/ddbc_bindings.cpp +++ b/mssql_python/pybind/ddbc_bindings.cpp @@ -1920,7 +1920,9 @@ PYBIND11_MODULE(ddbc_bindings, m) { py::class_(m, "SqlHandle") .def("free", &SqlHandle::free, "Free the handle"); py::class_(m, "Connection") - .def(py::init(), py::arg("conn_str"), py::arg("autocommit") = false) + .def(py::init(), py::arg("conn_str"), py::arg("autocommit") = false, py::arg("use_pooling") = false, + "Create a new connection with the given connection string, " + "autocommit mode, and pooling option") .def("connect", &Connection::connect) .def("close", &Connection::disconnect, "Close the connection") .def("commit", &Connection::commit, "Commit the current transaction")