Skip to content

Commit 1efd5d5

Browse files
committed
Update docs & weakref
1 parent cf349ce commit 1efd5d5

26 files changed

+1144
-368
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,3 +127,6 @@ dmypy.json
127127

128128
# Pyre type checker
129129
.pyre/
130+
131+
# Spinx
132+
/docs/build

README.md

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[![pyversions](https://img.shields.io/pypi/pyversions/cx-Oracle-async.svg)](https://pypi.org/project/cx-Oracle-async/)
55
[![Publish](https://github.com/GoodManWEN/cx_Oracle_async/workflows/Publish/badge.svg)](https://github.com/GoodManWEN/cx_Oracle_async/actions?query=workflow:Publish)
66
[![Build](https://github.com/GoodManWEN/cx_Oracle_async/workflows/Build/badge.svg)](https://github.com/GoodManWEN/cx_Oracle_async/actions?query=workflow:Build)
7+
[![Docs](https://readthedocs.org/projects/cx-oracle-async/badge/?version=latest)](https://readthedocs.org/projects/cx-oracle-async/)
78

89
A very simple asynchronous wrapper that allows you to get access to the Oracle database in asyncio programs.
910

@@ -16,15 +17,19 @@ Easy to use , buy may not the best practice for efficiency concern.
1617
## Install
1718

1819
pip install cx_Oracle_async
19-
20-
## Usage
20+
21+
## Feature
2122
- Nearly all the same as aiomysql in asynchronous operational approach , with limited cx_Oracle feature support.
2223
- No automaticly date format transition built-in.
23-
- AQ feature added , check [docs here](https://github.com/GoodManWEN/cx_Oracle_async/blob/main/docs/temporary_document_of_AQ.md) for further information.
24+
- AQ feature added , check [docs here](https://cx_oracle_async.readthedocs.io/en/latest/user_guide/advancedfeatures.html#oracle-advanced-queuing-aq) for further information.
2425
- You can modify some of the connection properties simply like you're using cx_Oracle.
2526
- You can do basic insert / select / delete etc.
2627
- If you're connecting to database which is on a different machine from python process , you need to install oracle client module in order to use this library. Check [cx-Oracle's installation guide](https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html) for further information.
2728

29+
## Documentation
30+
31+
[https://cx_oracle_async.readthedocs.io](https://cx_oracle_async.readthedocs.io)
32+
2833
## Performance
2934
query type | asynchronous multithreading | synchronous multithreading | synchronous single thread
3035
-|-|-|-
@@ -38,7 +43,7 @@ single line insertion | 1341.88 q/s | 1898 q/s | 1685.17 q/s
3843
*You can find performance test codes [here](https://github.com/GoodManWEN/cx_Oracle_async/blob/main/misc).*
3944

4045
## Examples
41-
Before running examples , make sure you've already installed a [oracle client](https://github.com/GoodManWEN/cx_Oracle_async#usage) on your machine.
46+
Before running examples , make sure you've already installed a [Oracle Client](https://cx-oracle-async.readthedocs.io/en/latest/user_guide/quickstart.html#install-oracle-client) on your machine.
4247
```Python
4348
# basic_usages.py
4449
import asyncio
@@ -57,42 +62,11 @@ async def main():
5762

5863
async with oracle_pool.acquire() as connection:
5964
async with connection.cursor() as cursor:
60-
# single fetch
61-
sql_1 = "SELECT * FROM SCOTT.DEPT WHERE deptno = :a"
62-
await cursor.execute(sql_1 , (10 , ))
63-
print(await cursor.fetchone())
64-
65-
# multiple inert
66-
sql_2 = "INSERT INTO SCOTT.DEPT(deptno , dname) VALUES (:a , :b)"
67-
sql_2_data = [
68-
[60 , "Hello"],
69-
[70 , "World"],
70-
]
71-
await cursor.executemany(sql_2 , sql_2_data)
72-
await connection.commit()
73-
74-
# multiple fetch
75-
sql_3 = "SELECT * FROM SCOTT.DEPT WHERE deptno >= :a"
76-
await cursor.execute(sql_3 , (60 , ))
65+
await cursor.execute("SELECT * FROM V$SESSION")
7766
print(await cursor.fetchall())
7867

7968
await oracle_pool.close()
8069

8170
if __name__ == '__main__':
8271
asyncio.run(main())
83-
```
84-
85-
Or you can connect to database via dsn style:
86-
```Python
87-
# makedsn.py
88-
import asyncio
89-
import cx_Oracle_async
90-
91-
async def main():
92-
# same api as cx_Oracle.makedsn with 4 limited parameters(host , port , sid , service_name).
93-
dsn = cx_Oracle_async.makedsn(host = 'localhost' , port = '1521' , service_name = 'orcl')
94-
async with cx_Oracle_async.create_pool(user='', password='',dsn = dsn) as pool:
95-
...
96-
97-
asyncio.run(main())
98-
```
72+
```

cx_Oracle_async/connections.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ async def commit(self):
9191
return await self._loop.run_in_executor(self._thread_pool , self._conn.commit)
9292

9393
async def release(self):
94-
self._pool_wrapper._unoccupied(self._conn)
94+
self._pool_wrapper._ofree(self)
9595
return await self._loop.run_in_executor(self._thread_pool , self._pool.release , self._conn)
9696

9797
async def cancel(self):

cx_Oracle_async/cursors.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ def __init__(self , cursor : Cursor, loop : 'ProactorEventLoop' , thread_pool :
2121
self._thread_pool = thread_pool
2222

2323
async def execute(self , sql , *args , **kwargs):
24+
if kwargs:
25+
return await self._loop.run_in_executor(
26+
self._thread_pool ,
27+
lambda : self._cursor.execute(sql , *args , **kwargs)
28+
)
2429
return await self._loop.run_in_executor(self._thread_pool , self._cursor.execute , sql , *args , **kwargs)
2530

2631
async def executemany(self , sql , *args , **kwargs):

cx_Oracle_async/pools.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from .connections import AsyncConnectionWrapper , AsyncConnectionWrapper_context
33
from ThreadPoolExecutorPlus import ThreadPoolExecutor
44
from cx_Oracle import Connection , SessionPool
5+
from weakref import WeakSet
56
from types import CoroutineType
67
import asyncio
78
import platform
@@ -38,22 +39,24 @@ def __init__(self , pool : SessionPool, loop : 'ProactorEventLoop' = None):
3839
self._thread_pool.set_daemon_opts(min_workers = max(4 , pool.min << 1))
3940
self._loop = loop
4041
self._pool = pool
41-
self._occupied = set()
42+
self._occupied = WeakSet()
4243

4344
def acquire(self):
4445
coro = self._loop.run_in_executor(self._thread_pool , self._acquire)
4546
return AsyncConnectionWrapper_context(coro)
4647

4748
def _acquire(self):
48-
_conn = self._pool.acquire()
49-
self._occupied.update((_conn , ))
50-
return AsyncConnectionWrapper(_conn , self._loop , self._thread_pool , self._pool , self)
49+
wrapper = AsyncConnectionWrapper(self._pool.acquire() , self._loop , self._thread_pool , self._pool , self)
50+
self._occupied.add(wrapper)
51+
return wrapper
5152

52-
def _unoccupied(self , obj: Connection):
53-
self._occupied.remove(obj)
53+
def _ofree(self , obj: AsyncConnectionWrapper):
54+
if obj in self._occupied:
55+
self._occupied.remove(obj)
5456

55-
async def release(self , conn: Connection):
56-
return await self._loop.run_in_executor(self._thread_pool , self._pool.release , conn)
57+
async def release(self , conn: AsyncConnectionWrapper):
58+
self._ofree(conn)
59+
return await self._loop.run_in_executor(self._thread_pool , self._pool.release , conn._conn)
5760

5861
async def drop(self , conn: Connection):
5962
return await self._loop.run_in_executor(self._thread_pool , self._pool.drop , conn)
@@ -67,8 +70,8 @@ async def close(self , force: bool = False , interrupt: bool = False):
6770
Do make sure this option works fine with your working enviornment.
6871
'''
6972
while self._occupied:
70-
_conn = self._occupied.pop()
73+
wrapper = self._occupied.pop()
7174
if interrupt:
72-
await self._loop.run_in_executor(self._thread_pool , _conn.cancel)
75+
await self._loop.run_in_executor(self._thread_pool , wrapper._conn.cancel)
7376

74-
return await self._loop.run_in_executor(self._thread_pool , self._pool.close , force)
77+
return await self._loop.run_in_executor(self._thread_pool , self._pool.close , force)

docs/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Minimal makefile for Sphinx documentation
2+
#
3+
4+
# You can set these variables from the command line, and also
5+
# from the environment for the first two.
6+
SPHINXOPTS ?=
7+
SPHINXBUILD ?= sphinx-build
8+
SOURCEDIR = source
9+
BUILDDIR = build
10+
11+
# Put it first so that "make" without argument is like "make help".
12+
help:
13+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14+
15+
.PHONY: help Makefile
16+
17+
# Catch-all target: route all unknown targets to Sphinx using the new
18+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19+
%: Makefile
20+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

docs/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
The generated cx_Oracle_async documentation is at https://cx_oracle_async.readthedocs.io/
2+
3+
This directory contains the documentation source. It is written using reST
4+
(re-Structured Text) format source files which are processed using Sphinx and
5+
turned into HTML, PDF or ePub documents. If you wish to build these yourself,
6+
you need to install Sphinx. Sphinx is available on many Linux distributions as a
7+
pre-built package. You can also install Sphinx on all platforms using the Python
8+
package manager "pip". For more information on Sphinx, please visit this page:
9+
10+
http://www.sphinx-doc.org
11+
12+
Once Sphinx is installed, the supplied Makefile can be used to build the
13+
different targets.

docs/make.bat

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@ECHO OFF
2+
3+
pushd %~dp0
4+
5+
REM Command file for Sphinx documentation
6+
7+
if "%SPHINXBUILD%" == "" (
8+
set SPHINXBUILD=sphinx-build
9+
)
10+
set SOURCEDIR=source
11+
set BUILDDIR=build
12+
13+
if "%1" == "" goto help
14+
15+
%SPHINXBUILD% >NUL 2>NUL
16+
if errorlevel 9009 (
17+
echo.
18+
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19+
echo.installed, then set the SPHINXBUILD environment variable to point
20+
echo.to the full path of the 'sphinx-build' executable. Alternatively you
21+
echo.may add the Sphinx directory to PATH.
22+
echo.
23+
echo.If you don't have Sphinx installed, grab it from
24+
echo.http://sphinx-doc.org/
25+
exit /b 1
26+
)
27+
28+
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29+
goto end
30+
31+
:help
32+
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33+
34+
:end
35+
popd

docs/requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Sphinx
2+
sphinx-autobuild
3+
recommonmark
4+
sphinx-rtd-theme
5+
sphinx_markdown_tables

docs/serve.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
sphinx-autobuild source build/html

0 commit comments

Comments
 (0)