Skip to content

Commit

Permalink
Reorder functions to be typing friendly. (#417)
Browse files Browse the repository at this point in the history
  • Loading branch information
jettify committed Apr 4, 2023
1 parent 4d00b85 commit d58c7fd
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 133 deletions.
9 changes: 7 additions & 2 deletions aioodbc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import asyncio
import warnings
from concurrent.futures.thread import ThreadPoolExecutor
from typing import Dict, Optional

from pyodbc import dataSources as _dataSources

Expand All @@ -20,10 +22,13 @@
)


async def dataSources(loop=None, executor=None):
async def dataSources(
loop: Optional[asyncio.AbstractEventLoop] = None,
executor: Optional[ThreadPoolExecutor] = None,
) -> Dict[str, str]:
"""Returns a dictionary mapping available DSNs to their descriptions.
:param loop: asyncio compatible event loop
:param loop: asyncio compatible event loop, deprecated
:param executor: instance of custom ThreadPoolExecutor, if not supplied
default executor will be used
:return dict: mapping of dsn to driver description
Expand Down
176 changes: 88 additions & 88 deletions aioodbc/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,94 +12,6 @@
__all__ = ["connect", "Connection"]


def connect(
*,
dsn,
autocommit=False,
ansi=False,
timeout=0,
loop=None,
executor=None,
echo=False,
after_created=None,
**kwargs,
):
"""Accepts an ODBC connection string and returns a new Connection object.
The connection string can be passed as the string `str`, as a list of
keywords,or a combination of the two. Any keywords except autocommit,
ansi, and timeout are simply added to the connection string.
:param autocommit bool: False or zero, the default, if True or non-zero,
the connection is put into ODBC autocommit mode and statements are
committed automatically.
:param ansi bool: By default, pyodbc first attempts to connect using
the Unicode version of SQLDriverConnectW. If the driver returns IM001
indicating it does not support the Unicode version, the ANSI version
is tried.
:param timeout int: An integer login timeout in seconds, used to set
the SQL_ATTR_LOGIN_TIMEOUT attribute of the connection. The default is
0 which means the database's default timeout, if any, is use
:param after_created callable: support customize configuration after
connection is connected. Must be an async unary function, or leave it
as None.
"""
if loop is not None:
msg = "Explicit loop is deprecated, and has no effect."
warnings.warn(msg, DeprecationWarning, stacklevel=2)
return _ContextManager(
_connect(
dsn=dsn,
autocommit=autocommit,
ansi=ansi,
timeout=timeout,
executor=executor,
echo=echo,
after_created=after_created,
**kwargs,
),
_disconnect,
_disconnect_on_error,
)


async def _disconnect(c: "Connection") -> None:
if not c.autocommit:
await c.commit()
await c.close()


async def _disconnect_on_error(c: "Connection") -> None:
await c.rollback()
await c.close()


async def _connect(
*,
dsn,
autocommit=False,
ansi=False,
timeout=0,
executor=None,
echo=False,
after_created=None,
**kwargs,
):
conn = Connection(
dsn=dsn,
autocommit=autocommit,
ansi=ansi,
timeout=timeout,
echo=echo,
loop=None, # deprecated
executor=executor,
after_created=after_created,
**kwargs,
)
await conn._connect()
return conn


async def _close_cursor(c: Cursor) -> None:
if not c.autocommit:
await c.commit()
Expand Down Expand Up @@ -323,3 +235,91 @@ async def __aenter__(self):
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.close()
return


async def _disconnect(c: "Connection") -> None:
if not c.autocommit:
await c.commit()
await c.close()


async def _disconnect_on_error(c: "Connection") -> None:
await c.rollback()
await c.close()


async def _connect(
*,
dsn,
autocommit=False,
ansi=False,
timeout=0,
executor=None,
echo=False,
after_created=None,
**kwargs,
):
conn = Connection(
dsn=dsn,
autocommit=autocommit,
ansi=ansi,
timeout=timeout,
echo=echo,
loop=None, # deprecated
executor=executor,
after_created=after_created,
**kwargs,
)
await conn._connect()
return conn


def connect(
*,
dsn,
autocommit=False,
ansi=False,
timeout=0,
loop=None,
executor=None,
echo=False,
after_created=None,
**kwargs,
):
"""Accepts an ODBC connection string and returns a new Connection object.
The connection string can be passed as the string `str`, as a list of
keywords,or a combination of the two. Any keywords except autocommit,
ansi, and timeout are simply added to the connection string.
:param autocommit bool: False or zero, the default, if True or non-zero,
the connection is put into ODBC autocommit mode and statements are
committed automatically.
:param ansi bool: By default, pyodbc first attempts to connect using
the Unicode version of SQLDriverConnectW. If the driver returns IM001
indicating it does not support the Unicode version, the ANSI version
is tried.
:param timeout int: An integer login timeout in seconds, used to set
the SQL_ATTR_LOGIN_TIMEOUT attribute of the connection. The default is
0 which means the database's default timeout, if any, is use
:param after_created callable: support customize configuration after
connection is connected. Must be an async unary function, or leave it
as None.
"""
if loop is not None:
msg = "Explicit loop is deprecated, and has no effect."
warnings.warn(msg, DeprecationWarning, stacklevel=2)
return _ContextManager(
_connect(
dsn=dsn,
autocommit=autocommit,
ansi=ansi,
timeout=timeout,
executor=executor,
echo=echo,
after_created=after_created,
**kwargs,
),
_disconnect,
_disconnect_on_error,
)
6 changes: 3 additions & 3 deletions aioodbc/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ class Cursor:
the other cursors.
"""

