CyMySQL 1.1.1__tar.gz → 1.1.2__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.
- {cymysql-1.1.1 → cymysql-1.1.2}/CyMySQL.egg-info/PKG-INFO +2 -2
- {cymysql-1.1.1 → cymysql-1.1.2}/CyMySQL.egg-info/SOURCES.txt +1 -0
- cymysql-1.1.2/MANIFEST.in +3 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/PKG-INFO +2 -2
- {cymysql-1.1.1 → cymysql-1.1.2}/README.rst +1 -1
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/__init__.py +8 -5
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/__version__.py +1 -1
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/aio/__init__.py +10 -1
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/aio/connections.py +54 -47
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/aio/context.py +28 -26
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/aio/cursors.py +23 -19
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/aio/pool.py +33 -31
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/charset.pxd +2 -2
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/charset.py +9 -7
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/connections.py +82 -75
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/converters.py +33 -30
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/cursors.py +41 -35
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/err.py +7 -4
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/packet.py +2 -2
- cymysql-1.1.2/cymysql/py.typed +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/result.py +1 -1
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/times.py +5 -4
- {cymysql-1.1.1 → cymysql-1.1.2}/pyproject.toml +4 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/setup.py +7 -3
- cymysql-1.1.1/MANIFEST.in +0 -3
- {cymysql-1.1.1 → cymysql-1.1.2}/CyMySQL.egg-info/dependency_links.txt +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/CyMySQL.egg-info/requires.txt +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/CyMySQL.egg-info/top_level.txt +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/LICENSE +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/aio/result.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/aio/socketwrapper.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/constants/CLIENT.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/constants/COMMAND.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/constants/CR.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/constants/ER.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/constants/FIELD_TYPE.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/constants/FLAG.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/constants/SERVER_STATUS.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/constants/__init__.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/packet.pyx +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/result.pyx +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/socketwrapper.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/socketwrapper.pyx +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/tests/__init__.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/tests/base.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/tests/test_DictCursor.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/tests/test_async.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/tests/test_basic.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/tests/test_example.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/cymysql/tests/test_issues.py +0 -0
- {cymysql-1.1.1 → cymysql-1.1.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: CyMySQL
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: Python MySQL Driver using Cython
|
|
5
5
|
Author-email: Yutaka Matsubara <yutaka.matsubara@gmail.com>
|
|
6
6
|
Maintainer-email: Hajime Nakagami <nakagami@gmail.com>
|
|
@@ -57,7 +57,7 @@ Or without cythonize
|
|
|
57
57
|
|
|
58
58
|
::
|
|
59
59
|
|
|
60
|
-
$ NO_CYTHON=1 pip
|
|
60
|
+
$ NO_CYTHON=1 pip install cymysql
|
|
61
61
|
|
|
62
62
|
Example
|
|
63
63
|
---------------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: CyMySQL
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.2
|
|
4
4
|
Summary: Python MySQL Driver using Cython
|
|
5
5
|
Author-email: Yutaka Matsubara <yutaka.matsubara@gmail.com>
|
|
6
6
|
Maintainer-email: Hajime Nakagami <nakagami@gmail.com>
|
|
@@ -57,7 +57,7 @@ Or without cythonize
|
|
|
57
57
|
|
|
58
58
|
::
|
|
59
59
|
|
|
60
|
-
$ NO_CYTHON=1 pip
|
|
60
|
+
$ NO_CYTHON=1 pip install cymysql
|
|
61
61
|
|
|
62
62
|
Example
|
|
63
63
|
---------------
|
|
@@ -22,6 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
22
22
|
THE SOFTWARE.
|
|
23
23
|
|
|
24
24
|
'''
|
|
25
|
+
from typing import Any
|
|
26
|
+
|
|
25
27
|
from cymysql import converters
|
|
26
28
|
from cymysql.converters import escape_dict, escape_sequence, escape_string
|
|
27
29
|
from cymysql.err import (
|
|
@@ -45,19 +47,19 @@ paramstyle = "format"
|
|
|
45
47
|
|
|
46
48
|
class DBAPISet(frozenset):
|
|
47
49
|
|
|
48
|
-
def __ne__(self, other):
|
|
50
|
+
def __ne__(self, other: Any) -> bool:
|
|
49
51
|
if isinstance(other, set):
|
|
50
52
|
return super(DBAPISet, self).__ne__(self, other)
|
|
51
53
|
else:
|
|
52
54
|
return other not in self
|
|
53
55
|
|
|
54
|
-
def __eq__(self, other):
|
|
56
|
+
def __eq__(self, other: Any) -> bool:
|
|
55
57
|
if isinstance(other, frozenset):
|
|
56
58
|
return frozenset.__eq__(self, other)
|
|
57
59
|
else:
|
|
58
60
|
return other in self
|
|
59
61
|
|
|
60
|
-
def __hash__(self):
|
|
62
|
+
def __hash__(self) -> int:
|
|
61
63
|
return frozenset.__hash__(self)
|
|
62
64
|
|
|
63
65
|
|
|
@@ -76,18 +78,19 @@ DATETIME = TIMESTAMP
|
|
|
76
78
|
ROWID = DBAPISet()
|
|
77
79
|
|
|
78
80
|
|
|
79
|
-
def Binary(x):
|
|
81
|
+
def Binary(x: Any) -> bytes:
|
|
80
82
|
"""Return x as a binary type."""
|
|
81
83
|
return bytes(x)
|
|
82
84
|
|
|
83
85
|
|
|
84
|
-
def connect(*args, **kwargs):
|
|
86
|
+
def connect(*args: Any, **kwargs: Any) -> Connection:
|
|
85
87
|
conn = Connection(*args, **kwargs)
|
|
86
88
|
conn._connect()
|
|
87
89
|
conn._initialize()
|
|
88
90
|
return conn
|
|
89
91
|
|
|
90
92
|
|
|
93
|
+
|
|
91
94
|
NULL = "NULL"
|
|
92
95
|
|
|
93
96
|
__all__ = [
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
VERSION = (1, 1,
|
|
1
|
+
VERSION = (1, 1, 2)
|
|
2
2
|
__version__ = '%s.%s.%s' % VERSION
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
from .connections import AsyncConnection, connect
|
|
2
|
-
from .pool import create_pool
|
|
3
2
|
from .cursors import AsyncCursor, AsyncDictCursor
|
|
3
|
+
from .pool import create_pool
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
'AsyncConnection',
|
|
7
|
+
'connect',
|
|
8
|
+
'create_pool',
|
|
9
|
+
'AsyncCursor',
|
|
10
|
+
'AsyncDictCursor',
|
|
11
|
+
]
|
|
12
|
+
|
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
import ssl
|
|
3
1
|
import asyncio
|
|
2
|
+
import ssl
|
|
4
3
|
import struct
|
|
4
|
+
import sys
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
|
+
|
|
7
|
+
from ..charset import charset_by_name
|
|
5
8
|
from ..connections import (
|
|
6
9
|
Connection,
|
|
10
|
+
_xor,
|
|
7
11
|
byte2int,
|
|
8
|
-
|
|
12
|
+
int2bytes,
|
|
9
13
|
pack_int24,
|
|
10
|
-
_xor,
|
|
11
14
|
)
|
|
12
|
-
from
|
|
13
|
-
from ..
|
|
15
|
+
from ..constants import CLIENT, COMMAND
|
|
16
|
+
from ..err import InterfaceError
|
|
14
17
|
from ..packet import MysqlPacket
|
|
18
|
+
from .cursors import AsyncCursor
|
|
15
19
|
from .result import AsyncMySQLResult
|
|
16
20
|
from .socketwrapper import AsyncSocketWrapper
|
|
17
|
-
|
|
18
|
-
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from .cursors import AsyncCursor
|
|
19
24
|
|
|
20
25
|
|
|
21
26
|
class AsyncConnection(Connection):
|
|
22
|
-
def __init__(self, *args, **kwargs):
|
|
27
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
23
28
|
if kwargs.get("loop"):
|
|
24
29
|
self.loop = kwargs.get("loop")
|
|
25
30
|
del kwargs["loop"]
|
|
@@ -28,10 +33,10 @@ class AsyncConnection(Connection):
|
|
|
28
33
|
super().__init__(*args, **kwargs)
|
|
29
34
|
self.last_usage = self.loop.time()
|
|
30
35
|
|
|
31
|
-
def _connect(self):
|
|
36
|
+
def _connect(self) -> None:
|
|
32
37
|
self.socket = AsyncSocketWrapper(self._get_socket(), self.compress)
|
|
33
38
|
|
|
34
|
-
async def _initialize(self):
|
|
39
|
+
async def _initialize(self) -> None:
|
|
35
40
|
self.socket.setblocking(False)
|
|
36
41
|
await self._get_server_information()
|
|
37
42
|
await self._request_authentication()
|
|
@@ -49,16 +54,16 @@ class AsyncConnection(Connection):
|
|
|
49
54
|
|
|
50
55
|
self.commit()
|
|
51
56
|
|
|
52
|
-
async def close(self):
|
|
57
|
+
async def close(self) -> None:
|
|
53
58
|
''' Send the quit message and close the socket '''
|
|
54
59
|
if self.socket is None:
|
|
55
60
|
return
|
|
56
|
-
send_data = b'\x01\x00\x00\x00' +
|
|
61
|
+
send_data = b'\x01\x00\x00\x00' + int2bytes(COMMAND.COM_QUIT)
|
|
57
62
|
await self.socket.send_packet(send_data, self.loop)
|
|
58
63
|
self.socket.close()
|
|
59
64
|
self.socket = None
|
|
60
65
|
|
|
61
|
-
async def autocommit(self, value):
|
|
66
|
+
async def autocommit(self, value: bool) -> None:
|
|
62
67
|
''' Set whether or not to commit after every execute() '''
|
|
63
68
|
if value:
|
|
64
69
|
q = "SET AUTOCOMMIT = 1"
|
|
@@ -71,7 +76,7 @@ class AsyncConnection(Connection):
|
|
|
71
76
|
exc, value, tb = sys.exc_info()
|
|
72
77
|
self.errorhandler(None, exc, value)
|
|
73
78
|
|
|
74
|
-
async def commit(self):
|
|
79
|
+
async def commit(self) -> None:
|
|
75
80
|
''' Commit changes to stable storage '''
|
|
76
81
|
try:
|
|
77
82
|
await self._execute_command(COMMAND.COM_QUERY, "COMMIT")
|
|
@@ -80,7 +85,7 @@ class AsyncConnection(Connection):
|
|
|
80
85
|
exc, value, tb = sys.exc_info()
|
|
81
86
|
self.errorhandler(None, exc, value)
|
|
82
87
|
|
|
83
|
-
async def rollback(self):
|
|
88
|
+
async def rollback(self) -> None:
|
|
84
89
|
''' Roll back the current transaction '''
|
|
85
90
|
try:
|
|
86
91
|
await self._execute_command(COMMAND.COM_QUERY, "ROLLBACK")
|
|
@@ -89,7 +94,7 @@ class AsyncConnection(Connection):
|
|
|
89
94
|
exc, value, tb = sys.exc_info()
|
|
90
95
|
self.errorhandler(None, exc, value)
|
|
91
96
|
|
|
92
|
-
def cursor(self, cursor=None):
|
|
97
|
+
def cursor(self, cursor: type[AsyncCursor] | None = None) -> AsyncCursor:
|
|
93
98
|
self.last_usage = self.loop.time()
|
|
94
99
|
if cursor is None:
|
|
95
100
|
cursor = self.cursorclass
|
|
@@ -97,30 +102,30 @@ class AsyncConnection(Connection):
|
|
|
97
102
|
cursor = AsyncCursor
|
|
98
103
|
return cursor(self)
|
|
99
104
|
|
|
100
|
-
async def __aenter__(self):
|
|
105
|
+
async def __aenter__(self) -> 'AsyncConnection':
|
|
101
106
|
return self
|
|
102
107
|
|
|
103
|
-
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
108
|
+
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
104
109
|
if self.socket is not None:
|
|
105
110
|
await self.close()
|
|
106
111
|
|
|
107
112
|
# The following methods are INTERNAL USE ONLY (called from Cursor)
|
|
108
|
-
async def query(self, sql):
|
|
113
|
+
async def query(self, sql: str | bytes) -> None:
|
|
109
114
|
await self._execute_command(COMMAND.COM_QUERY, sql)
|
|
110
115
|
self._result = AsyncMySQLResult(self)
|
|
111
116
|
await self._result.read_result()
|
|
112
117
|
|
|
113
|
-
async def next_result(self):
|
|
118
|
+
async def next_result(self) -> None:
|
|
114
119
|
self._result = AsyncMySQLResult(self)
|
|
115
120
|
await self._result.read_result()
|
|
116
121
|
|
|
117
|
-
def affected_rows(self):
|
|
122
|
+
def affected_rows(self) -> int:
|
|
118
123
|
if self._result:
|
|
119
|
-
self._result._affected_rows
|
|
124
|
+
return self._result._affected_rows
|
|
120
125
|
else:
|
|
121
126
|
return 0
|
|
122
127
|
|
|
123
|
-
async def kill(self, thread_id):
|
|
128
|
+
async def kill(self, thread_id: int) -> bool:
|
|
124
129
|
arg = struct.pack('<I', thread_id)
|
|
125
130
|
try:
|
|
126
131
|
await self._execute_command(COMMAND.COM_PROCESS_KILL, arg)
|
|
@@ -131,7 +136,7 @@ class AsyncConnection(Connection):
|
|
|
131
136
|
self.errorhandler(None, exc, value)
|
|
132
137
|
return False
|
|
133
138
|
|
|
134
|
-
async def ping(self, reconnect=True):
|
|
139
|
+
async def ping(self, reconnect: bool = True) -> bool | None:
|
|
135
140
|
''' Check if the server is alive '''
|
|
136
141
|
try:
|
|
137
142
|
await self._execute_command(COMMAND.COM_PING, "")
|
|
@@ -147,7 +152,7 @@ class AsyncConnection(Connection):
|
|
|
147
152
|
pkt = await self.read_packet()
|
|
148
153
|
return pkt.is_ok_packet()
|
|
149
154
|
|
|
150
|
-
async def set_charset(self, charset):
|
|
155
|
+
async def set_charset(self, charset: str) -> None:
|
|
151
156
|
try:
|
|
152
157
|
if charset:
|
|
153
158
|
await self._execute_command(COMMAND.COM_QUERY, "SET NAMES %s" %
|
|
@@ -158,12 +163,12 @@ class AsyncConnection(Connection):
|
|
|
158
163
|
exc, value, tb = sys.exc_info()
|
|
159
164
|
self.errorhandler(None, exc, value)
|
|
160
165
|
|
|
161
|
-
async def read_packet(self):
|
|
166
|
+
async def read_packet(self) -> MysqlPacket:
|
|
162
167
|
"""Read an entire "mysql packet" in its entirety from the network
|
|
163
168
|
and return a MysqlPacket type that represents the results."""
|
|
164
169
|
return MysqlPacket(await self.socket.recv_packet(self.loop), self.charset, self.encoding)
|
|
165
170
|
|
|
166
|
-
async def _request_authentication(self):
|
|
171
|
+
async def _request_authentication(self) -> None:
|
|
167
172
|
if self.user is None:
|
|
168
173
|
raise ValueError("Did not specify a username")
|
|
169
174
|
|
|
@@ -175,32 +180,32 @@ class AsyncConnection(Connection):
|
|
|
175
180
|
data_init = (
|
|
176
181
|
struct.pack('<i', self.client_flag) +
|
|
177
182
|
struct.pack("<I", 1) +
|
|
178
|
-
|
|
183
|
+
int2bytes(charset_id) + int2bytes(0)*23
|
|
179
184
|
)
|
|
180
185
|
|
|
181
186
|
if self.ssl and self.server_capabilities & CLIENT.SSL:
|
|
182
|
-
data = pack_int24(len(data_init)) +
|
|
187
|
+
data = pack_int24(len(data_init)) + int2bytes(next_packet) + data_init
|
|
183
188
|
await self.socket.send_uncompress_packet(data, self.loop)
|
|
184
189
|
next_packet += 1
|
|
185
190
|
self.socket = ssl.wrap_socket(self.socket, keyfile=self.key,
|
|
186
191
|
certfile=self.cert,
|
|
187
192
|
ca_certs=self.ca)
|
|
188
193
|
|
|
189
|
-
data = data_init + user +
|
|
194
|
+
data = data_init + user + int2bytes(0)
|
|
190
195
|
authresp = self._scramble()
|
|
191
196
|
|
|
192
197
|
if self.server_capabilities & CLIENT.SECURE_CONNECTION:
|
|
193
|
-
data +=
|
|
198
|
+
data += int2bytes(len(authresp)) + authresp
|
|
194
199
|
else:
|
|
195
|
-
data += authresp +
|
|
200
|
+
data += authresp + int2bytes(0)
|
|
196
201
|
|
|
197
202
|
if self.db and self.server_capabilities & CLIENT.CONNECT_WITH_DB:
|
|
198
|
-
data += self.db.encode(self.encoding) +
|
|
203
|
+
data += self.db.encode(self.encoding) + int2bytes(0)
|
|
199
204
|
|
|
200
205
|
if self.server_capabilities & CLIENT.PLUGIN_AUTH:
|
|
201
|
-
data += self.auth_plugin_name.encode(self.encoding) +
|
|
206
|
+
data += self.auth_plugin_name.encode(self.encoding) + int2bytes(0)
|
|
202
207
|
|
|
203
|
-
data = pack_int24(len(data)) +
|
|
208
|
+
data = pack_int24(len(data)) + int2bytes(next_packet) + data
|
|
204
209
|
next_packet += 2
|
|
205
210
|
|
|
206
211
|
await self.socket.send_uncompress_packet(data, self.loop)
|
|
@@ -214,7 +219,7 @@ class AsyncConnection(Connection):
|
|
|
214
219
|
j = auth_packet.find(b'\0', i + 1)
|
|
215
220
|
self.salt = auth_packet[i + 1:j]
|
|
216
221
|
data = self._scramble()
|
|
217
|
-
data = pack_int24(len(data)) +
|
|
222
|
+
data = pack_int24(len(data)) + int2bytes(next_packet) + data
|
|
218
223
|
next_packet += 2
|
|
219
224
|
await self.socket.send_uncompress_packet(data, self.loop)
|
|
220
225
|
auth_packet = await self.socket.recv_uncompress_packet(self.loop)
|
|
@@ -222,18 +227,19 @@ class AsyncConnection(Connection):
|
|
|
222
227
|
if self.auth_plugin_name == 'caching_sha2_password':
|
|
223
228
|
await self._caching_sha2_authentication2(auth_packet, next_packet)
|
|
224
229
|
|
|
225
|
-
async def _execute_command(self, command, sql):
|
|
230
|
+
async def _execute_command(self, command: int, sql: str | bytes) -> None:
|
|
226
231
|
if not self.socket:
|
|
227
232
|
self.errorhandler(None, InterfaceError, (-1, 'socket not found'))
|
|
228
233
|
|
|
229
|
-
sql
|
|
234
|
+
if isinstance(sql, str):
|
|
235
|
+
sql = sql.encode(self.encoding)
|
|
230
236
|
|
|
231
237
|
if len(sql) + 1 > 0xffffff:
|
|
232
238
|
raise ValueError('Sending query packet is too large')
|
|
233
|
-
prelude = struct.pack('<i', len(sql)+1) +
|
|
239
|
+
prelude = struct.pack('<i', len(sql)+1) + int2bytes(command)
|
|
234
240
|
await self.socket.send_packet(prelude + sql, self.loop)
|
|
235
241
|
|
|
236
|
-
async def _caching_sha2_authentication2(self, auth_packet, next_packet):
|
|
242
|
+
async def _caching_sha2_authentication2(self, auth_packet: bytes, next_packet: int) -> None:
|
|
237
243
|
# https://dev.mysql.com/doc/dev/mysql-server/latest/page_caching_sha2_authentication_exchanges.html
|
|
238
244
|
if auth_packet == b'\x01\x03': # fast_auth_success
|
|
239
245
|
await self.read_packet()
|
|
@@ -247,7 +253,7 @@ class AsyncConnection(Connection):
|
|
|
247
253
|
else:
|
|
248
254
|
# request_public_key
|
|
249
255
|
data = b'\x02'
|
|
250
|
-
data = pack_int24(len(data)) +
|
|
256
|
+
data = pack_int24(len(data)) + int2bytes(next_packet) + data
|
|
251
257
|
next_packet += 2
|
|
252
258
|
await self.socket.send_uncompress_packet(data, self.loop)
|
|
253
259
|
response = await self.read_packet()
|
|
@@ -260,20 +266,20 @@ class AsyncConnection(Connection):
|
|
|
260
266
|
password = self.password.encode(self.encoding) + b'\x00'
|
|
261
267
|
data = cipher.encrypt(_xor(password, self.salt))
|
|
262
268
|
|
|
263
|
-
data = pack_int24(len(data)) +
|
|
269
|
+
data = pack_int24(len(data)) + int2bytes(next_packet) + data
|
|
264
270
|
next_packet += 2
|
|
265
271
|
await self.socket.send_packet(data, self.loop)
|
|
266
272
|
|
|
267
273
|
await self.read_packet()
|
|
268
274
|
|
|
269
|
-
async def _get_server_information(self):
|
|
275
|
+
async def _get_server_information(self) -> None:
|
|
270
276
|
# https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
|
|
271
277
|
i = 0
|
|
272
278
|
data = await self.socket.recv_uncompress_packet(self.loop)
|
|
273
279
|
|
|
274
280
|
self.protocol_version = byte2int(data[i:i+1])
|
|
275
281
|
i += 1
|
|
276
|
-
str_end = data.find(
|
|
282
|
+
str_end = data.find(int2bytes(0), i)
|
|
277
283
|
self.server_version = data[i:str_end].decode('utf-8')
|
|
278
284
|
i = str_end + 1
|
|
279
285
|
self.server_thread_id = struct.unpack('<I', data[i:i+4])
|
|
@@ -304,11 +310,12 @@ class AsyncConnection(Connection):
|
|
|
304
310
|
rest_salt_len = max(13, salt_len-8)
|
|
305
311
|
self.salt += data[i:i+rest_salt_len-1]
|
|
306
312
|
i += rest_salt_len
|
|
307
|
-
self.auth_plugin_name = data[i:data.find(
|
|
313
|
+
self.auth_plugin_name = data[i:data.find(int2bytes(0), i)].decode('utf-8')
|
|
308
314
|
|
|
309
315
|
|
|
310
|
-
async def connect(*args, **kwargs):
|
|
316
|
+
async def connect(*args: Any, **kwargs: Any) -> AsyncConnection:
|
|
311
317
|
conn = AsyncConnection(*args, **kwargs)
|
|
312
318
|
conn._connect()
|
|
313
319
|
await conn._initialize()
|
|
314
320
|
return conn
|
|
321
|
+
|
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
# https://github.com/aio-libs/aiomysql/blob/master/aiomysql/utils.py
|
|
3
3
|
|
|
4
4
|
from collections.abc import Coroutine
|
|
5
|
+
from typing import Any
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
class _ContextManager(Coroutine):
|
|
8
9
|
|
|
9
10
|
__slots__ = ('_coro', '_obj')
|
|
10
11
|
|
|
11
|
-
def __init__(self, coro):
|
|
12
|
+
def __init__(self, coro: Any) -> None:
|
|
12
13
|
self._coro = coro
|
|
13
|
-
self._obj = None
|
|
14
|
+
self._obj: Any = None
|
|
14
15
|
|
|
15
|
-
def send(self, value):
|
|
16
|
+
def send(self, value: Any) -> Any:
|
|
16
17
|
return self._coro.send(value)
|
|
17
18
|
|
|
18
|
-
def throw(self, typ, val=None, tb=None):
|
|
19
|
+
def throw(self, typ: Any, val: Any = None, tb: Any = None) -> Any:
|
|
19
20
|
if val is None:
|
|
20
21
|
return self._coro.throw(typ)
|
|
21
22
|
elif tb is None:
|
|
@@ -23,41 +24,41 @@ class _ContextManager(Coroutine):
|
|
|
23
24
|
else:
|
|
24
25
|
return self._coro.throw(typ, val, tb)
|
|
25
26
|
|
|
26
|
-
def close(self):
|
|
27
|
+
def close(self) -> None:
|
|
27
28
|
return self._coro.close()
|
|
28
29
|
|
|
29
30
|
@property
|
|
30
|
-
def gi_frame(self):
|
|
31
|
+
def gi_frame(self) -> Any:
|
|
31
32
|
return self._coro.gi_frame
|
|
32
33
|
|
|
33
34
|
@property
|
|
34
|
-
def gi_running(self):
|
|
35
|
+
def gi_running(self) -> Any:
|
|
35
36
|
return self._coro.gi_running
|
|
36
37
|
|
|
37
38
|
@property
|
|
38
|
-
def gi_code(self):
|
|
39
|
+
def gi_code(self) -> Any:
|
|
39
40
|
return self._coro.gi_code
|
|
40
41
|
|
|
41
|
-
def __next__(self):
|
|
42
|
+
def __next__(self) -> Any:
|
|
42
43
|
return self.send(None)
|
|
43
44
|
|
|
44
|
-
def __iter__(self):
|
|
45
|
+
def __iter__(self) -> Any:
|
|
45
46
|
return self._coro.__await__()
|
|
46
47
|
|
|
47
|
-
def __await__(self):
|
|
48
|
+
def __await__(self) -> Any:
|
|
48
49
|
return self._coro.__await__()
|
|
49
50
|
|
|
50
|
-
async def __aenter__(self):
|
|
51
|
+
async def __aenter__(self) -> Any:
|
|
51
52
|
self._obj = await self._coro
|
|
52
53
|
return self._obj
|
|
53
54
|
|
|
54
|
-
async def __aexit__(self, exc_type, exc, tb):
|
|
55
|
+
async def __aexit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
|
|
55
56
|
await self._obj.close()
|
|
56
57
|
self._obj = None
|
|
57
58
|
|
|
58
59
|
|
|
59
60
|
class _PoolContextManager(_ContextManager):
|
|
60
|
-
async def __aexit__(self, exc_type, exc, tb):
|
|
61
|
+
async def __aexit__(self, exc_type: Any, exc: Any, tb: Any) -> None:
|
|
61
62
|
self._obj.close()
|
|
62
63
|
await self._obj.wait_closed()
|
|
63
64
|
self._obj = None
|
|
@@ -67,16 +68,16 @@ class _PoolAcquireContextManager(_ContextManager):
|
|
|
67
68
|
|
|
68
69
|
__slots__ = ('_coro', '_conn', '_pool')
|
|
69
70
|
|
|
70
|
-
def __init__(self, coro, pool):
|
|
71
|
+
def __init__(self, coro: Any, pool: Any) -> None:
|
|
71
72
|
self._coro = coro
|
|
72
|
-
self._conn = None
|
|
73
|
-
self._pool = pool
|
|
73
|
+
self._conn: Any = None
|
|
74
|
+
self._pool: Any = pool
|
|
74
75
|
|
|
75
|
-
async def __aenter__(self):
|
|
76
|
+
async def __aenter__(self) -> Any:
|
|
76
77
|
self._conn = await self._coro
|
|
77
78
|
return self._conn
|
|
78
79
|
|
|
79
|
-
async def __aexit__(self, exc_type, exc, tb):
|
|
80
|
+
async def __aexit__(self, exc_type: Any, exc, tb) -> None:
|
|
80
81
|
try:
|
|
81
82
|
await self._pool.release(self._conn)
|
|
82
83
|
finally:
|
|
@@ -101,29 +102,30 @@ class _PoolConnectionContextManager:
|
|
|
101
102
|
|
|
102
103
|
__slots__ = ('_pool', '_conn')
|
|
103
104
|
|
|
104
|
-
def __init__(self, pool, conn):
|
|
105
|
-
self._pool = pool
|
|
106
|
-
self._conn = conn
|
|
105
|
+
def __init__(self, pool: Any, conn: Any) -> None:
|
|
106
|
+
self._pool: Any = pool
|
|
107
|
+
self._conn: Any = conn
|
|
107
108
|
|
|
108
|
-
def __enter__(self):
|
|
109
|
+
def __enter__(self) -> Any:
|
|
109
110
|
assert self._conn
|
|
110
111
|
return self._conn
|
|
111
112
|
|
|
112
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
113
|
+
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
113
114
|
try:
|
|
114
115
|
self._pool.release(self._conn)
|
|
115
116
|
finally:
|
|
116
117
|
self._pool = None
|
|
117
118
|
self._conn = None
|
|
118
119
|
|
|
119
|
-
async def __aenter__(self):
|
|
120
|
+
async def __aenter__(self) -> Any:
|
|
120
121
|
assert not self._conn
|
|
121
122
|
self._conn = await self._pool.acquire()
|
|
122
123
|
return self._conn
|
|
123
124
|
|
|
124
|
-
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
125
|
+
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
125
126
|
try:
|
|
126
127
|
await self._pool.release(self._conn)
|
|
127
128
|
finally:
|
|
128
129
|
self._pool = None
|
|
129
130
|
self._conn = None
|
|
131
|
+
|