sqlcycli 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. sqlcycli-1.0.1/LICENSE +42 -0
  2. sqlcycli-1.0.1/MANIFEST.in +12 -0
  3. sqlcycli-1.0.1/PKG-INFO +174 -0
  4. sqlcycli-1.0.1/README.md +152 -0
  5. sqlcycli-1.0.1/pyproject.toml +8 -0
  6. sqlcycli-1.0.1/setup.cfg +41 -0
  7. sqlcycli-1.0.1/setup.py +107 -0
  8. sqlcycli-1.0.1/src/sqlcycli/__init__.pxd +0 -0
  9. sqlcycli-1.0.1/src/sqlcycli/__init__.py +46 -0
  10. sqlcycli-1.0.1/src/sqlcycli/_auth.c +31124 -0
  11. sqlcycli-1.0.1/src/sqlcycli/_auth.pxd +23 -0
  12. sqlcycli-1.0.1/src/sqlcycli/_auth.py +343 -0
  13. sqlcycli-1.0.1/src/sqlcycli/_connect.c +22401 -0
  14. sqlcycli-1.0.1/src/sqlcycli/_connect.pxd +88 -0
  15. sqlcycli-1.0.1/src/sqlcycli/_connect.py +458 -0
  16. sqlcycli-1.0.1/src/sqlcycli/_optionfile.c +17035 -0
  17. sqlcycli-1.0.1/src/sqlcycli/_optionfile.pxd +15 -0
  18. sqlcycli-1.0.1/src/sqlcycli/_optionfile.py +257 -0
  19. sqlcycli-1.0.1/src/sqlcycli/_ssl.c +15297 -0
  20. sqlcycli-1.0.1/src/sqlcycli/_ssl.pxd +21 -0
  21. sqlcycli-1.0.1/src/sqlcycli/_ssl.py +233 -0
  22. sqlcycli-1.0.1/src/sqlcycli/aio/__init__.pxd +0 -0
  23. sqlcycli-1.0.1/src/sqlcycli/aio/__init__.py +24 -0
  24. sqlcycli-1.0.1/src/sqlcycli/aio/connection.c +126075 -0
  25. sqlcycli-1.0.1/src/sqlcycli/aio/connection.pxd +158 -0
  26. sqlcycli-1.0.1/src/sqlcycli/aio/connection.py +3611 -0
  27. sqlcycli-1.0.1/src/sqlcycli/aio/pool.c +55631 -0
  28. sqlcycli-1.0.1/src/sqlcycli/aio/pool.pxd +85 -0
  29. sqlcycli-1.0.1/src/sqlcycli/aio/pool.py +1301 -0
  30. sqlcycli-1.0.1/src/sqlcycli/charset.c +25647 -0
  31. sqlcycli-1.0.1/src/sqlcycli/charset.pxd +35 -0
  32. sqlcycli-1.0.1/src/sqlcycli/charset.py +499 -0
  33. sqlcycli-1.0.1/src/sqlcycli/connection.c +88260 -0
  34. sqlcycli-1.0.1/src/sqlcycli/connection.pxd +227 -0
  35. sqlcycli-1.0.1/src/sqlcycli/connection.py +3701 -0
  36. sqlcycli-1.0.1/src/sqlcycli/constants/CLIENT.py +38 -0
  37. sqlcycli-1.0.1/src/sqlcycli/constants/COMMAND.py +32 -0
  38. sqlcycli-1.0.1/src/sqlcycli/constants/CR.py +79 -0
  39. sqlcycli-1.0.1/src/sqlcycli/constants/ER.py +477 -0
  40. sqlcycli-1.0.1/src/sqlcycli/constants/FIELD_TYPE.py +31 -0
  41. sqlcycli-1.0.1/src/sqlcycli/constants/FLAG.py +15 -0
  42. sqlcycli-1.0.1/src/sqlcycli/constants/SERVER_STATUS.py +10 -0
  43. sqlcycli-1.0.1/src/sqlcycli/constants/_CLIENT.c +5153 -0
  44. sqlcycli-1.0.1/src/sqlcycli/constants/_CLIENT.pxd +9 -0
  45. sqlcycli-1.0.1/src/sqlcycli/constants/_CLIENT.py +31 -0
  46. sqlcycli-1.0.1/src/sqlcycli/constants/_COMMAND.c +5330 -0
  47. sqlcycli-1.0.1/src/sqlcycli/constants/_COMMAND.pxd +10 -0
  48. sqlcycli-1.0.1/src/sqlcycli/constants/_COMMAND.py +36 -0
  49. sqlcycli-1.0.1/src/sqlcycli/constants/_FIELD_TYPE.c +5282 -0
  50. sqlcycli-1.0.1/src/sqlcycli/constants/_FIELD_TYPE.pxd +8 -0
  51. sqlcycli-1.0.1/src/sqlcycli/constants/_FIELD_TYPE.py +34 -0
  52. sqlcycli-1.0.1/src/sqlcycli/constants/_SERVER_STATUS.c +4804 -0
  53. sqlcycli-1.0.1/src/sqlcycli/constants/_SERVER_STATUS.pxd +8 -0
  54. sqlcycli-1.0.1/src/sqlcycli/constants/_SERVER_STATUS.py +16 -0
  55. sqlcycli-1.0.1/src/sqlcycli/constants/__init__.pxd +0 -0
  56. sqlcycli-1.0.1/src/sqlcycli/constants/__init__.py +0 -0
  57. sqlcycli-1.0.1/src/sqlcycli/errors.c +26419 -0
  58. sqlcycli-1.0.1/src/sqlcycli/errors.pxd +7 -0
  59. sqlcycli-1.0.1/src/sqlcycli/errors.py +402 -0
  60. sqlcycli-1.0.1/src/sqlcycli/protocol.c +33623 -0
  61. sqlcycli-1.0.1/src/sqlcycli/protocol.pxd +65 -0
  62. sqlcycli-1.0.1/src/sqlcycli/protocol.py +626 -0
  63. sqlcycli-1.0.1/src/sqlcycli/transcode.c +37092 -0
  64. sqlcycli-1.0.1/src/sqlcycli/transcode.pxd +301 -0
  65. sqlcycli-1.0.1/src/sqlcycli/transcode.py +2118 -0
  66. sqlcycli-1.0.1/src/sqlcycli/typeref.c +5691 -0
  67. sqlcycli-1.0.1/src/sqlcycli/typeref.pxd +20 -0
  68. sqlcycli-1.0.1/src/sqlcycli/typeref.py +46 -0
  69. sqlcycli-1.0.1/src/sqlcycli/utils.c +18107 -0
  70. sqlcycli-1.0.1/src/sqlcycli/utils.pxd +509 -0
  71. sqlcycli-1.0.1/src/sqlcycli/utils.py +3 -0
  72. sqlcycli-1.0.1/src/sqlcycli.egg-info/PKG-INFO +174 -0
  73. sqlcycli-1.0.1/src/sqlcycli.egg-info/SOURCES.txt +76 -0
  74. sqlcycli-1.0.1/src/sqlcycli.egg-info/dependency_links.txt +1 -0
  75. sqlcycli-1.0.1/src/sqlcycli.egg-info/not-zip-safe +1 -0
  76. sqlcycli-1.0.1/src/sqlcycli.egg-info/requires.txt +5 -0
  77. sqlcycli-1.0.1/src/sqlcycli.egg-info/top_level.txt +1 -0