def __init__(self, pyodbc_cursor, connection, echo=False):
def __init__(self, pyodbc_cursor: pyodbc.Cursor, connection, echo=False):
self._conn = connection
self._impl = pyodbc_cursor
self._impl: pyodbc.Cursor = pyodbc_cursor
self._loop = connection.loop
self._echo = echo
self._echo: bool = echo

async def _run_operation(self, func, *args, **kwargs):
# execute func in thread pool of attached to cursor connection
Expand Down
80 changes: 40 additions & 40 deletions aioodbc/pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,46 +14,6 @@
__all__ = ["create_pool", "Pool"]


async def _destroy_pool(pool: "Pool") -> None:
pool.close()
await pool.wait_closed()


def create_pool(
minsize=10, maxsize=10, echo=False, loop=None, pool_recycle=-1, **kwargs
):
if loop is not None:
msg = "Explicit loop is deprecated, and has no effect."
warnings.warn(msg, DeprecationWarning, stacklevel=2)

return _ContextManager[Pool](
_create_pool(
minsize=minsize,
maxsize=maxsize,
echo=echo,
pool_recycle=pool_recycle,
**kwargs
),
_destroy_pool,
)


async def _create_pool(
minsize=10, maxsize=10, echo=False, pool_recycle=-1, **kwargs
):
pool = Pool(
minsize=minsize,
maxsize=maxsize,
echo=echo,
pool_recycle=pool_recycle,
**kwargs
)
if minsize > 0:
async with pool._cond:
await pool._fill_free_pool(False)
return pool


class Pool(asyncio.AbstractServer):
"""Connection pool"""

Expand Down Expand Up @@ -229,3 +189,43 @@ async def __aenter__(self):
async def __aexit__(self, exc_type, exc_val, exc_tb):
self.close()
await self.wait_closed()


async def _destroy_pool(pool: "Pool") -> None:
pool.close()
await pool.wait_closed()


async def _create_pool(
minsize=10, maxsize=10, echo=False, pool_recycle=-1, **kwargs
):
pool = Pool(
minsize=minsize,
maxsize=maxsize,
echo=echo,
pool_recycle=pool_recycle,
**kwargs
)
if minsize > 0:
async with pool._cond:
await pool._fill_free_pool(False)
return pool


def create_pool(
minsize=10, maxsize=10, echo=False, loop=None, pool_recycle=-1, **kwargs
):
if loop is not None:
msg = "Explicit loop is deprecated, and has no effect."
warnings.warn(msg, DeprecationWarning, stacklevel=2)

return _ContextManager[Pool](
_create_pool(
minsize=minsize,
maxsize=maxsize,
echo=echo,
pool_recycle=pool_recycle,
**kwargs
),
_destroy_pool,
)

0 comments on commit d58c7fd

Please sign in to comment.