sqlcycli-1.0.1/LICENSE ADDED
@@ -0,0 +1,42 @@
1
+ MIT License
2
+
3
+ sqlcycli - Copyright (c) 2023 Jifu Chen.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
22
+
23
+ --------------------------------------------------------------------------------
24
+ Copyright (c) 2010, 2013 PyMySQL contributors
25
+
26
+ Permission is hereby granted, free of charge, to any person obtaining a copy
27
+ of this software and associated documentation files (the "Software"), to deal
28
+ in the Software without restriction, including without limitation the rights
29
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
30
+ copies of the Software, and to permit persons to whom the Software is
31
+ furnished to do so, subject to the following conditions:
32
+
33
+ The above copyright notice and this permission notice shall be included in
34
+ all copies or substantial portions of the Software.
35
+
36
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
37
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
38
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
39
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
40
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
41
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
42
+ THE SOFTWARE.
@@ -0,0 +1,12 @@
1
+ include LICENSE
2
+ include README.md
3
+
4
+ include src/sqlcycli/aio/*.pxd
5
+ include src/sqlcycli/aio/*.py
6
+ include src/sqlcycli/aio/*.pyx
7
+ include src/sqlcycli/constants/*.pxd
8
+ include src/sqlcycli/constants/*.py
9
+ include src/sqlcycli/constants/*.pyx
10
+ include src/sqlcycli/*.pxd
11
+ include src/sqlcycli/*.py
12
+ include src/sqlcycli/*.pyx
@@ -0,0 +1,174 @@
1
+ Metadata-Version: 2.1
2
+ Name: sqlcycli
3
+ Version: 1.0.1
4
+ Summary: Fast MySQL driver build in Cython (Sync and Async).
5
+ Home-page: https://github.com/AresJef/SQLCyCli
6
+ Author: Jiefu Chen
7
+ Author-email: keppa1991@163.com
8
+ License: MIT license
9
+ Keywords: mysql,mariadb,pymysql,aiomysql,cython,asyncio
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Operating System :: Unix
12
+ Classifier: Operating System :: MacOS :: MacOS X
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: cytimes>=1.0.3
18
+ Requires-Dist: numpy>=1.25.2
19
+ Requires-Dist: orjson>=3.10.2
20
+ Requires-Dist: pandas>=2.1.0
21
+ Requires-Dist: mysqlclient>=2.2.0
22
+
23
+ ## Fast MySQL driver build in Cython (Sync and Async).
24
+
25
+ Created to be used in a project, this package is published to github for ease of management and installation across different modules.
26
+
27
+ ### Installation
28
+ Install from `PyPi`
29
+ ``` bash
30
+ pip install sqlcycli
31
+ ```
32
+
33
+ Install from `github`
34
+ ``` bash
35
+ pip install git+https://github.com/AresJef/SQLCyCli.git
36
+ ```
37
+
38
+ ### Requirements
39
+ - Python 3.10 or higher.
40
+ - MySQL 5.5 or higher.
41
+
42
+ ### Features
43
+ - Written in [Cython](https://cython.org/) for optimal performance (especially for SELECT/INSERT query).
44
+ - All classes and methods are well documented and static typed.
45
+ - Supports both `Sync` and `Async` connection to the server.
46
+ - API Compatiable with [PyMySQL](https://github.com/PyMySQL/PyMySQL) and [aiomysql](https://github.com/aio-libs/aiomysql).
47
+ - Support conversion (escape) for most of the native python types, and objects from libaray [numpy](https://github.com/numpy/numpy) and [pandas](https://github.com/pandas-dev/pandas). Does `NOT` support custom conversion (escape).
48
+
49
+ ### Benchmark
50
+ The following result comes from [benchmark](./src/benchmark.py):
51
+ - Device: MacbookPro M1Pro(2E8P) 32GB
52
+ - Python: 3.12.4
53
+ - MySQL: 8.3.0
54
+ - mysqlclient: 2.2.4
55
+ - PyMySQL: 1.1.1
56
+ - aiomysql: 0.2.0
57
+ - asyncmy: 0.2.9
58
+ ```
59
+ # Unit: second | Lower is better
60
+ name type rows insert-per-row insert-bulk select-per-row select-all update-per-row update-all delete-per-row delete-all
61
+ mysqlclient sync 50000 1.734200 0.427027 1.756226 0.117552 1.901870 0.365056 1.651022 0.131151
62
+ SQLCyCli sync 50000 2.203967 0.293410 2.331576 0.062152 2.279076 0.352106 2.115025 0.107902
63
+ PyMySQL sync 50000 2.607349 0.412063 4.219286 0.321089 2.572826 0.345419 2.304015 0.104720
64
+ SQLCyCli async 50000 3.342991 0.270254 4.297667 0.141201 3.466729 0.346168 3.343880 0.105293
65
+ aiomysql async 50000 3.464662 0.384193 5.115068 0.322858 3.582689 0.345661 3.444377 0.104894
66
+ asyncmy async 50000 3.851011 0.416715 5.604330 0.314939 3.824736 0.346903 3.580444 0.104748
67
+ ```
68
+
69
+ ### Usage
70
+ #### Use `connect()` to create one connection (`Sync` or `Async`) to the server.
71
+ ```python
72
+ import asyncio
73
+ import sqlcycli
74
+
75
+ HOST = "localhost"
76
+ PORT = 3306
77
+ USER = "root"
78
+ PSWD = "password"
79
+
80
+ # Synchronous Connection
81
+ def test_sync_connection() -> None:
82
+ with sqlcycli.connect(HOST, PORT, USER, PSWD) as conn:
83
+ with conn.cursor() as cur:
84
+ cur.execute("SELECT 1")
85
+ res = cur.fetchone()
86
+ assert res == (1,)
87
+ # Connection closed
88
+ assert conn.closed()
89
+
90
+ # Asynchronous Connection
91
+ async def test_async_connection() -> None:
92
+ async with sqlcycli.connect(HOST, PORT, USER, PSWD) as conn:
93
+ async with conn.cursor() as cur:
94
+ await cur.execute("SELECT 1")
95
+ res = await cur.fetchone()
96
+ assert res == (1,)
97
+ # Connection closed
98
+ assert conn.closed()
99
+
100
+ if __name__ == "__main__":
101
+ test_sync_connection()
102
+ asyncio.run(test_async_connection())
103
+ ```
104
+
105
+ #### Use `create_pool()` to create a Pool for managing and maintaining `Async` connections to the server.
106
+ ```python
107
+ import asyncio
108
+ import sqlcycli
109
+
110
+ HOST = "localhost"
111
+ PORT = 3306
112
+ USER = "root"
113
+ PSWD = "password"
114
+
115
+ # Pool (Context Manager: Connected)
116
+ async def test_pool_context_connected() -> None:
117
+ async with sqlcycli.create_pool(HOST, PORT, USER, PSWD, min_size=1) as pool:
118
+ # Pool is connected: 1 free connection (min_size=1)
119
+ assert not pool.closed() and pool.free == 1
120
+ async with pool.acquire() as conn:
121
+ async with conn.cursor() as cur:
122
+ await cur.execute("SELECT 1")
123
+ res = await cur.fetchone()
124
+ assert res == (1,)
125
+ # Pool closed
126
+ assert pool.closed() and pool.total == 0
127
+
128
+ # Pool (Context Manager: Disconnected)
129
+ async def test_pool_context_disconnected() -> None:
130
+ with sqlcycli.create_pool(HOST, PORT, USER, PSWD, min_size=1) as pool:
131
+ # Pool is not connected: 0 free connection (min_size=1)
132
+ assert pool.closed() and pool.free == 0
133
+ # Connect automatically
134
+ async with pool.acquire() as conn:
135
+ async with conn.cursor() as cur:
136
+ await cur.execute("SELECT 1")
137
+ res = await cur.fetchone()
138
+ assert res == (1,)
139
+ # 1 free connection
140
+ assert pool.free == 1
141
+ # Pool closed
142
+ assert pool.closed() and pool.total == 0
143
+
144
+ # Pool (Create Directly: Connected)
145
+ async def test_pool_direct_connected() -> None:
146
+ pool = await sqlcycli.create_pool(HOST, PORT, USER, PSWD, min_size=1)
147
+ # Pool is connected: 1 free connection (min_size=1)
148
+ assert not pool.closed() and pool.free == 1
149
+ async with pool.acquire() as conn:
150
+ async with conn.cursor() as cur:
151
+ await cur.execute("SELECT 1")
152
+ res = await cur.fetchone()
153
+ assert res == (1,)
154
+ # Close pool manually
155
+ await pool.close()
156
+ assert pool.closed() and pool.total == 0
157
+
158
+ if __name__ == "__main__":
159
+ asyncio.run(test_pool_context_connected())
160
+ asyncio.run(test_pool_context_disconnected())
161
+ asyncio.run(test_pool_direct_connected())
162
+ ```
163
+
164
+ ### Acknowledgements
165
+ SQLCyCli is build on top of the following open-source repositories:
166
+ - [aiomysql](https://github.com/aio-libs/aiomysql)
167
+ - [PyMySQL](https://github.com/PyMySQL/PyMySQL)
168
+
169
+ SQLCyCli is based on the following open-source repositories:
170
+ - [cytimes](https://github.com/AresJef/cyTimes)
171
+ - [numpy](https://github.com/numpy/numpy)
172
+ - [orjson](https://github.com/ijl/orjson)
173
+ - [pandas](https://github.com/pandas-dev/pandas)
174
+ - [mysqlclient](https://github.com/PyMySQL/mysqlclient)
@@ -0,0 +1,152 @@
1
+ ## Fast MySQL driver build in Cython (Sync and Async).
2
+
3
+ Created to be used in a project, this package is published to github for ease of management and installation across different modules.
4
+
5
+ ### Installation
6
+ Install from `PyPi`
7
+ ``` bash
8
+ pip install sqlcycli
9
+ ```
10
+
11
+ Install from `github`
12
+ ``` bash
13
+ pip install git+https://github.com/AresJef/SQLCyCli.git
14
+ ```
15
+
16
+ ### Requirements
17
+ - Python 3.10 or higher.
18
+ - MySQL 5.5 or higher.
19
+
20
+ ### Features
21
+ - Written in [Cython](https://cython.org/) for optimal performance (especially for SELECT/INSERT query).
22
+ - All classes and methods are well documented and static typed.
23
+ - Supports both `Sync` and `Async` connection to the server.
24
+ - API Compatiable with [PyMySQL](https://github.com/PyMySQL/PyMySQL) and [aiomysql](https://github.com/aio-libs/aiomysql).
25
+ - Support conversion (escape) for most of the native python types, and objects from libaray [numpy](https://github.com/numpy/numpy) and [pandas](https://github.com/pandas-dev/pandas). Does `NOT` support custom conversion (escape).
26
+
27
+ ### Benchmark
28
+ The following result comes from [benchmark](./src/benchmark.py):
29
+ - Device: MacbookPro M1Pro(2E8P) 32GB
30
+ - Python: 3.12.4
31
+ - MySQL: 8.3.0
32
+ - mysqlclient: 2.2.4
33
+ - PyMySQL: 1.1.1
34
+ - aiomysql: 0.2.0
35
+ - asyncmy: 0.2.9
36
+ ```
37
+ # Unit: second | Lower is better
38
+ name type rows insert-per-row insert-bulk select-per-row select-all update-per-row update-all delete-per-row delete-all
39
+ mysqlclient sync 50000 1.734200 0.427027 1.756226 0.117552 1.901870 0.365056 1.651022 0.131151
40
+ SQLCyCli sync 50000 2.203967 0.293410 2.331576 0.062152 2.279076 0.352106 2.115025 0.107902
41
+ PyMySQL sync 50000 2.607349 0.412063 4.219286 0.321089 2.572826 0.345419 2.304015 0.104720
42
+ SQLCyCli async 50000 3.342991 0.270254 4.297667 0.141201 3.466729 0.346168 3.343880 0.105293
43
+ aiomysql async 50000 3.464662 0.384193 5.115068 0.322858 3.582689 0.345661 3.444377 0.104894
44
+ asyncmy async 50000 3.851011 0.416715 5.604330 0.314939 3.824736 0.346903 3.580444 0.104748
45
+ ```
46
+
47
+ ### Usage
48
+ #### Use `connect()` to create one connection (`Sync` or `Async`) to the server.
49
+ ```python
50
+ import asyncio
51
+ import sqlcycli
52
+
53
+ HOST = "localhost"
54
+ PORT = 3306
55
+ USER = "root"
56
+ PSWD = "password"
57
+
58
+ # Synchronous Connection
59
+ def test_sync_connection() -> None:
60
+ with sqlcycli.connect(HOST, PORT, USER, PSWD) as conn:
61
+ with conn.cursor() as cur:
62
+ cur.execute("SELECT 1")
63
+ res = cur.fetchone()
64
+ assert res == (1,)
65
+ # Connection closed
66
+ assert conn.closed()
67
+
68
+ # Asynchronous Connection
69
+ async def test_async_connection() -> None:
70
+ async with sqlcycli.connect(HOST, PORT, USER, PSWD) as conn:
71
+ async with conn.cursor() as cur:
72
+ await cur.execute("SELECT 1")
73
+ res = await cur.fetchone()
74
+ assert res == (1,)
75
+ # Connection closed
76
+ assert conn.closed()
77
+
78
+ if __name__ == "__main__":
79
+ test_sync_connection()
80
+ asyncio.run(test_async_connection())
81
+ ```
82
+
83
+ #### Use `create_pool()` to create a Pool for managing and maintaining `Async` connections to the server.
84
+ ```python
85
+ import asyncio
86
+ import sqlcycli
87
+
88
+ HOST = "localhost"
89
+ PORT = 3306
90
+ USER = "root"
91
+ PSWD = "password"
92
+
93
+ # Pool (Context Manager: Connected)
94
+ async def test_pool_context_connected() -> None:
95
+ async with sqlcycli.create_pool(HOST, PORT, USER, PSWD, min_size=1) as pool:
96
+ # Pool is connected: 1 free connection (min_size=1)
97
+ assert not pool.closed() and pool.free == 1
98
+ async with pool.acquire() as conn:
99
+ async with conn.cursor() as cur:
100
+ await cur.execute("SELECT 1")
101
+ res = await cur.fetchone()
102
+ assert res == (1,)
103
+ # Pool closed
104
+ assert pool.closed() and pool.total == 0
105
+
106
+ # Pool (Context Manager: Disconnected)
107
+ async def test_pool_context_disconnected() -> None:
108
+ with sqlcycli.create_pool(HOST, PORT, USER, PSWD, min_size=1) as pool:
109
+ # Pool is not connected: 0 free connection (min_size=1)
110
+ assert pool.closed() and pool.free == 0
111
+ # Connect automatically
112
+ async with pool.acquire() as conn:
113
+ async with conn.cursor() as cur:
114
+ await cur.execute("SELECT 1")
115
+ res = await cur.fetchone()
116
+ assert res == (1,)
117
+ # 1 free connection
118
+ assert pool.free == 1
119
+ # Pool closed
120
+ assert pool.closed() and pool.total == 0
121
+
122
+ # Pool (Create Directly: Connected)
123
+ async def test_pool_direct_connected() -> None:
124
+ pool = await sqlcycli.create_pool(HOST, PORT, USER, PSWD, min_size=1)
125
+ # Pool is connected: 1 free connection (min_size=1)
126
+ assert not pool.closed() and pool.free == 1
127
+ async with pool.acquire() as conn:
128
+ async with conn.cursor() as cur:
129
+ await cur.execute("SELECT 1")
130
+ res = await cur.fetchone()
131
+ assert res == (1,)
132
+ # Close pool manually
133
+ await pool.close()
134
+ assert pool.closed() and pool.total == 0
135
+
136
+ if __name__ == "__main__":
137
+ asyncio.run(test_pool_context_connected())
138
+ asyncio.run(test_pool_context_disconnected())
139
+ asyncio.run(test_pool_direct_connected())
140
+ ```
141
+
142
+ ### Acknowledgements
143
+ SQLCyCli is build on top of the following open-source repositories:
144
+ - [aiomysql](https://github.com/aio-libs/aiomysql)
145
+ - [PyMySQL](https://github.com/PyMySQL/PyMySQL)
146
+
147
+ SQLCyCli is based on the following open-source repositories:
148
+ - [cytimes](https://github.com/AresJef/cyTimes)
149
+ - [numpy](https://github.com/numpy/numpy)
150
+ - [orjson](https://github.com/ijl/orjson)
151
+ - [pandas](https://github.com/pandas-dev/pandas)
152
+ - [mysqlclient](https://github.com/PyMySQL/mysqlclient)
@@ -0,0 +1,8 @@
1
+ [build-system]
2
+ requires = [
3
+ "setuptools>=68.0.0",
4
+ "wheel>=0.41.0",
5
+ "Cython==3.0.10",
6
+ "numpy>=1.25.2",
7
+ ]
8
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,41 @@
1
+ [metadata]
2
+ name = sqlcycli
3
+ version = 1.0.1
4
+ author = Jiefu Chen
5
+ author_email = keppa1991@163.com
6
+ description = Fast MySQL driver build in Cython (Sync and Async).
7
+ url = https://github.com/AresJef/SQLCyCli
8
+ long_description = file: README.md
9
+ long_description_content_type = text/markdown
10
+ keywords = mysql, mariadb, pymysql, aiomysql, cython, asyncio
11
+ license = MIT license
12
+ classifiers =
13
+ Programming Language :: Python :: 3
14
+ Operating System :: Unix
15
+ Operating System :: MacOS :: MacOS X
16
+ Operating System :: Microsoft :: Windows
17
+
18
+ [options]
19
+ zip_safe = False
20
+ include_package_data = True
21
+ package_dir =
22
+ = src
23
+ packages = find:
24
+ python_requires = >=3.10
25
+ install_requires =
26
+ cytimes>=1.0.3
27
+ numpy>=1.25.2
28
+ orjson>=3.10.2
29
+ pandas>=2.1.0
30
+ mysqlclient>=2.2.0
31
+
32
+ [options.packages.find]
33
+ where = src
34
+
35
+ [build_ext]
36
+ inplace = 1
37
+
38
+ [egg_info]
39
+ tag_build =
40
+ tag_date = 0
41
+
@@ -0,0 +1,107 @@
1
+ import os, numpy as np, platform
2
+ from setuptools import setup, Extension
3
+ from Cython.Build import cythonize
4
+
5
+ # Package name
6
+ __package__ = "sqlcycli"
7
+
8
+
9
+ # Create Extension
10
+ def extension(filename: str, include_np: bool, *extra_compile_args: str) -> Extension:
11
+ # Extra arguments
12
+ extra_args = list(extra_compile_args) if extra_compile_args else None
13
+ # Name
14
+ name: str = "%s.%s" % (__package__, filename.split(".")[0])
15
+ source: str = os.path.join("src", __package__, filename)
16
+ # Create extension
17
+ if include_np:
18
+ return Extension(
19
+ name,
20
+ sources=[source],
21
+ extra_compile_args=extra_args,
22
+ include_dirs=[np.get_include()],
23
+ define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
24
+ )
25
+ else:
26
+ return Extension(name, sources=[source], extra_compile_args=extra_args)
27
+
28
+
29
+ # Create Constant Extension
30
+ def folder_extension(
31
+ folder: str,
32
+ filename: str,
33
+ include_np: bool,
34
+ *extra_compile_args: str,
35
+ ) -> Extension:
36
+ # Extra arguments
37
+ extra_args = list(extra_compile_args) if extra_compile_args else None
38
+ # Name
39
+ name: str = "%s.%s.%s" % (__package__, folder, filename.split(".")[0])
40
+ source: str = os.path.join("src", __package__, folder, filename)
41
+ # Create extension
42
+ if include_np:
43
+ return Extension(
44
+ name,
45
+ sources=[source],
46
+ extra_compile_args=extra_args,
47
+ include_dirs=[np.get_include()],
48
+ define_macros=[("NPY_NO_DEPRECATED_API", "NPY_1_7_API_VERSION")],
49
+ )
50
+ else:
51
+ return Extension(name, sources=[source], extra_compile_args=extra_args)
52
+
53
+
54
+ # Build Extensions
55
+ if platform.system() == "Windows":
56
+ extensions = [
57
+ # fmt: off
58
+ folder_extension("aio", "connection.py", True),
59
+ folder_extension("aio", "pool.py", True),
60
+ # fmt: on
61
+ folder_extension("constants", "_CLIENT.py", False),
62
+ folder_extension("constants", "_COMMAND.py", False),
63
+ folder_extension("constants", "_FIELD_TYPE.py", False),
64
+ folder_extension("constants", "_SERVER_STATUS.py", False),
65
+ extension("_auth.py", True),
66
+ extension("_connect.py", False),
67
+ extension("_optionfile.py", False),
68
+ extension("_ssl.py", False),
69
+ extension("charset.py", False),
70
+ extension("connection.py", True),
71
+ extension("errors.py", True),
72
+ extension("protocol.py", True),
73
+ extension("transcode.py", True),
74
+ extension("typeref.py", False),
75
+ extension("utils.py", True),
76
+ ]
77
+ else:
78
+ extensions = [
79
+ # fmt: off
80
+ folder_extension("aio", "connection.py", True, "-Wno-unreachable-code", "-Wno-incompatible-pointer-types"),
81
+ folder_extension("aio", "pool.py", True, "-Wno-unreachable-code", "-Wno-incompatible-pointer-types"),
82
+ # fmt: on
83
+ folder_extension("constants", "_CLIENT.py", False),
84
+ folder_extension("constants", "_COMMAND.py", False),
85
+ folder_extension("constants", "_FIELD_TYPE.py", False),
86
+ folder_extension("constants", "_SERVER_STATUS.py", False),
87
+ extension("_auth.py", True, "-Wno-unreachable-code"),
88
+ extension("_connect.py", False, "-Wno-unreachable-code"),
89
+ extension("_optionfile.py", False, "-Wno-unreachable-code"),
90
+ extension("_ssl.py", False, "-Wno-unreachable-code"),
91
+ extension("charset.py", False, "-Wno-unreachable-code"),
92
+ extension("connection.py", True, "-Wno-unreachable-code"),
93
+ extension("errors.py", True, "-Wno-unreachable-code"),
94
+ extension("protocol.py", True, "-Wno-unreachable-code"),
95
+ extension("transcode.py", True, "-Wno-unreachable-code"),
96
+ extension("typeref.py", False),
97
+ extension("utils.py", True, "-Wno-unreachable-code"),
98
+ ]
99
+
100
+ # Build
101
+ setup(
102
+ ext_modules=cythonize(
103
+ extensions,
104
+ compiler_directives={"language_level": "3"},
105
+ annotate=True,
106
+ ),
107
+ )
File without changes
@@ -0,0 +1,46 @@
1
+ from sqlcycli import constants, errors
2
+ from sqlcycli._auth import AuthPlugin
3
+ from sqlcycli._optionfile import OptionFile
4
+ from sqlcycli._ssl import SSL, SSL_ENABLED
5
+ from sqlcycli.charset import Charset, all_charsets
6
+ from sqlcycli.protocol import MysqlPacket, FieldDescriptorPacket
7
+ from sqlcycli.connection import (
8
+ Cursor,
9
+ DictCursor,
10
+ DfCursor,
11
+ SSCursor,
12
+ SSDictCursor,
13
+ SSDfCursor,
14
+ BaseConnection,
15
+ Connection,
16
+ )
17
+ from sqlcycli import aio
18
+ from sqlcycli.aio.pool import Pool, PoolConnection
19
+ from sqlcycli._connect import connect, create_pool
20
+
21
+
22
+ __all__ = [
23
+ "constants",
24
+ "errors",
25
+ "AuthPlugin",
26
+ "OptionFile",
27
+ "SSL",
28
+ "SSL_ENABLED",
29
+ "Charset",
30
+ "all_charsets",
31
+ "MysqlPacket",
32
+ "FieldDescriptorPacket",
33
+ "Cursor",
34
+ "DictCursor",
35
+ "DfCursor",
36
+ "SSCursor",
37
+ "SSDictCursor",
38
+ "SSDfCursor",
39
+ "BaseConnection",
40
+ "Connection",
41
+ "aio",
42
+ "Pool",
43
+ "PoolConnection",
44
+ "connect",
45
+ "create_pool",
46
+ ]