Ausgabe der neuen DB Einträge
This commit is contained in:
parent
bad48e1627
commit
cfbbb9ee3d
2399 changed files with 843193 additions and 43 deletions
141
venv/lib/python3.9/site-packages/pymysql/__init__.py
Normal file
141
venv/lib/python3.9/site-packages/pymysql/__init__.py
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
"""
|
||||
PyMySQL: A pure-Python MySQL client library.
|
||||
|
||||
Copyright (c) 2010-2016 PyMySQL contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
import sys
|
||||
|
||||
from ._compat import PY2
|
||||
from .constants import FIELD_TYPE
|
||||
from .converters import escape_dict, escape_sequence, escape_string
|
||||
from .err import (
|
||||
Warning, Error, InterfaceError, DataError,
|
||||
DatabaseError, OperationalError, IntegrityError, InternalError,
|
||||
NotSupportedError, ProgrammingError, MySQLError)
|
||||
from .times import (
|
||||
Date, Time, Timestamp,
|
||||
DateFromTicks, TimeFromTicks, TimestampFromTicks)
|
||||
|
||||
|
||||
VERSION = (0, 10, 1, None)
|
||||
if VERSION[3] is not None:
|
||||
VERSION_STRING = "%d.%d.%d_%s" % VERSION
|
||||
else:
|
||||
VERSION_STRING = "%d.%d.%d" % VERSION[:3]
|
||||
threadsafety = 1
|
||||
apilevel = "2.0"
|
||||
paramstyle = "pyformat"
|
||||
|
||||
|
||||
class DBAPISet(frozenset):
|
||||
|
||||
def __ne__(self, other):
|
||||
if isinstance(other, set):
|
||||
return frozenset.__ne__(self, other)
|
||||
else:
|
||||
return other not in self
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, frozenset):
|
||||
return frozenset.__eq__(self, other)
|
||||
else:
|
||||
return other in self
|
||||
|
||||
def __hash__(self):
|
||||
return frozenset.__hash__(self)
|
||||
|
||||
|
||||
STRING = DBAPISet([FIELD_TYPE.ENUM, FIELD_TYPE.STRING,
|
||||
FIELD_TYPE.VAR_STRING])
|
||||
BINARY = DBAPISet([FIELD_TYPE.BLOB, FIELD_TYPE.LONG_BLOB,
|
||||
FIELD_TYPE.MEDIUM_BLOB, FIELD_TYPE.TINY_BLOB])
|
||||
NUMBER = DBAPISet([FIELD_TYPE.DECIMAL, FIELD_TYPE.DOUBLE, FIELD_TYPE.FLOAT,
|
||||
FIELD_TYPE.INT24, FIELD_TYPE.LONG, FIELD_TYPE.LONGLONG,
|
||||
FIELD_TYPE.TINY, FIELD_TYPE.YEAR])
|
||||
DATE = DBAPISet([FIELD_TYPE.DATE, FIELD_TYPE.NEWDATE])
|
||||
TIME = DBAPISet([FIELD_TYPE.TIME])
|
||||
TIMESTAMP = DBAPISet([FIELD_TYPE.TIMESTAMP, FIELD_TYPE.DATETIME])
|
||||
DATETIME = TIMESTAMP
|
||||
ROWID = DBAPISet()
|
||||
|
||||
|
||||
def Binary(x):
|
||||
"""Return x as a binary type."""
|
||||
if PY2:
|
||||
return bytearray(x)
|
||||
else:
|
||||
return bytes(x)
|
||||
|
||||
|
||||
def Connect(*args, **kwargs):
|
||||
"""
|
||||
Connect to the database; see connections.Connection.__init__() for
|
||||
more information.
|
||||
"""
|
||||
from .connections import Connection
|
||||
return Connection(*args, **kwargs)
|
||||
|
||||
from . import connections as _orig_conn
|
||||
if _orig_conn.Connection.__init__.__doc__ is not None:
|
||||
Connect.__doc__ = _orig_conn.Connection.__init__.__doc__
|
||||
del _orig_conn
|
||||
|
||||
|
||||
def get_client_info(): # for MySQLdb compatibility
|
||||
version = VERSION
|
||||
if VERSION[3] is None:
|
||||
version = VERSION[:3]
|
||||
return '.'.join(map(str, version))
|
||||
|
||||
connect = Connection = Connect
|
||||
|
||||
# we include a doctored version_info here for MySQLdb compatibility
|
||||
version_info = (1, 3, 13, "final", 0)
|
||||
|
||||
NULL = "NULL"
|
||||
|
||||
__version__ = get_client_info()
|
||||
|
||||
def thread_safe():
|
||||
return True # match MySQLdb.thread_safe()
|
||||
|
||||
def install_as_MySQLdb():
|
||||
"""
|
||||
After this function is called, any application that imports MySQLdb or
|
||||
_mysql will unwittingly actually use pymysql.
|
||||
"""
|
||||
sys.modules["MySQLdb"] = sys.modules["_mysql"] = sys.modules["pymysql"]
|
||||
|
||||
|
||||
__all__ = [
|
||||
'BINARY', 'Binary', 'Connect', 'Connection', 'DATE', 'Date',
|
||||
'Time', 'Timestamp', 'DateFromTicks', 'TimeFromTicks', 'TimestampFromTicks',
|
||||
'DataError', 'DatabaseError', 'Error', 'FIELD_TYPE', 'IntegrityError',
|
||||
'InterfaceError', 'InternalError', 'MySQLError', 'NULL', 'NUMBER',
|
||||
'NotSupportedError', 'DBAPISet', 'OperationalError', 'ProgrammingError',
|
||||
'ROWID', 'STRING', 'TIME', 'TIMESTAMP', 'Warning', 'apilevel', 'connect',
|
||||
'connections', 'constants', 'converters', 'cursors',
|
||||
'escape_dict', 'escape_sequence', 'escape_string', 'get_client_info',
|
||||
'paramstyle', 'threadsafety', 'version_info',
|
||||
|
||||
"install_as_MySQLdb",
|
||||
"NULL", "__version__",
|
||||
]
|
||||
327
venv/lib/python3.9/site-packages/pymysql/_auth.py
Normal file
327
venv/lib/python3.9/site-packages/pymysql/_auth.py
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
"""
|
||||
Implements auth methods
|
||||
"""
|
||||
from ._compat import PY2
|
||||
from .err import OperationalError
|
||||
from .util import byte2int, int2byte
|
||||
|
||||
|
||||
try:
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization, hashes
|
||||
from cryptography.hazmat.primitives.asymmetric import padding
|
||||
_have_cryptography = True
|
||||
except ImportError:
|
||||
_have_cryptography = False
|
||||
|
||||
from functools import partial
|
||||
import hashlib
|
||||
import io
|
||||
import struct
|
||||
import warnings
|
||||
|
||||
|
||||
DEBUG = False
|
||||
SCRAMBLE_LENGTH = 20
|
||||
sha1_new = partial(hashlib.new, 'sha1')
|
||||
|
||||
|
||||
# mysql_native_password
|
||||
# https://dev.mysql.com/doc/internals/en/secure-password-authentication.html#packet-Authentication::Native41
|
||||
|
||||
|
||||
def scramble_native_password(password, message):
|
||||
"""Scramble used for mysql_native_password"""
|
||||
if not password:
|
||||
return b''
|
||||
|
||||
stage1 = sha1_new(password).digest()
|
||||
stage2 = sha1_new(stage1).digest()
|
||||
s = sha1_new()
|
||||
s.update(message[:SCRAMBLE_LENGTH])
|
||||
s.update(stage2)
|
||||
result = s.digest()
|
||||
return _my_crypt(result, stage1)
|
||||
|
||||
|
||||
def _my_crypt(message1, message2):
|
||||
result = bytearray(message1)
|
||||
if PY2:
|
||||
message2 = bytearray(message2)
|
||||
|
||||
for i in range(len(result)):
|
||||
result[i] ^= message2[i]
|
||||
|
||||
return bytes(result)
|
||||
|
||||
|
||||
# old_passwords support ported from libmysql/password.c
|
||||
# https://dev.mysql.com/doc/internals/en/old-password-authentication.html
|
||||
|
||||
SCRAMBLE_LENGTH_323 = 8
|
||||
|
||||
|
||||
class RandStruct_323(object):
|
||||
|
||||
def __init__(self, seed1, seed2):
|
||||
self.max_value = 0x3FFFFFFF
|
||||
self.seed1 = seed1 % self.max_value
|
||||
self.seed2 = seed2 % self.max_value
|
||||
|
||||
def my_rnd(self):
|
||||
self.seed1 = (self.seed1 * 3 + self.seed2) % self.max_value
|
||||
self.seed2 = (self.seed1 + self.seed2 + 33) % self.max_value
|
||||
return float(self.seed1) / float(self.max_value)
|
||||
|
||||
|
||||
def scramble_old_password(password, message):
|
||||
"""Scramble for old_password"""
|
||||
warnings.warn("old password (for MySQL <4.1) is used. Upgrade your password with newer auth method.\n"
|
||||
"old password support will be removed in future PyMySQL version")
|
||||
hash_pass = _hash_password_323(password)
|
||||
hash_message = _hash_password_323(message[:SCRAMBLE_LENGTH_323])
|
||||
hash_pass_n = struct.unpack(">LL", hash_pass)
|
||||
hash_message_n = struct.unpack(">LL", hash_message)
|
||||
|
||||
rand_st = RandStruct_323(
|
||||
hash_pass_n[0] ^ hash_message_n[0], hash_pass_n[1] ^ hash_message_n[1]
|
||||
)
|
||||
outbuf = io.BytesIO()
|
||||
for _ in range(min(SCRAMBLE_LENGTH_323, len(message))):
|
||||
outbuf.write(int2byte(int(rand_st.my_rnd() * 31) + 64))
|
||||
extra = int2byte(int(rand_st.my_rnd() * 31))
|
||||
out = outbuf.getvalue()
|
||||
outbuf = io.BytesIO()
|
||||
for c in out:
|
||||
outbuf.write(int2byte(byte2int(c) ^ byte2int(extra)))
|
||||
return outbuf.getvalue()
|
||||
|
||||
|
||||
def _hash_password_323(password):
|
||||
nr = 1345345333
|
||||
add = 7
|
||||
nr2 = 0x12345671
|
||||
|
||||
# x in py3 is numbers, p27 is chars
|
||||
for c in [byte2int(x) for x in password if x not in (' ', '\t', 32, 9)]:
|
||||
nr ^= (((nr & 63) + add) * c) + (nr << 8) & 0xFFFFFFFF
|
||||
nr2 = (nr2 + ((nr2 << 8) ^ nr)) & 0xFFFFFFFF
|
||||
add = (add + c) & 0xFFFFFFFF
|
||||
|
||||
r1 = nr & ((1 << 31) - 1) # kill sign bits
|
||||
r2 = nr2 & ((1 << 31) - 1)
|
||||
return struct.pack(">LL", r1, r2)
|
||||
|
||||
|
||||
# MariaDB's client_ed25519-plugin
|
||||
# https://mariadb.com/kb/en/library/connection/#client_ed25519-plugin
|
||||
|
||||
_nacl_bindings = False
|
||||
|
||||
|
||||
def _init_nacl():
|
||||
global _nacl_bindings
|
||||
try:
|
||||
from nacl import bindings
|
||||
_nacl_bindings = bindings
|
||||
except ImportError:
|
||||
raise RuntimeError("'pynacl' package is required for ed25519_password auth method")
|
||||
|
||||
|
||||
def _scalar_clamp(s32):
|
||||
ba = bytearray(s32)
|
||||
ba0 = bytes(bytearray([ba[0] & 248]))
|
||||
ba31 = bytes(bytearray([(ba[31] & 127) | 64]))
|
||||
return ba0 + bytes(s32[1:31]) + ba31
|
||||
|
||||
|
||||
def ed25519_password(password, scramble):
|
||||
"""Sign a random scramble with elliptic curve Ed25519.
|
||||
|
||||
Secret and public key are derived from password.
|
||||
"""
|
||||
# variable names based on rfc8032 section-5.1.6
|
||||
#
|
||||
if not _nacl_bindings:
|
||||
_init_nacl()
|
||||
|
||||
# h = SHA512(password)
|
||||
h = hashlib.sha512(password).digest()
|
||||
|
||||
# s = prune(first_half(h))
|
||||
s = _scalar_clamp(h[:32])
|
||||
|
||||
# r = SHA512(second_half(h) || M)
|
||||
r = hashlib.sha512(h[32:] + scramble).digest()
|
||||
|
||||
# R = encoded point [r]B
|
||||
r = _nacl_bindings.crypto_core_ed25519_scalar_reduce(r)
|
||||
R = _nacl_bindings.crypto_scalarmult_ed25519_base_noclamp(r)
|
||||
|
||||
# A = encoded point [s]B
|
||||
A = _nacl_bindings.crypto_scalarmult_ed25519_base_noclamp(s)
|
||||
|
||||
# k = SHA512(R || A || M)
|
||||
k = hashlib.sha512(R + A + scramble).digest()
|
||||
|
||||
# S = (k * s + r) mod L
|
||||
k = _nacl_bindings.crypto_core_ed25519_scalar_reduce(k)
|
||||
ks = _nacl_bindings.crypto_core_ed25519_scalar_mul(k, s)
|
||||
S = _nacl_bindings.crypto_core_ed25519_scalar_add(ks, r)
|
||||
|
||||
# signature = R || S
|
||||
return R + S
|
||||
|
||||
|
||||
# sha256_password
|
||||
|
||||
|
||||
def _roundtrip(conn, send_data):
|
||||
conn.write_packet(send_data)
|
||||
pkt = conn._read_packet()
|
||||
pkt.check_error()
|
||||
return pkt
|
||||
|
||||
|
||||
def _xor_password(password, salt):
|
||||
# Trailing NUL character will be added in Auth Switch Request.
|
||||
# See https://github.com/mysql/mysql-server/blob/7d10c82196c8e45554f27c00681474a9fb86d137/sql/auth/sha2_password.cc#L939-L945
|
||||
salt = salt[:SCRAMBLE_LENGTH]
|
||||
password_bytes = bytearray(password)
|
||||
salt = bytearray(salt) # for PY2 compat.
|
||||
salt_len = len(salt)
|
||||
for i in range(len(password_bytes)):
|
||||
password_bytes[i] ^= salt[i % salt_len]
|
||||
return bytes(password_bytes)
|
||||
|
||||
|
||||
def sha2_rsa_encrypt(password, salt, public_key):
|
||||
"""Encrypt password with salt and public_key.
|
||||
|
||||
Used for sha256_password and caching_sha2_password.
|
||||
"""
|
||||
if not _have_cryptography:
|
||||
raise RuntimeError("'cryptography' package is required for sha256_password or caching_sha2_password auth methods")
|
||||
message = _xor_password(password + b'\0', salt)
|
||||
rsa_key = serialization.load_pem_public_key(public_key, default_backend())
|
||||
return rsa_key.encrypt(
|
||||
message,
|
||||
padding.OAEP(
|
||||
mgf=padding.MGF1(algorithm=hashes.SHA1()),
|
||||
algorithm=hashes.SHA1(),
|
||||
label=None,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def sha256_password_auth(conn, pkt):
|
||||
if conn._secure:
|
||||
if DEBUG:
|
||||
print("sha256: Sending plain password")
|
||||
data = conn.password + b'\0'
|
||||
return _roundtrip(conn, data)
|
||||
|
||||
if pkt.is_auth_switch_request():
|
||||
conn.salt = pkt.read_all()
|
||||
if not conn.server_public_key and conn.password:
|
||||
# Request server public key
|
||||
if DEBUG:
|
||||
print("sha256: Requesting server public key")
|
||||
pkt = _roundtrip(conn, b'\1')
|
||||
|
||||
if pkt.is_extra_auth_data():
|
||||
conn.server_public_key = pkt._data[1:]
|
||||
if DEBUG:
|
||||
print("Received public key:\n", conn.server_public_key.decode('ascii'))
|
||||
|
||||
if conn.password:
|
||||
if not conn.server_public_key:
|
||||
raise OperationalError("Couldn't receive server's public key")
|
||||
|
||||
data = sha2_rsa_encrypt(conn.password, conn.salt, conn.server_public_key)
|
||||
else:
|
||||
data = b''
|
||||
|
||||
return _roundtrip(conn, data)
|
||||
|
||||
|
||||
def scramble_caching_sha2(password, nonce):
|
||||
# (bytes, bytes) -> bytes
|
||||
"""Scramble algorithm used in cached_sha2_password fast path.
|
||||
|
||||
XOR(SHA256(password), SHA256(SHA256(SHA256(password)), nonce))
|
||||
"""
|
||||
if not password:
|
||||
return b''
|
||||
|
||||
p1 = hashlib.sha256(password).digest()
|
||||
p2 = hashlib.sha256(p1).digest()
|
||||
p3 = hashlib.sha256(p2 + nonce).digest()
|
||||
|
||||
res = bytearray(p1)
|
||||
if PY2:
|
||||
p3 = bytearray(p3)
|
||||
for i in range(len(p3)):
|
||||
res[i] ^= p3[i]
|
||||
|
||||
return bytes(res)
|
||||
|
||||
|
||||
def caching_sha2_password_auth(conn, pkt):
|
||||
# No password fast path
|
||||
if not conn.password:
|
||||
return _roundtrip(conn, b'')
|
||||
|
||||
if pkt.is_auth_switch_request():
|
||||
# Try from fast auth
|
||||
if DEBUG:
|
||||
print("caching sha2: Trying fast path")
|
||||
conn.salt = pkt.read_all()
|
||||
scrambled = scramble_caching_sha2(conn.password, conn.salt)
|
||||
pkt = _roundtrip(conn, scrambled)
|
||||
# else: fast auth is tried in initial handshake
|
||||
|
||||
if not pkt.is_extra_auth_data():
|
||||
raise OperationalError(
|
||||
"caching sha2: Unknown packet for fast auth: %s" % pkt._data[:1]
|
||||
)
|
||||
|
||||
# magic numbers:
|
||||
# 2 - request public key
|
||||
# 3 - fast auth succeeded
|
||||
# 4 - need full auth
|
||||
|
||||
pkt.advance(1)
|
||||
n = pkt.read_uint8()
|
||||
|
||||
if n == 3:
|
||||
if DEBUG:
|
||||
print("caching sha2: succeeded by fast path.")
|
||||
pkt = conn._read_packet()
|
||||
pkt.check_error() # pkt must be OK packet
|
||||
return pkt
|
||||
|
||||
if n != 4:
|
||||
raise OperationalError("caching sha2: Unknwon result for fast auth: %s" % n)
|
||||
|
||||
if DEBUG:
|
||||
print("caching sha2: Trying full auth...")
|
||||
|
||||
if conn._secure:
|
||||
if DEBUG:
|
||||
print("caching sha2: Sending plain password via secure connection")
|
||||
return _roundtrip(conn, conn.password + b'\0')
|
||||
|
||||
if not conn.server_public_key:
|
||||
pkt = _roundtrip(conn, b'\x02') # Request public key
|
||||
if not pkt.is_extra_auth_data():
|
||||
raise OperationalError(
|
||||
"caching sha2: Unknown packet for public key: %s" % pkt._data[:1]
|
||||
)
|
||||
|
||||
conn.server_public_key = pkt._data[1:]
|
||||
if DEBUG:
|
||||
print(conn.server_public_key.decode('ascii'))
|
||||
|
||||
data = sha2_rsa_encrypt(conn.password, conn.salt, conn.server_public_key)
|
||||
pkt = _roundtrip(conn, data)
|
||||
21
venv/lib/python3.9/site-packages/pymysql/_compat.py
Normal file
21
venv/lib/python3.9/site-packages/pymysql/_compat.py
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import sys
|
||||
|
||||
PY2 = sys.version_info[0] == 2
|
||||
PYPY = hasattr(sys, 'pypy_translation_info')
|
||||
JYTHON = sys.platform.startswith('java')
|
||||
IRONPYTHON = sys.platform == 'cli'
|
||||
CPYTHON = not PYPY and not JYTHON and not IRONPYTHON
|
||||
|
||||
if PY2:
|
||||
import __builtin__
|
||||
range_type = xrange
|
||||
text_type = unicode
|
||||
long_type = long
|
||||
str_type = basestring
|
||||
unichr = __builtin__.unichr
|
||||
else:
|
||||
range_type = range
|
||||
text_type = str
|
||||
long_type = int
|
||||
str_type = str
|
||||
unichr = chr
|
||||
134
venv/lib/python3.9/site-packages/pymysql/_socketio.py
Normal file
134
venv/lib/python3.9/site-packages/pymysql/_socketio.py
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
"""
|
||||
SocketIO imported from socket module in Python 3.
|
||||
|
||||
Copyright (c) 2001-2013 Python Software Foundation; All Rights Reserved.
|
||||
"""
|
||||
|
||||
from socket import *
|
||||
import io
|
||||
import errno
|
||||
|
||||
__all__ = ['SocketIO']
|
||||
|
||||
EINTR = errno.EINTR
|
||||
_blocking_errnos = (errno.EAGAIN, errno.EWOULDBLOCK)
|
||||
|
||||
class SocketIO(io.RawIOBase):
|
||||
|
||||
"""Raw I/O implementation for stream sockets.
|
||||
|
||||
This class supports the makefile() method on sockets. It provides
|
||||
the raw I/O interface on top of a socket object.
|
||||
"""
|
||||
|
||||
# One might wonder why not let FileIO do the job instead. There are two
|
||||
# main reasons why FileIO is not adapted:
|
||||
# - it wouldn't work under Windows (where you can't used read() and
|
||||
# write() on a socket handle)
|
||||
# - it wouldn't work with socket timeouts (FileIO would ignore the
|
||||
# timeout and consider the socket non-blocking)
|
||||
|
||||
# XXX More docs
|
||||
|
||||
def __init__(self, sock, mode):
|
||||
if mode not in ("r", "w", "rw", "rb", "wb", "rwb"):
|
||||
raise ValueError("invalid mode: %r" % mode)
|
||||
io.RawIOBase.__init__(self)
|
||||
self._sock = sock
|
||||
if "b" not in mode:
|
||||
mode += "b"
|
||||
self._mode = mode
|
||||
self._reading = "r" in mode
|
||||
self._writing = "w" in mode
|
||||
self._timeout_occurred = False
|
||||
|
||||
def readinto(self, b):
|
||||
"""Read up to len(b) bytes into the writable buffer *b* and return
|
||||
the number of bytes read. If the socket is non-blocking and no bytes
|
||||
are available, None is returned.
|
||||
|
||||
If *b* is non-empty, a 0 return value indicates that the connection
|
||||
was shutdown at the other end.
|
||||
"""
|
||||
self._checkClosed()
|
||||
self._checkReadable()
|
||||
if self._timeout_occurred:
|
||||
raise IOError("cannot read from timed out object")
|
||||
while True:
|
||||
try:
|
||||
return self._sock.recv_into(b)
|
||||
except timeout:
|
||||
self._timeout_occurred = True
|
||||
raise
|
||||
except error as e:
|
||||
n = e.args[0]
|
||||
if n == EINTR:
|
||||
continue
|
||||
if n in _blocking_errnos:
|
||||
return None
|
||||
raise
|
||||
|
||||
def write(self, b):
|
||||
"""Write the given bytes or bytearray object *b* to the socket
|
||||
and return the number of bytes written. This can be less than
|
||||
len(b) if not all data could be written. If the socket is
|
||||
non-blocking and no bytes could be written None is returned.
|
||||
"""
|
||||
self._checkClosed()
|
||||
self._checkWritable()
|
||||
try:
|
||||
return self._sock.send(b)
|
||||
except error as e:
|
||||
# XXX what about EINTR?
|
||||
if e.args[0] in _blocking_errnos:
|
||||
return None
|
||||
raise
|
||||
|
||||
def readable(self):
|
||||
"""True if the SocketIO is open for reading.
|
||||
"""
|
||||
if self.closed:
|
||||
raise ValueError("I/O operation on closed socket.")
|
||||
return self._reading
|
||||
|
||||
def writable(self):
|
||||
"""True if the SocketIO is open for writing.
|
||||
"""
|
||||
if self.closed:
|
||||
raise ValueError("I/O operation on closed socket.")
|
||||
return self._writing
|
||||
|
||||
def seekable(self):
|
||||
"""True if the SocketIO is open for seeking.
|
||||
"""
|
||||
if self.closed:
|
||||
raise ValueError("I/O operation on closed socket.")
|
||||
return super().seekable()
|
||||
|
||||
def fileno(self):
|
||||
"""Return the file descriptor of the underlying socket.
|
||||
"""
|
||||
self._checkClosed()
|
||||
return self._sock.fileno()
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
if not self.closed:
|
||||
return self.fileno()
|
||||
else:
|
||||
return -1
|
||||
|
||||
@property
|
||||
def mode(self):
|
||||
return self._mode
|
||||
|
||||
def close(self):
|
||||
"""Close the SocketIO object. This doesn't close the underlying
|
||||
socket, except if all references to it have disappeared.
|
||||
"""
|
||||
if self.closed:
|
||||
return
|
||||
io.RawIOBase.close(self)
|
||||
self._sock._decref_socketios()
|
||||
self._sock = None
|
||||
|
||||
210
venv/lib/python3.9/site-packages/pymysql/charset.py
Normal file
210
venv/lib/python3.9/site-packages/pymysql/charset.py
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
MBLENGTH = {
|
||||
8:1,
|
||||
33:3,
|
||||
88:2,
|
||||
91:2
|
||||
}
|
||||
|
||||
|
||||
class Charset(object):
|
||||
def __init__(self, id, name, collation, is_default):
|
||||
self.id, self.name, self.collation = id, name, collation
|
||||
self.is_default = is_default == 'Yes'
|
||||
|
||||
def __repr__(self):
|
||||
return "Charset(id=%s, name=%r, collation=%r)" % (
|
||||
self.id, self.name, self.collation)
|
||||
|
||||
@property
|
||||
def encoding(self):
|
||||
name = self.name
|
||||
if name in ('utf8mb4', 'utf8mb3'):
|
||||
return 'utf8'
|
||||
if name == 'latin1':
|
||||
return 'cp1252'
|
||||
if name == 'koi8r':
|
||||
return 'koi8_r'
|
||||
if name == 'koi8u':
|
||||
return 'koi8_u'
|
||||
return name
|
||||
|
||||
@property
|
||||
def is_binary(self):
|
||||
return self.id == 63
|
||||
|
||||
|
||||
class Charsets:
|
||||
def __init__(self):
|
||||
self._by_id = {}
|
||||
self._by_name = {}
|
||||
|
||||
def add(self, c):
|
||||
self._by_id[c.id] = c
|
||||
if c.is_default:
|
||||
self._by_name[c.name] = c
|
||||
|
||||
def by_id(self, id):
|
||||
return self._by_id[id]
|
||||
|
||||
def by_name(self, name):
|
||||
return self._by_name.get(name.lower())
|
||||
|
||||
_charsets = Charsets()
|
||||
"""
|
||||
Generated with:
|
||||
|
||||
mysql -N -s -e "select id, character_set_name, collation_name, is_default
|
||||
from information_schema.collations order by id;" | python -c "import sys
|
||||
for l in sys.stdin.readlines():
|
||||
id, name, collation, is_default = l.split(chr(9))
|
||||
print '_charsets.add(Charset(%s, \'%s\', \'%s\', \'%s\'))' \
|
||||
% (id, name, collation, is_default.strip())
|
||||
"
|
||||
|
||||
"""
|
||||
_charsets.add(Charset(1, 'big5', 'big5_chinese_ci', 'Yes'))
|
||||
_charsets.add(Charset(2, 'latin2', 'latin2_czech_cs', ''))
|
||||
_charsets.add(Charset(3, 'dec8', 'dec8_swedish_ci', 'Yes'))
|
||||
_charsets.add(Charset(4, 'cp850', 'cp850_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(5, 'latin1', 'latin1_german1_ci', ''))
|
||||
_charsets.add(Charset(6, 'hp8', 'hp8_english_ci', 'Yes'))
|
||||
_charsets.add(Charset(7, 'koi8r', 'koi8r_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(8, 'latin1', 'latin1_swedish_ci', 'Yes'))
|
||||
_charsets.add(Charset(9, 'latin2', 'latin2_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(10, 'swe7', 'swe7_swedish_ci', 'Yes'))
|
||||
_charsets.add(Charset(11, 'ascii', 'ascii_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(12, 'ujis', 'ujis_japanese_ci', 'Yes'))
|
||||
_charsets.add(Charset(13, 'sjis', 'sjis_japanese_ci', 'Yes'))
|
||||
_charsets.add(Charset(14, 'cp1251', 'cp1251_bulgarian_ci', ''))
|
||||
_charsets.add(Charset(15, 'latin1', 'latin1_danish_ci', ''))
|
||||
_charsets.add(Charset(16, 'hebrew', 'hebrew_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(18, 'tis620', 'tis620_thai_ci', 'Yes'))
|
||||
_charsets.add(Charset(19, 'euckr', 'euckr_korean_ci', 'Yes'))
|
||||
_charsets.add(Charset(20, 'latin7', 'latin7_estonian_cs', ''))
|
||||
_charsets.add(Charset(21, 'latin2', 'latin2_hungarian_ci', ''))
|
||||
_charsets.add(Charset(22, 'koi8u', 'koi8u_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(23, 'cp1251', 'cp1251_ukrainian_ci', ''))
|
||||
_charsets.add(Charset(24, 'gb2312', 'gb2312_chinese_ci', 'Yes'))
|
||||
_charsets.add(Charset(25, 'greek', 'greek_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(26, 'cp1250', 'cp1250_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(27, 'latin2', 'latin2_croatian_ci', ''))
|
||||
_charsets.add(Charset(28, 'gbk', 'gbk_chinese_ci', 'Yes'))
|
||||
_charsets.add(Charset(29, 'cp1257', 'cp1257_lithuanian_ci', ''))
|
||||
_charsets.add(Charset(30, 'latin5', 'latin5_turkish_ci', 'Yes'))
|
||||
_charsets.add(Charset(31, 'latin1', 'latin1_german2_ci', ''))
|
||||
_charsets.add(Charset(32, 'armscii8', 'armscii8_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(33, 'utf8', 'utf8_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(34, 'cp1250', 'cp1250_czech_cs', ''))
|
||||
_charsets.add(Charset(36, 'cp866', 'cp866_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(37, 'keybcs2', 'keybcs2_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(38, 'macce', 'macce_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(39, 'macroman', 'macroman_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(40, 'cp852', 'cp852_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(41, 'latin7', 'latin7_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(42, 'latin7', 'latin7_general_cs', ''))
|
||||
_charsets.add(Charset(43, 'macce', 'macce_bin', ''))
|
||||
_charsets.add(Charset(44, 'cp1250', 'cp1250_croatian_ci', ''))
|
||||
_charsets.add(Charset(45, 'utf8mb4', 'utf8mb4_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(46, 'utf8mb4', 'utf8mb4_bin', ''))
|
||||
_charsets.add(Charset(47, 'latin1', 'latin1_bin', ''))
|
||||
_charsets.add(Charset(48, 'latin1', 'latin1_general_ci', ''))
|
||||
_charsets.add(Charset(49, 'latin1', 'latin1_general_cs', ''))
|
||||
_charsets.add(Charset(50, 'cp1251', 'cp1251_bin', ''))
|
||||
_charsets.add(Charset(51, 'cp1251', 'cp1251_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(52, 'cp1251', 'cp1251_general_cs', ''))
|
||||
_charsets.add(Charset(53, 'macroman', 'macroman_bin', ''))
|
||||
_charsets.add(Charset(57, 'cp1256', 'cp1256_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(58, 'cp1257', 'cp1257_bin', ''))
|
||||
_charsets.add(Charset(59, 'cp1257', 'cp1257_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(63, 'binary', 'binary', 'Yes'))
|
||||
_charsets.add(Charset(64, 'armscii8', 'armscii8_bin', ''))
|
||||
_charsets.add(Charset(65, 'ascii', 'ascii_bin', ''))
|
||||
_charsets.add(Charset(66, 'cp1250', 'cp1250_bin', ''))
|
||||
_charsets.add(Charset(67, 'cp1256', 'cp1256_bin', ''))
|
||||
_charsets.add(Charset(68, 'cp866', 'cp866_bin', ''))
|
||||
_charsets.add(Charset(69, 'dec8', 'dec8_bin', ''))
|
||||
_charsets.add(Charset(70, 'greek', 'greek_bin', ''))
|
||||
_charsets.add(Charset(71, 'hebrew', 'hebrew_bin', ''))
|
||||
_charsets.add(Charset(72, 'hp8', 'hp8_bin', ''))
|
||||
_charsets.add(Charset(73, 'keybcs2', 'keybcs2_bin', ''))
|
||||
_charsets.add(Charset(74, 'koi8r', 'koi8r_bin', ''))
|
||||
_charsets.add(Charset(75, 'koi8u', 'koi8u_bin', ''))
|
||||
_charsets.add(Charset(76, 'utf8', 'utf8_tolower_ci', ''))
|
||||
_charsets.add(Charset(77, 'latin2', 'latin2_bin', ''))
|
||||
_charsets.add(Charset(78, 'latin5', 'latin5_bin', ''))
|
||||
_charsets.add(Charset(79, 'latin7', 'latin7_bin', ''))
|
||||
_charsets.add(Charset(80, 'cp850', 'cp850_bin', ''))
|
||||
_charsets.add(Charset(81, 'cp852', 'cp852_bin', ''))
|
||||
_charsets.add(Charset(82, 'swe7', 'swe7_bin', ''))
|
||||
_charsets.add(Charset(83, 'utf8', 'utf8_bin', ''))
|
||||
_charsets.add(Charset(84, 'big5', 'big5_bin', ''))
|
||||
_charsets.add(Charset(85, 'euckr', 'euckr_bin', ''))
|
||||
_charsets.add(Charset(86, 'gb2312', 'gb2312_bin', ''))
|
||||
_charsets.add(Charset(87, 'gbk', 'gbk_bin', ''))
|
||||
_charsets.add(Charset(88, 'sjis', 'sjis_bin', ''))
|
||||
_charsets.add(Charset(89, 'tis620', 'tis620_bin', ''))
|
||||
_charsets.add(Charset(91, 'ujis', 'ujis_bin', ''))
|
||||
_charsets.add(Charset(92, 'geostd8', 'geostd8_general_ci', 'Yes'))
|
||||
_charsets.add(Charset(93, 'geostd8', 'geostd8_bin', ''))
|
||||
_charsets.add(Charset(94, 'latin1', 'latin1_spanish_ci', ''))
|
||||
_charsets.add(Charset(95, 'cp932', 'cp932_japanese_ci', 'Yes'))
|
||||
_charsets.add(Charset(96, 'cp932', 'cp932_bin', ''))
|
||||
_charsets.add(Charset(97, 'eucjpms', 'eucjpms_japanese_ci', 'Yes'))
|
||||
_charsets.add(Charset(98, 'eucjpms', 'eucjpms_bin', ''))
|
||||
_charsets.add(Charset(99, 'cp1250', 'cp1250_polish_ci', ''))
|
||||
_charsets.add(Charset(192, 'utf8', 'utf8_unicode_ci', ''))
|
||||
_charsets.add(Charset(193, 'utf8', 'utf8_icelandic_ci', ''))
|
||||
_charsets.add(Charset(194, 'utf8', 'utf8_latvian_ci', ''))
|
||||
_charsets.add(Charset(195, 'utf8', 'utf8_romanian_ci', ''))
|
||||
_charsets.add(Charset(196, 'utf8', 'utf8_slovenian_ci', ''))
|
||||
_charsets.add(Charset(197, 'utf8', 'utf8_polish_ci', ''))
|
||||
_charsets.add(Charset(198, 'utf8', 'utf8_estonian_ci', ''))
|
||||
_charsets.add(Charset(199, 'utf8', 'utf8_spanish_ci', ''))
|
||||
_charsets.add(Charset(200, 'utf8', 'utf8_swedish_ci', ''))
|
||||
_charsets.add(Charset(201, 'utf8', 'utf8_turkish_ci', ''))
|
||||
_charsets.add(Charset(202, 'utf8', 'utf8_czech_ci', ''))
|
||||
_charsets.add(Charset(203, 'utf8', 'utf8_danish_ci', ''))
|
||||
_charsets.add(Charset(204, 'utf8', 'utf8_lithuanian_ci', ''))
|
||||
_charsets.add(Charset(205, 'utf8', 'utf8_slovak_ci', ''))
|
||||
_charsets.add(Charset(206, 'utf8', 'utf8_spanish2_ci', ''))
|
||||
_charsets.add(Charset(207, 'utf8', 'utf8_roman_ci', ''))
|
||||
_charsets.add(Charset(208, 'utf8', 'utf8_persian_ci', ''))
|
||||
_charsets.add(Charset(209, 'utf8', 'utf8_esperanto_ci', ''))
|
||||
_charsets.add(Charset(210, 'utf8', 'utf8_hungarian_ci', ''))
|
||||
_charsets.add(Charset(211, 'utf8', 'utf8_sinhala_ci', ''))
|
||||
_charsets.add(Charset(212, 'utf8', 'utf8_german2_ci', ''))
|
||||
_charsets.add(Charset(213, 'utf8', 'utf8_croatian_ci', ''))
|
||||
_charsets.add(Charset(214, 'utf8', 'utf8_unicode_520_ci', ''))
|
||||
_charsets.add(Charset(215, 'utf8', 'utf8_vietnamese_ci', ''))
|
||||
_charsets.add(Charset(223, 'utf8', 'utf8_general_mysql500_ci', ''))
|
||||
_charsets.add(Charset(224, 'utf8mb4', 'utf8mb4_unicode_ci', ''))
|
||||
_charsets.add(Charset(225, 'utf8mb4', 'utf8mb4_icelandic_ci', ''))
|
||||
_charsets.add(Charset(226, 'utf8mb4', 'utf8mb4_latvian_ci', ''))
|
||||
_charsets.add(Charset(227, 'utf8mb4', 'utf8mb4_romanian_ci', ''))
|
||||
_charsets.add(Charset(228, 'utf8mb4', 'utf8mb4_slovenian_ci', ''))
|
||||
_charsets.add(Charset(229, 'utf8mb4', 'utf8mb4_polish_ci', ''))
|
||||
_charsets.add(Charset(230, 'utf8mb4', 'utf8mb4_estonian_ci', ''))
|
||||
_charsets.add(Charset(231, 'utf8mb4', 'utf8mb4_spanish_ci', ''))
|
||||
_charsets.add(Charset(232, 'utf8mb4', 'utf8mb4_swedish_ci', ''))
|
||||
_charsets.add(Charset(233, 'utf8mb4', 'utf8mb4_turkish_ci', ''))
|
||||
_charsets.add(Charset(234, 'utf8mb4', 'utf8mb4_czech_ci', ''))
|
||||
_charsets.add(Charset(235, 'utf8mb4', 'utf8mb4_danish_ci', ''))
|
||||
_charsets.add(Charset(236, 'utf8mb4', 'utf8mb4_lithuanian_ci', ''))
|
||||
_charsets.add(Charset(237, 'utf8mb4', 'utf8mb4_slovak_ci', ''))
|
||||
_charsets.add(Charset(238, 'utf8mb4', 'utf8mb4_spanish2_ci', ''))
|
||||
_charsets.add(Charset(239, 'utf8mb4', 'utf8mb4_roman_ci', ''))
|
||||
_charsets.add(Charset(240, 'utf8mb4', 'utf8mb4_persian_ci', ''))
|
||||
_charsets.add(Charset(241, 'utf8mb4', 'utf8mb4_esperanto_ci', ''))
|
||||
_charsets.add(Charset(242, 'utf8mb4', 'utf8mb4_hungarian_ci', ''))
|
||||
_charsets.add(Charset(243, 'utf8mb4', 'utf8mb4_sinhala_ci', ''))
|
||||
_charsets.add(Charset(244, 'utf8mb4', 'utf8mb4_german2_ci', ''))
|
||||
_charsets.add(Charset(245, 'utf8mb4', 'utf8mb4_croatian_ci', ''))
|
||||
_charsets.add(Charset(246, 'utf8mb4', 'utf8mb4_unicode_520_ci', ''))
|
||||
_charsets.add(Charset(247, 'utf8mb4', 'utf8mb4_vietnamese_ci', ''))
|
||||
_charsets.add(Charset(248, 'gb18030', 'gb18030_chinese_ci', 'Yes'))
|
||||
_charsets.add(Charset(249, 'gb18030', 'gb18030_bin', ''))
|
||||
_charsets.add(Charset(250, 'gb18030', 'gb18030_unicode_520_ci', ''))
|
||||
_charsets.add(Charset(255, 'utf8mb4', 'utf8mb4_0900_ai_ci', ''))
|
||||
|
||||
charset_by_name = _charsets.by_name
|
||||
charset_by_id = _charsets.by_id
|
||||
1273
venv/lib/python3.9/site-packages/pymysql/connections.py
Normal file
1273
venv/lib/python3.9/site-packages/pymysql/connections.py
Normal file
File diff suppressed because it is too large
Load diff
31
venv/lib/python3.9/site-packages/pymysql/constants/CLIENT.py
Normal file
31
venv/lib/python3.9/site-packages/pymysql/constants/CLIENT.py
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# https://dev.mysql.com/doc/internals/en/capability-flags.html#packet-Protocol::CapabilityFlags
|
||||
LONG_PASSWORD = 1
|
||||
FOUND_ROWS = 1 << 1
|
||||
LONG_FLAG = 1 << 2
|
||||
CONNECT_WITH_DB = 1 << 3
|
||||
NO_SCHEMA = 1 << 4
|
||||
COMPRESS = 1 << 5
|
||||
ODBC = 1 << 6
|
||||
LOCAL_FILES = 1 << 7
|
||||
IGNORE_SPACE = 1 << 8
|
||||
PROTOCOL_41 = 1 << 9
|
||||
INTERACTIVE = 1 << 10
|
||||
SSL = 1 << 11
|
||||
IGNORE_SIGPIPE = 1 << 12
|
||||
TRANSACTIONS = 1 << 13
|
||||
SECURE_CONNECTION = 1 << 15
|
||||
MULTI_STATEMENTS = 1 << 16
|
||||
MULTI_RESULTS = 1 << 17
|
||||
PS_MULTI_RESULTS = 1 << 18
|
||||
PLUGIN_AUTH = 1 << 19
|
||||
CONNECT_ATTRS = 1 << 20
|
||||
PLUGIN_AUTH_LENENC_CLIENT_DATA = 1 << 21
|
||||
CAPABILITIES = (
|
||||
LONG_PASSWORD | LONG_FLAG | PROTOCOL_41 | TRANSACTIONS
|
||||
| SECURE_CONNECTION | MULTI_RESULTS
|
||||
| PLUGIN_AUTH | PLUGIN_AUTH_LENENC_CLIENT_DATA | CONNECT_ATTRS)
|
||||
|
||||
# Not done yet
|
||||
HANDLE_EXPIRED_PASSWORDS = 1 << 22
|
||||
SESSION_TRACK = 1 << 23
|
||||
DEPRECATE_EOF = 1 << 24
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
COM_SLEEP = 0x00
|
||||
COM_QUIT = 0x01
|
||||
COM_INIT_DB = 0x02
|
||||
COM_QUERY = 0x03
|
||||
COM_FIELD_LIST = 0x04
|
||||
COM_CREATE_DB = 0x05
|
||||
COM_DROP_DB = 0x06
|
||||
COM_REFRESH = 0x07
|
||||
COM_SHUTDOWN = 0x08
|
||||
COM_STATISTICS = 0x09
|
||||
COM_PROCESS_INFO = 0x0a
|
||||
COM_CONNECT = 0x0b
|
||||
COM_PROCESS_KILL = 0x0c
|
||||
COM_DEBUG = 0x0d
|
||||
COM_PING = 0x0e
|
||||
COM_TIME = 0x0f
|
||||
COM_DELAYED_INSERT = 0x10
|
||||
COM_CHANGE_USER = 0x11
|
||||
COM_BINLOG_DUMP = 0x12
|
||||
COM_TABLE_DUMP = 0x13
|
||||
COM_CONNECT_OUT = 0x14
|
||||
COM_REGISTER_SLAVE = 0x15
|
||||
COM_STMT_PREPARE = 0x16
|
||||
COM_STMT_EXECUTE = 0x17
|
||||
COM_STMT_SEND_LONG_DATA = 0x18
|
||||
COM_STMT_CLOSE = 0x19
|
||||
COM_STMT_RESET = 0x1a
|
||||
COM_SET_OPTION = 0x1b
|
||||
COM_STMT_FETCH = 0x1c
|
||||
COM_DAEMON = 0x1d
|
||||
COM_BINLOG_DUMP_GTID = 0x1e
|
||||
COM_END = 0x1f
|
||||
68
venv/lib/python3.9/site-packages/pymysql/constants/CR.py
Normal file
68
venv/lib/python3.9/site-packages/pymysql/constants/CR.py
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
# flake8: noqa
|
||||
# errmsg.h
|
||||
CR_ERROR_FIRST = 2000
|
||||
CR_UNKNOWN_ERROR = 2000
|
||||
CR_SOCKET_CREATE_ERROR = 2001
|
||||
CR_CONNECTION_ERROR = 2002
|
||||
CR_CONN_HOST_ERROR = 2003
|
||||
CR_IPSOCK_ERROR = 2004
|
||||
CR_UNKNOWN_HOST = 2005
|
||||
CR_SERVER_GONE_ERROR = 2006
|
||||
CR_VERSION_ERROR = 2007
|
||||
CR_OUT_OF_MEMORY = 2008
|
||||
CR_WRONG_HOST_INFO = 2009
|
||||
CR_LOCALHOST_CONNECTION = 2010
|
||||
CR_TCP_CONNECTION = 2011
|
||||
CR_SERVER_HANDSHAKE_ERR = 2012
|
||||
CR_SERVER_LOST = 2013
|
||||
CR_COMMANDS_OUT_OF_SYNC = 2014
|
||||
CR_NAMEDPIPE_CONNECTION = 2015
|
||||
CR_NAMEDPIPEWAIT_ERROR = 2016
|
||||
CR_NAMEDPIPEOPEN_ERROR = 2017
|
||||
CR_NAMEDPIPESETSTATE_ERROR = 2018
|
||||
CR_CANT_READ_CHARSET = 2019
|
||||
CR_NET_PACKET_TOO_LARGE = 2020
|
||||
CR_EMBEDDED_CONNECTION = 2021
|
||||
CR_PROBE_SLAVE_STATUS = 2022
|
||||
CR_PROBE_SLAVE_HOSTS = 2023
|
||||
CR_PROBE_SLAVE_CONNECT = 2024
|
||||
CR_PROBE_MASTER_CONNECT = 2025
|
||||
CR_SSL_CONNECTION_ERROR = 2026
|
||||
CR_MALFORMED_PACKET = 2027
|
||||
CR_WRONG_LICENSE = 2028
|
||||
|
||||
CR_NULL_POINTER = 2029
|
||||
CR_NO_PREPARE_STMT = 2030
|
||||
CR_PARAMS_NOT_BOUND = 2031
|
||||
CR_DATA_TRUNCATED = 2032
|
||||
CR_NO_PARAMETERS_EXISTS = 2033
|
||||
CR_INVALID_PARAMETER_NO = 2034
|
||||
CR_INVALID_BUFFER_USE = 2035
|
||||
CR_UNSUPPORTED_PARAM_TYPE = 2036
|
||||
|
||||
CR_SHARED_MEMORY_CONNECTION = 2037
|
||||
CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR = 2038
|
||||
CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR = 2039
|
||||
CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR = 2040
|
||||
CR_SHARED_MEMORY_CONNECT_MAP_ERROR = 2041
|
||||
CR_SHARED_MEMORY_FILE_MAP_ERROR = 2042
|
||||
CR_SHARED_MEMORY_MAP_ERROR = 2043
|
||||
CR_SHARED_MEMORY_EVENT_ERROR = 2044
|
||||
CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR = 2045
|
||||
CR_SHARED_MEMORY_CONNECT_SET_ERROR = 2046
|
||||
CR_CONN_UNKNOW_PROTOCOL = 2047
|
||||
CR_INVALID_CONN_HANDLE = 2048
|
||||
CR_SECURE_AUTH = 2049
|
||||
CR_FETCH_CANCELED = 2050
|
||||
CR_NO_DATA = 2051
|
||||
CR_NO_STMT_METADATA = 2052
|
||||
CR_NO_RESULT_SET = 2053
|
||||
CR_NOT_IMPLEMENTED = 2054
|
||||
CR_SERVER_LOST_EXTENDED = 2055
|
||||
CR_STMT_CLOSED = 2056
|
||||
CR_NEW_STMT_METADATA = 2057
|
||||
CR_ALREADY_CONNECTED = 2058
|
||||
CR_AUTH_PLUGIN_CANNOT_LOAD = 2059
|
||||
CR_DUPLICATE_CONNECTION_ATTR = 2060
|
||||
CR_AUTH_PLUGIN_ERR = 2061
|
||||
CR_ERROR_LAST = 2061
|
||||
474
venv/lib/python3.9/site-packages/pymysql/constants/ER.py
Normal file
474
venv/lib/python3.9/site-packages/pymysql/constants/ER.py
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
ERROR_FIRST = 1000
|
||||
HASHCHK = 1000
|
||||
NISAMCHK = 1001
|
||||
NO = 1002
|
||||
YES = 1003
|
||||
CANT_CREATE_FILE = 1004
|
||||
CANT_CREATE_TABLE = 1005
|
||||
CANT_CREATE_DB = 1006
|
||||
DB_CREATE_EXISTS = 1007
|
||||
DB_DROP_EXISTS = 1008
|
||||
DB_DROP_DELETE = 1009
|
||||
DB_DROP_RMDIR = 1010
|
||||
CANT_DELETE_FILE = 1011
|
||||
CANT_FIND_SYSTEM_REC = 1012
|
||||
CANT_GET_STAT = 1013
|
||||
CANT_GET_WD = 1014
|
||||
CANT_LOCK = 1015
|
||||
CANT_OPEN_FILE = 1016
|
||||
FILE_NOT_FOUND = 1017
|
||||
CANT_READ_DIR = 1018
|
||||
CANT_SET_WD = 1019
|
||||
CHECKREAD = 1020
|
||||
DISK_FULL = 1021
|
||||
DUP_KEY = 1022
|
||||
ERROR_ON_CLOSE = 1023
|
||||
ERROR_ON_READ = 1024
|
||||
ERROR_ON_RENAME = 1025
|
||||
ERROR_ON_WRITE = 1026
|
||||
FILE_USED = 1027
|
||||
FILSORT_ABORT = 1028
|
||||
FORM_NOT_FOUND = 1029
|
||||
GET_ERRNO = 1030
|
||||
ILLEGAL_HA = 1031
|
||||
KEY_NOT_FOUND = 1032
|
||||
NOT_FORM_FILE = 1033
|
||||
NOT_KEYFILE = 1034
|
||||
OLD_KEYFILE = 1035
|
||||
OPEN_AS_READONLY = 1036
|
||||
OUTOFMEMORY = 1037
|
||||
OUT_OF_SORTMEMORY = 1038
|
||||
UNEXPECTED_EOF = 1039
|
||||
CON_COUNT_ERROR = 1040
|
||||
OUT_OF_RESOURCES = 1041
|
||||
BAD_HOST_ERROR = 1042
|
||||
HANDSHAKE_ERROR = 1043
|
||||
DBACCESS_DENIED_ERROR = 1044
|
||||
ACCESS_DENIED_ERROR = 1045
|
||||
NO_DB_ERROR = 1046
|
||||
UNKNOWN_COM_ERROR = 1047
|
||||
BAD_NULL_ERROR = 1048
|
||||
BAD_DB_ERROR = 1049
|
||||
TABLE_EXISTS_ERROR = 1050
|
||||
BAD_TABLE_ERROR = 1051
|
||||
NON_UNIQ_ERROR = 1052
|
||||
SERVER_SHUTDOWN = 1053
|
||||
BAD_FIELD_ERROR = 1054
|
||||
WRONG_FIELD_WITH_GROUP = 1055
|
||||
WRONG_GROUP_FIELD = 1056
|
||||
WRONG_SUM_SELECT = 1057
|
||||
WRONG_VALUE_COUNT = 1058
|
||||
TOO_LONG_IDENT = 1059
|
||||
DUP_FIELDNAME = 1060
|
||||
DUP_KEYNAME = 1061
|
||||
DUP_ENTRY = 1062
|
||||
WRONG_FIELD_SPEC = 1063
|
||||
PARSE_ERROR = 1064
|
||||
EMPTY_QUERY = 1065
|
||||
NONUNIQ_TABLE = 1066
|
||||
INVALID_DEFAULT = 1067
|
||||
MULTIPLE_PRI_KEY = 1068
|
||||
TOO_MANY_KEYS = 1069
|
||||
TOO_MANY_KEY_PARTS = 1070
|
||||
TOO_LONG_KEY = 1071
|
||||
KEY_COLUMN_DOES_NOT_EXITS = 1072
|
||||
BLOB_USED_AS_KEY = 1073
|
||||
TOO_BIG_FIELDLENGTH = 1074
|
||||
WRONG_AUTO_KEY = 1075
|
||||
READY = 1076
|
||||
NORMAL_SHUTDOWN = 1077
|
||||
GOT_SIGNAL = 1078
|
||||
SHUTDOWN_COMPLETE = 1079
|
||||
FORCING_CLOSE = 1080
|
||||
IPSOCK_ERROR = 1081
|
||||
NO_SUCH_INDEX = 1082
|
||||
WRONG_FIELD_TERMINATORS = 1083
|
||||
BLOBS_AND_NO_TERMINATED = 1084
|
||||
TEXTFILE_NOT_READABLE = 1085
|
||||
FILE_EXISTS_ERROR = 1086
|
||||
LOAD_INFO = 1087
|
||||
ALTER_INFO = 1088
|
||||
WRONG_SUB_KEY = 1089
|
||||
CANT_REMOVE_ALL_FIELDS = 1090
|
||||
CANT_DROP_FIELD_OR_KEY = 1091
|
||||
INSERT_INFO = 1092
|
||||
UPDATE_TABLE_USED = 1093
|
||||
NO_SUCH_THREAD = 1094
|
||||
KILL_DENIED_ERROR = 1095
|
||||
NO_TABLES_USED = 1096
|
||||
TOO_BIG_SET = 1097
|
||||
NO_UNIQUE_LOGFILE = 1098
|
||||
TABLE_NOT_LOCKED_FOR_WRITE = 1099
|
||||
TABLE_NOT_LOCKED = 1100
|
||||
BLOB_CANT_HAVE_DEFAULT = 1101
|
||||
WRONG_DB_NAME = 1102
|
||||
WRONG_TABLE_NAME = 1103
|
||||
TOO_BIG_SELECT = 1104
|
||||
UNKNOWN_ERROR = 1105
|
||||
UNKNOWN_PROCEDURE = 1106
|
||||
WRONG_PARAMCOUNT_TO_PROCEDURE = 1107
|
||||
WRONG_PARAMETERS_TO_PROCEDURE = 1108
|
||||
UNKNOWN_TABLE = 1109
|
||||
FIELD_SPECIFIED_TWICE = 1110
|
||||
INVALID_GROUP_FUNC_USE = 1111
|
||||
UNSUPPORTED_EXTENSION = 1112
|
||||
TABLE_MUST_HAVE_COLUMNS = 1113
|
||||
RECORD_FILE_FULL = 1114
|
||||
UNKNOWN_CHARACTER_SET = 1115
|
||||
TOO_MANY_TABLES = 1116
|
||||
TOO_MANY_FIELDS = 1117
|
||||
TOO_BIG_ROWSIZE = 1118
|
||||
STACK_OVERRUN = 1119
|
||||
WRONG_OUTER_JOIN = 1120
|
||||
NULL_COLUMN_IN_INDEX = 1121
|
||||
CANT_FIND_UDF = 1122
|
||||
CANT_INITIALIZE_UDF = 1123
|
||||
UDF_NO_PATHS = 1124
|
||||
UDF_EXISTS = 1125
|
||||
CANT_OPEN_LIBRARY = 1126
|
||||
CANT_FIND_DL_ENTRY = 1127
|
||||
FUNCTION_NOT_DEFINED = 1128
|
||||
HOST_IS_BLOCKED = 1129
|
||||
HOST_NOT_PRIVILEGED = 1130
|
||||
PASSWORD_ANONYMOUS_USER = 1131
|
||||
PASSWORD_NOT_ALLOWED = 1132
|
||||
PASSWORD_NO_MATCH = 1133
|
||||
UPDATE_INFO = 1134
|
||||
CANT_CREATE_THREAD = 1135
|
||||
WRONG_VALUE_COUNT_ON_ROW = 1136
|
||||
CANT_REOPEN_TABLE = 1137
|
||||
INVALID_USE_OF_NULL = 1138
|
||||
REGEXP_ERROR = 1139
|
||||
MIX_OF_GROUP_FUNC_AND_FIELDS = 1140
|
||||
NONEXISTING_GRANT = 1141
|
||||
TABLEACCESS_DENIED_ERROR = 1142
|
||||
COLUMNACCESS_DENIED_ERROR = 1143
|
||||
ILLEGAL_GRANT_FOR_TABLE = 1144
|
||||
GRANT_WRONG_HOST_OR_USER = 1145
|
||||
NO_SUCH_TABLE = 1146
|
||||
NONEXISTING_TABLE_GRANT = 1147
|
||||
NOT_ALLOWED_COMMAND = 1148
|
||||
SYNTAX_ERROR = 1149
|
||||
DELAYED_CANT_CHANGE_LOCK = 1150
|
||||
TOO_MANY_DELAYED_THREADS = 1151
|
||||
ABORTING_CONNECTION = 1152
|
||||
NET_PACKET_TOO_LARGE = 1153
|
||||
NET_READ_ERROR_FROM_PIPE = 1154
|
||||
NET_FCNTL_ERROR = 1155
|
||||
NET_PACKETS_OUT_OF_ORDER = 1156
|
||||
NET_UNCOMPRESS_ERROR = 1157
|
||||
NET_READ_ERROR = 1158
|
||||
NET_READ_INTERRUPTED = 1159
|
||||
NET_ERROR_ON_WRITE = 1160
|
||||
NET_WRITE_INTERRUPTED = 1161
|
||||
TOO_LONG_STRING = 1162
|
||||
TABLE_CANT_HANDLE_BLOB = 1163
|
||||
TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164
|
||||
DELAYED_INSERT_TABLE_LOCKED = 1165
|
||||
WRONG_COLUMN_NAME = 1166
|
||||
WRONG_KEY_COLUMN = 1167
|
||||
WRONG_MRG_TABLE = 1168
|
||||
DUP_UNIQUE = 1169
|
||||
BLOB_KEY_WITHOUT_LENGTH = 1170
|
||||
PRIMARY_CANT_HAVE_NULL = 1171
|
||||
TOO_MANY_ROWS = 1172
|
||||
REQUIRES_PRIMARY_KEY = 1173
|
||||
NO_RAID_COMPILED = 1174
|
||||
UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175
|
||||
KEY_DOES_NOT_EXITS = 1176
|
||||
CHECK_NO_SUCH_TABLE = 1177
|
||||
CHECK_NOT_IMPLEMENTED = 1178
|
||||
CANT_DO_THIS_DURING_AN_TRANSACTION = 1179
|
||||
ERROR_DURING_COMMIT = 1180
|
||||
ERROR_DURING_ROLLBACK = 1181
|
||||
ERROR_DURING_FLUSH_LOGS = 1182
|
||||
ERROR_DURING_CHECKPOINT = 1183
|
||||
NEW_ABORTING_CONNECTION = 1184
|
||||
DUMP_NOT_IMPLEMENTED = 1185
|
||||
FLUSH_MASTER_BINLOG_CLOSED = 1186
|
||||
INDEX_REBUILD = 1187
|
||||
MASTER = 1188
|
||||
MASTER_NET_READ = 1189
|
||||
MASTER_NET_WRITE = 1190
|
||||
FT_MATCHING_KEY_NOT_FOUND = 1191
|
||||
LOCK_OR_ACTIVE_TRANSACTION = 1192
|
||||
UNKNOWN_SYSTEM_VARIABLE = 1193
|
||||
CRASHED_ON_USAGE = 1194
|
||||
CRASHED_ON_REPAIR = 1195
|
||||
WARNING_NOT_COMPLETE_ROLLBACK = 1196
|
||||
TRANS_CACHE_FULL = 1197
|
||||
SLAVE_MUST_STOP = 1198
|
||||
SLAVE_NOT_RUNNING = 1199
|
||||
BAD_SLAVE = 1200
|
||||
MASTER_INFO = 1201
|
||||
SLAVE_THREAD = 1202
|
||||
TOO_MANY_USER_CONNECTIONS = 1203
|
||||
SET_CONSTANTS_ONLY = 1204
|
||||
LOCK_WAIT_TIMEOUT = 1205
|
||||
LOCK_TABLE_FULL = 1206
|
||||
READ_ONLY_TRANSACTION = 1207
|
||||
DROP_DB_WITH_READ_LOCK = 1208
|
||||
CREATE_DB_WITH_READ_LOCK = 1209
|
||||
WRONG_ARGUMENTS = 1210
|
||||
NO_PERMISSION_TO_CREATE_USER = 1211
|
||||
UNION_TABLES_IN_DIFFERENT_DIR = 1212
|
||||
LOCK_DEADLOCK = 1213
|
||||
TABLE_CANT_HANDLE_FT = 1214
|
||||
CANNOT_ADD_FOREIGN = 1215
|
||||
NO_REFERENCED_ROW = 1216
|
||||
ROW_IS_REFERENCED = 1217
|
||||
CONNECT_TO_MASTER = 1218
|
||||
QUERY_ON_MASTER = 1219
|
||||
ERROR_WHEN_EXECUTING_COMMAND = 1220
|
||||
WRONG_USAGE = 1221
|
||||
WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222
|
||||
CANT_UPDATE_WITH_READLOCK = 1223
|
||||
MIXING_NOT_ALLOWED = 1224
|
||||
DUP_ARGUMENT = 1225
|
||||
USER_LIMIT_REACHED = 1226
|
||||
SPECIFIC_ACCESS_DENIED_ERROR = 1227
|
||||
LOCAL_VARIABLE = 1228
|
||||
GLOBAL_VARIABLE = 1229
|
||||
NO_DEFAULT = 1230
|
||||
WRONG_VALUE_FOR_VAR = 1231
|
||||
WRONG_TYPE_FOR_VAR = 1232
|
||||
VAR_CANT_BE_READ = 1233
|
||||
CANT_USE_OPTION_HERE = 1234
|
||||
NOT_SUPPORTED_YET = 1235
|
||||
MASTER_FATAL_ERROR_READING_BINLOG = 1236
|
||||
SLAVE_IGNORED_TABLE = 1237
|
||||
INCORRECT_GLOBAL_LOCAL_VAR = 1238
|
||||
WRONG_FK_DEF = 1239
|
||||
KEY_REF_DO_NOT_MATCH_TABLE_REF = 1240
|
||||
OPERAND_COLUMNS = 1241
|
||||
SUBQUERY_NO_1_ROW = 1242
|
||||
UNKNOWN_STMT_HANDLER = 1243
|
||||
CORRUPT_HELP_DB = 1244
|
||||
CYCLIC_REFERENCE = 1245
|
||||
AUTO_CONVERT = 1246
|
||||
ILLEGAL_REFERENCE = 1247
|
||||
DERIVED_MUST_HAVE_ALIAS = 1248
|
||||
SELECT_REDUCED = 1249
|
||||
TABLENAME_NOT_ALLOWED_HERE = 1250
|
||||
NOT_SUPPORTED_AUTH_MODE = 1251
|
||||
SPATIAL_CANT_HAVE_NULL = 1252
|
||||
COLLATION_CHARSET_MISMATCH = 1253
|
||||
SLAVE_WAS_RUNNING = 1254
|
||||
SLAVE_WAS_NOT_RUNNING = 1255
|
||||
TOO_BIG_FOR_UNCOMPRESS = 1256
|
||||
ZLIB_Z_MEM_ERROR = 1257
|
||||
ZLIB_Z_BUF_ERROR = 1258
|
||||
ZLIB_Z_DATA_ERROR = 1259
|
||||
CUT_VALUE_GROUP_CONCAT = 1260
|
||||
WARN_TOO_FEW_RECORDS = 1261
|
||||
WARN_TOO_MANY_RECORDS = 1262
|
||||
WARN_NULL_TO_NOTNULL = 1263
|
||||
WARN_DATA_OUT_OF_RANGE = 1264
|
||||
WARN_DATA_TRUNCATED = 1265
|
||||
WARN_USING_OTHER_HANDLER = 1266
|
||||
CANT_AGGREGATE_2COLLATIONS = 1267
|
||||
DROP_USER = 1268
|
||||
REVOKE_GRANTS = 1269
|
||||
CANT_AGGREGATE_3COLLATIONS = 1270
|
||||
CANT_AGGREGATE_NCOLLATIONS = 1271
|
||||
VARIABLE_IS_NOT_STRUCT = 1272
|
||||
UNKNOWN_COLLATION = 1273
|
||||
SLAVE_IGNORED_SSL_PARAMS = 1274
|
||||
SERVER_IS_IN_SECURE_AUTH_MODE = 1275
|
||||
WARN_FIELD_RESOLVED = 1276
|
||||
BAD_SLAVE_UNTIL_COND = 1277
|
||||
MISSING_SKIP_SLAVE = 1278
|
||||
UNTIL_COND_IGNORED = 1279
|
||||
WRONG_NAME_FOR_INDEX = 1280
|
||||
WRONG_NAME_FOR_CATALOG = 1281
|
||||
WARN_QC_RESIZE = 1282
|
||||
BAD_FT_COLUMN = 1283
|
||||
UNKNOWN_KEY_CACHE = 1284
|
||||
WARN_HOSTNAME_WONT_WORK = 1285
|
||||
UNKNOWN_STORAGE_ENGINE = 1286
|
||||
WARN_DEPRECATED_SYNTAX = 1287
|
||||
NON_UPDATABLE_TABLE = 1288
|
||||
FEATURE_DISABLED = 1289
|
||||
OPTION_PREVENTS_STATEMENT = 1290
|
||||
DUPLICATED_VALUE_IN_TYPE = 1291
|
||||
TRUNCATED_WRONG_VALUE = 1292
|
||||
TOO_MUCH_AUTO_TIMESTAMP_COLS = 1293
|
||||
INVALID_ON_UPDATE = 1294
|
||||
UNSUPPORTED_PS = 1295
|
||||
GET_ERRMSG = 1296
|
||||
GET_TEMPORARY_ERRMSG = 1297
|
||||
UNKNOWN_TIME_ZONE = 1298
|
||||
WARN_INVALID_TIMESTAMP = 1299
|
||||
INVALID_CHARACTER_STRING = 1300
|
||||
WARN_ALLOWED_PACKET_OVERFLOWED = 1301
|
||||
CONFLICTING_DECLARATIONS = 1302
|
||||
SP_NO_RECURSIVE_CREATE = 1303
|
||||
SP_ALREADY_EXISTS = 1304
|
||||
SP_DOES_NOT_EXIST = 1305
|
||||
SP_DROP_FAILED = 1306
|
||||
SP_STORE_FAILED = 1307
|
||||
SP_LILABEL_MISMATCH = 1308
|
||||
SP_LABEL_REDEFINE = 1309
|
||||
SP_LABEL_MISMATCH = 1310
|
||||
SP_UNINIT_VAR = 1311
|
||||
SP_BADSELECT = 1312
|
||||
SP_BADRETURN = 1313
|
||||
SP_BADSTATEMENT = 1314
|
||||
UPDATE_LOG_DEPRECATED_IGNORED = 1315
|
||||
UPDATE_LOG_DEPRECATED_TRANSLATED = 1316
|
||||
QUERY_INTERRUPTED = 1317
|
||||
SP_WRONG_NO_OF_ARGS = 1318
|
||||
SP_COND_MISMATCH = 1319
|
||||
SP_NORETURN = 1320
|
||||
SP_NORETURNEND = 1321
|
||||
SP_BAD_CURSOR_QUERY = 1322
|
||||
SP_BAD_CURSOR_SELECT = 1323
|
||||
SP_CURSOR_MISMATCH = 1324
|
||||
SP_CURSOR_ALREADY_OPEN = 1325
|
||||
SP_CURSOR_NOT_OPEN = 1326
|
||||
SP_UNDECLARED_VAR = 1327
|
||||
SP_WRONG_NO_OF_FETCH_ARGS = 1328
|
||||
SP_FETCH_NO_DATA = 1329
|
||||
SP_DUP_PARAM = 1330
|
||||
SP_DUP_VAR = 1331
|
||||
SP_DUP_COND = 1332
|
||||
SP_DUP_CURS = 1333
|
||||
SP_CANT_ALTER = 1334
|
||||
SP_SUBSELECT_NYI = 1335
|
||||
STMT_NOT_ALLOWED_IN_SF_OR_TRG = 1336
|
||||
SP_VARCOND_AFTER_CURSHNDLR = 1337
|
||||
SP_CURSOR_AFTER_HANDLER = 1338
|
||||
SP_CASE_NOT_FOUND = 1339
|
||||
FPARSER_TOO_BIG_FILE = 1340
|
||||
FPARSER_BAD_HEADER = 1341
|
||||
FPARSER_EOF_IN_COMMENT = 1342
|
||||
FPARSER_ERROR_IN_PARAMETER = 1343
|
||||
FPARSER_EOF_IN_UNKNOWN_PARAMETER = 1344
|
||||
VIEW_NO_EXPLAIN = 1345
|
||||
FRM_UNKNOWN_TYPE = 1346
|
||||
WRONG_OBJECT = 1347
|
||||
NONUPDATEABLE_COLUMN = 1348
|
||||
VIEW_SELECT_DERIVED = 1349
|
||||
VIEW_SELECT_CLAUSE = 1350
|
||||
VIEW_SELECT_VARIABLE = 1351
|
||||
VIEW_SELECT_TMPTABLE = 1352
|
||||
VIEW_WRONG_LIST = 1353
|
||||
WARN_VIEW_MERGE = 1354
|
||||
WARN_VIEW_WITHOUT_KEY = 1355
|
||||
VIEW_INVALID = 1356
|
||||
SP_NO_DROP_SP = 1357
|
||||
SP_GOTO_IN_HNDLR = 1358
|
||||
TRG_ALREADY_EXISTS = 1359
|
||||
TRG_DOES_NOT_EXIST = 1360
|
||||
TRG_ON_VIEW_OR_TEMP_TABLE = 1361
|
||||
TRG_CANT_CHANGE_ROW = 1362
|
||||
TRG_NO_SUCH_ROW_IN_TRG = 1363
|
||||
NO_DEFAULT_FOR_FIELD = 1364
|
||||
DIVISION_BY_ZERO = 1365
|
||||
TRUNCATED_WRONG_VALUE_FOR_FIELD = 1366
|
||||
ILLEGAL_VALUE_FOR_TYPE = 1367
|
||||
VIEW_NONUPD_CHECK = 1368
|
||||
VIEW_CHECK_FAILED = 1369
|
||||
PROCACCESS_DENIED_ERROR = 1370
|
||||
RELAY_LOG_FAIL = 1371
|
||||
PASSWD_LENGTH = 1372
|
||||
UNKNOWN_TARGET_BINLOG = 1373
|
||||
IO_ERR_LOG_INDEX_READ = 1374
|
||||
BINLOG_PURGE_PROHIBITED = 1375
|
||||
FSEEK_FAIL = 1376
|
||||
BINLOG_PURGE_FATAL_ERR = 1377
|
||||
LOG_IN_USE = 1378
|
||||
LOG_PURGE_UNKNOWN_ERR = 1379
|
||||
RELAY_LOG_INIT = 1380
|
||||
NO_BINARY_LOGGING = 1381
|
||||
RESERVED_SYNTAX = 1382
|
||||
WSAS_FAILED = 1383
|
||||
DIFF_GROUPS_PROC = 1384
|
||||
NO_GROUP_FOR_PROC = 1385
|
||||
ORDER_WITH_PROC = 1386
|
||||
LOGGING_PROHIBIT_CHANGING_OF = 1387
|
||||
NO_FILE_MAPPING = 1388
|
||||
WRONG_MAGIC = 1389
|
||||
PS_MANY_PARAM = 1390
|
||||
KEY_PART_0 = 1391
|
||||
VIEW_CHECKSUM = 1392
|
||||
VIEW_MULTIUPDATE = 1393
|
||||
VIEW_NO_INSERT_FIELD_LIST = 1394
|
||||
VIEW_DELETE_MERGE_VIEW = 1395
|
||||
CANNOT_USER = 1396
|
||||
XAER_NOTA = 1397
|
||||
XAER_INVAL = 1398
|
||||
XAER_RMFAIL = 1399
|
||||
XAER_OUTSIDE = 1400
|
||||
XAER_RMERR = 1401
|
||||
XA_RBROLLBACK = 1402
|
||||
NONEXISTING_PROC_GRANT = 1403
|
||||
PROC_AUTO_GRANT_FAIL = 1404
|
||||
PROC_AUTO_REVOKE_FAIL = 1405
|
||||
DATA_TOO_LONG = 1406
|
||||
SP_BAD_SQLSTATE = 1407
|
||||
STARTUP = 1408
|
||||
LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR = 1409
|
||||
CANT_CREATE_USER_WITH_GRANT = 1410
|
||||
WRONG_VALUE_FOR_TYPE = 1411
|
||||
TABLE_DEF_CHANGED = 1412
|
||||
SP_DUP_HANDLER = 1413
|
||||
SP_NOT_VAR_ARG = 1414
|
||||
SP_NO_RETSET = 1415
|
||||
CANT_CREATE_GEOMETRY_OBJECT = 1416
|
||||
FAILED_ROUTINE_BREAK_BINLOG = 1417
|
||||
BINLOG_UNSAFE_ROUTINE = 1418
|
||||
BINLOG_CREATE_ROUTINE_NEED_SUPER = 1419
|
||||
EXEC_STMT_WITH_OPEN_CURSOR = 1420
|
||||
STMT_HAS_NO_OPEN_CURSOR = 1421
|
||||
COMMIT_NOT_ALLOWED_IN_SF_OR_TRG = 1422
|
||||
NO_DEFAULT_FOR_VIEW_FIELD = 1423
|
||||
SP_NO_RECURSION = 1424
|
||||
TOO_BIG_SCALE = 1425
|
||||
TOO_BIG_PRECISION = 1426
|
||||
M_BIGGER_THAN_D = 1427
|
||||
WRONG_LOCK_OF_SYSTEM_TABLE = 1428
|
||||
CONNECT_TO_FOREIGN_DATA_SOURCE = 1429
|
||||
QUERY_ON_FOREIGN_DATA_SOURCE = 1430
|
||||
FOREIGN_DATA_SOURCE_DOESNT_EXIST = 1431
|
||||
FOREIGN_DATA_STRING_INVALID_CANT_CREATE = 1432
|
||||
FOREIGN_DATA_STRING_INVALID = 1433
|
||||
CANT_CREATE_FEDERATED_TABLE = 1434
|
||||
TRG_IN_WRONG_SCHEMA = 1435
|
||||
STACK_OVERRUN_NEED_MORE = 1436
|
||||
TOO_LONG_BODY = 1437
|
||||
WARN_CANT_DROP_DEFAULT_KEYCACHE = 1438
|
||||
TOO_BIG_DISPLAYWIDTH = 1439
|
||||
XAER_DUPID = 1440
|
||||
DATETIME_FUNCTION_OVERFLOW = 1441
|
||||
CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG = 1442
|
||||
VIEW_PREVENT_UPDATE = 1443
|
||||
PS_NO_RECURSION = 1444
|
||||
SP_CANT_SET_AUTOCOMMIT = 1445
|
||||
MALFORMED_DEFINER = 1446
|
||||
VIEW_FRM_NO_USER = 1447
|
||||
VIEW_OTHER_USER = 1448
|
||||
NO_SUCH_USER = 1449
|
||||
FORBID_SCHEMA_CHANGE = 1450
|
||||
ROW_IS_REFERENCED_2 = 1451
|
||||
NO_REFERENCED_ROW_2 = 1452
|
||||
SP_BAD_VAR_SHADOW = 1453
|
||||
TRG_NO_DEFINER = 1454
|
||||
OLD_FILE_FORMAT = 1455
|
||||
SP_RECURSION_LIMIT = 1456
|
||||
SP_PROC_TABLE_CORRUPT = 1457
|
||||
SP_WRONG_NAME = 1458
|
||||
TABLE_NEEDS_UPGRADE = 1459
|
||||
SP_NO_AGGREGATE = 1460
|
||||
MAX_PREPARED_STMT_COUNT_REACHED = 1461
|
||||
VIEW_RECURSIVE = 1462
|
||||
NON_GROUPING_FIELD_USED = 1463
|
||||
TABLE_CANT_HANDLE_SPKEYS = 1464
|
||||
NO_TRIGGERS_ON_SYSTEM_SCHEMA = 1465
|
||||
USERNAME = 1466
|
||||
HOSTNAME = 1467
|
||||
WRONG_STRING_LENGTH = 1468
|
||||
ERROR_LAST = 1468
|
||||
|
||||
# https://github.com/PyMySQL/PyMySQL/issues/607
|
||||
CONSTRAINT_FAILED = 4025
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
|
||||
DECIMAL = 0
|
||||
TINY = 1
|
||||
SHORT = 2
|
||||
LONG = 3
|
||||
FLOAT = 4
|
||||
DOUBLE = 5
|
||||
NULL = 6
|
||||
TIMESTAMP = 7
|
||||
LONGLONG = 8
|
||||
INT24 = 9
|
||||
DATE = 10
|
||||
TIME = 11
|
||||
DATETIME = 12
|
||||
YEAR = 13
|
||||
NEWDATE = 14
|
||||
VARCHAR = 15
|
||||
BIT = 16
|
||||
JSON = 245
|
||||
NEWDECIMAL = 246
|
||||
ENUM = 247
|
||||
SET = 248
|
||||
TINY_BLOB = 249
|
||||
MEDIUM_BLOB = 250
|
||||
LONG_BLOB = 251
|
||||
BLOB = 252
|
||||
VAR_STRING = 253
|
||||
STRING = 254
|
||||
GEOMETRY = 255
|
||||
|
||||
CHAR = TINY
|
||||
INTERVAL = ENUM
|
||||
15
venv/lib/python3.9/site-packages/pymysql/constants/FLAG.py
Normal file
15
venv/lib/python3.9/site-packages/pymysql/constants/FLAG.py
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
NOT_NULL = 1
|
||||
PRI_KEY = 2
|
||||
UNIQUE_KEY = 4
|
||||
MULTIPLE_KEY = 8
|
||||
BLOB = 16
|
||||
UNSIGNED = 32
|
||||
ZEROFILL = 64
|
||||
BINARY = 128
|
||||
ENUM = 256
|
||||
AUTO_INCREMENT = 512
|
||||
TIMESTAMP = 1024
|
||||
SET = 2048
|
||||
PART_KEY = 16384
|
||||
GROUP = 32767
|
||||
UNIQUE = 65536
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
SERVER_STATUS_IN_TRANS = 1
|
||||
SERVER_STATUS_AUTOCOMMIT = 2
|
||||
SERVER_MORE_RESULTS_EXISTS = 8
|
||||
SERVER_QUERY_NO_GOOD_INDEX_USED = 16
|
||||
SERVER_QUERY_NO_INDEX_USED = 32
|
||||
SERVER_STATUS_CURSOR_EXISTS = 64
|
||||
SERVER_STATUS_LAST_ROW_SENT = 128
|
||||
SERVER_STATUS_DB_DROPPED = 256
|
||||
SERVER_STATUS_NO_BACKSLASH_ESCAPES = 512
|
||||
SERVER_STATUS_METADATA_CHANGED = 1024
|
||||
380
venv/lib/python3.9/site-packages/pymysql/converters.py
Normal file
380
venv/lib/python3.9/site-packages/pymysql/converters.py
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
from ._compat import PY2, text_type, long_type, JYTHON, IRONPYTHON, unichr
|
||||
|
||||
import datetime
|
||||
from decimal import Decimal
|
||||
import re
|
||||
import time
|
||||
|
||||
from .err import ProgrammingError
|
||||
from .constants import FIELD_TYPE
|
||||
|
||||
|
||||
def escape_item(val, charset, mapping=None):
|
||||
if mapping is None:
|
||||
mapping = encoders
|
||||
encoder = mapping.get(type(val))
|
||||
|
||||
# Fallback to default when no encoder found
|
||||
if not encoder:
|
||||
try:
|
||||
encoder = mapping[text_type]
|
||||
except KeyError:
|
||||
raise TypeError("no default type converter defined")
|
||||
|
||||
if encoder in (escape_dict, escape_sequence):
|
||||
val = encoder(val, charset, mapping)
|
||||
else:
|
||||
val = encoder(val, mapping)
|
||||
return val
|
||||
|
||||
def escape_dict(val, charset, mapping=None):
|
||||
n = {}
|
||||
for k, v in val.items():
|
||||
quoted = escape_item(v, charset, mapping)
|
||||
n[k] = quoted
|
||||
return n
|
||||
|
||||
def escape_sequence(val, charset, mapping=None):
|
||||
n = []
|
||||
for item in val:
|
||||
quoted = escape_item(item, charset, mapping)
|
||||
n.append(quoted)
|
||||
return "(" + ",".join(n) + ")"
|
||||
|
||||
def escape_set(val, charset, mapping=None):
|
||||
return ','.join([escape_item(x, charset, mapping) for x in val])
|
||||
|
||||
def escape_bool(value, mapping=None):
|
||||
return str(int(value))
|
||||
|
||||
def escape_object(value, mapping=None):
|
||||
return str(value)
|
||||
|
||||
def escape_int(value, mapping=None):
|
||||
return str(value)
|
||||
|
||||
def escape_float(value, mapping=None):
|
||||
s = repr(value)
|
||||
if s in ('inf', 'nan'):
|
||||
raise ProgrammingError("%s can not be used with MySQL" % s)
|
||||
if 'e' not in s:
|
||||
s += 'e0'
|
||||
return s
|
||||
|
||||
_escape_table = [unichr(x) for x in range(128)]
|
||||
_escape_table[0] = u'\\0'
|
||||
_escape_table[ord('\\')] = u'\\\\'
|
||||
_escape_table[ord('\n')] = u'\\n'
|
||||
_escape_table[ord('\r')] = u'\\r'
|
||||
_escape_table[ord('\032')] = u'\\Z'
|
||||
_escape_table[ord('"')] = u'\\"'
|
||||
_escape_table[ord("'")] = u"\\'"
|
||||
|
||||
def _escape_unicode(value, mapping=None):
|
||||
"""escapes *value* without adding quote.
|
||||
|
||||
Value should be unicode
|
||||
"""
|
||||
return value.translate(_escape_table)
|
||||
|
||||
if PY2:
|
||||
def escape_string(value, mapping=None):
|
||||
"""escape_string escapes *value* but not surround it with quotes.
|
||||
|
||||
Value should be bytes or unicode.
|
||||
"""
|
||||
if isinstance(value, unicode):
|
||||
return _escape_unicode(value)
|
||||
assert isinstance(value, (bytes, bytearray))
|
||||
value = value.replace('\\', '\\\\')
|
||||
value = value.replace('\0', '\\0')
|
||||
value = value.replace('\n', '\\n')
|
||||
value = value.replace('\r', '\\r')
|
||||
value = value.replace('\032', '\\Z')
|
||||
value = value.replace("'", "\\'")
|
||||
value = value.replace('"', '\\"')
|
||||
return value
|
||||
|
||||
def escape_bytes_prefixed(value, mapping=None):
|
||||
assert isinstance(value, (bytes, bytearray))
|
||||
return b"_binary'%s'" % escape_string(value)
|
||||
|
||||
def escape_bytes(value, mapping=None):
|
||||
assert isinstance(value, (bytes, bytearray))
|
||||
return b"'%s'" % escape_string(value)
|
||||
|
||||
else:
|
||||
escape_string = _escape_unicode
|
||||
|
||||
# On Python ~3.5, str.decode('ascii', 'surrogateescape') is slow.
|
||||
# (fixed in Python 3.6, http://bugs.python.org/issue24870)
|
||||
# Workaround is str.decode('latin1') then translate 0x80-0xff into 0udc80-0udcff.
|
||||
# We can escape special chars and surrogateescape at once.
|
||||
_escape_bytes_table = _escape_table + [chr(i) for i in range(0xdc80, 0xdd00)]
|
||||
|
||||
def escape_bytes_prefixed(value, mapping=None):
|
||||
return "_binary'%s'" % value.decode('latin1').translate(_escape_bytes_table)
|
||||
|
||||
def escape_bytes(value, mapping=None):
|
||||
return "'%s'" % value.decode('latin1').translate(_escape_bytes_table)
|
||||
|
||||
|
||||
def escape_unicode(value, mapping=None):
|
||||
return u"'%s'" % _escape_unicode(value)
|
||||
|
||||
def escape_str(value, mapping=None):
|
||||
return "'%s'" % escape_string(str(value), mapping)
|
||||
|
||||
def escape_None(value, mapping=None):
|
||||
return 'NULL'
|
||||
|
||||
def escape_timedelta(obj, mapping=None):
|
||||
seconds = int(obj.seconds) % 60
|
||||
minutes = int(obj.seconds // 60) % 60
|
||||
hours = int(obj.seconds // 3600) % 24 + int(obj.days) * 24
|
||||
if obj.microseconds:
|
||||
fmt = "'{0:02d}:{1:02d}:{2:02d}.{3:06d}'"
|
||||
else:
|
||||
fmt = "'{0:02d}:{1:02d}:{2:02d}'"
|
||||
return fmt.format(hours, minutes, seconds, obj.microseconds)
|
||||
|
||||
def escape_time(obj, mapping=None):
|
||||
if obj.microsecond:
|
||||
fmt = "'{0.hour:02}:{0.minute:02}:{0.second:02}.{0.microsecond:06}'"
|
||||
else:
|
||||
fmt = "'{0.hour:02}:{0.minute:02}:{0.second:02}'"
|
||||
return fmt.format(obj)
|
||||
|
||||
def escape_datetime(obj, mapping=None):
|
||||
if obj.microsecond:
|
||||
fmt = "'{0.year:04}-{0.month:02}-{0.day:02} {0.hour:02}:{0.minute:02}:{0.second:02}.{0.microsecond:06}'"
|
||||
else:
|
||||
fmt = "'{0.year:04}-{0.month:02}-{0.day:02} {0.hour:02}:{0.minute:02}:{0.second:02}'"
|
||||
return fmt.format(obj)
|
||||
|
||||
def escape_date(obj, mapping=None):
|
||||
fmt = "'{0.year:04}-{0.month:02}-{0.day:02}'"
|
||||
return fmt.format(obj)
|
||||
|
||||
def escape_struct_time(obj, mapping=None):
|
||||
return escape_datetime(datetime.datetime(*obj[:6]))
|
||||
|
||||
|
||||
def Decimal2Literal(o, d):
|
||||
return format(o, "f")
|
||||
|
||||
|
||||
def _convert_second_fraction(s):
|
||||
if not s:
|
||||
return 0
|
||||
# Pad zeros to ensure the fraction length in microseconds
|
||||
s = s.ljust(6, '0')
|
||||
return int(s[:6])
|
||||
|
||||
DATETIME_RE = re.compile(r"(\d{1,4})-(\d{1,2})-(\d{1,2})[T ](\d{1,2}):(\d{1,2}):(\d{1,2})(?:.(\d{1,6}))?")
|
||||
|
||||
|
||||
def convert_datetime(obj):
|
||||
"""Returns a DATETIME or TIMESTAMP column value as a datetime object:
|
||||
|
||||
>>> datetime_or_None('2007-02-25 23:06:20')
|
||||
datetime.datetime(2007, 2, 25, 23, 6, 20)
|
||||
>>> datetime_or_None('2007-02-25T23:06:20')
|
||||
datetime.datetime(2007, 2, 25, 23, 6, 20)
|
||||
|
||||
Illegal values are returned as None:
|
||||
|
||||
>>> datetime_or_None('2007-02-31T23:06:20') is None
|
||||
True
|
||||
>>> datetime_or_None('0000-00-00 00:00:00') is None
|
||||
True
|
||||
|
||||
"""
|
||||
if not PY2 and isinstance(obj, (bytes, bytearray)):
|
||||
obj = obj.decode('ascii')
|
||||
|
||||
m = DATETIME_RE.match(obj)
|
||||
if not m:
|
||||
return convert_date(obj)
|
||||
|
||||
try:
|
||||
groups = list(m.groups())
|
||||
groups[-1] = _convert_second_fraction(groups[-1])
|
||||
return datetime.datetime(*[ int(x) for x in groups ])
|
||||
except ValueError:
|
||||
return convert_date(obj)
|
||||
|
||||
TIMEDELTA_RE = re.compile(r"(-)?(\d{1,3}):(\d{1,2}):(\d{1,2})(?:.(\d{1,6}))?")
|
||||
|
||||
|
||||
def convert_timedelta(obj):
|
||||
"""Returns a TIME column as a timedelta object:
|
||||
|
||||
>>> timedelta_or_None('25:06:17')
|
||||
datetime.timedelta(1, 3977)
|
||||
>>> timedelta_or_None('-25:06:17')
|
||||
datetime.timedelta(-2, 83177)
|
||||
|
||||
Illegal values are returned as None:
|
||||
|
||||
>>> timedelta_or_None('random crap') is None
|
||||
True
|
||||
|
||||
Note that MySQL always returns TIME columns as (+|-)HH:MM:SS, but
|
||||
can accept values as (+|-)DD HH:MM:SS. The latter format will not
|
||||
be parsed correctly by this function.
|
||||
"""
|
||||
if not PY2 and isinstance(obj, (bytes, bytearray)):
|
||||
obj = obj.decode('ascii')
|
||||
|
||||
m = TIMEDELTA_RE.match(obj)
|
||||
if not m:
|
||||
return obj
|
||||
|
||||
try:
|
||||
groups = list(m.groups())
|
||||
groups[-1] = _convert_second_fraction(groups[-1])
|
||||
negate = -1 if groups[0] else 1
|
||||
hours, minutes, seconds, microseconds = groups[1:]
|
||||
|
||||
tdelta = datetime.timedelta(
|
||||
hours = int(hours),
|
||||
minutes = int(minutes),
|
||||
seconds = int(seconds),
|
||||
microseconds = int(microseconds)
|
||||
) * negate
|
||||
return tdelta
|
||||
except ValueError:
|
||||
return obj
|
||||
|
||||
TIME_RE = re.compile(r"(\d{1,2}):(\d{1,2}):(\d{1,2})(?:.(\d{1,6}))?")
|
||||
|
||||
|
||||
def convert_time(obj):
|
||||
"""Returns a TIME column as a time object:
|
||||
|
||||
>>> time_or_None('15:06:17')
|
||||
datetime.time(15, 6, 17)
|
||||
|
||||
Illegal values are returned as None:
|
||||
|
||||
>>> time_or_None('-25:06:17') is None
|
||||
True
|
||||
>>> time_or_None('random crap') is None
|
||||
True
|
||||
|
||||
Note that MySQL always returns TIME columns as (+|-)HH:MM:SS, but
|
||||
can accept values as (+|-)DD HH:MM:SS. The latter format will not
|
||||
be parsed correctly by this function.
|
||||
|
||||
Also note that MySQL's TIME column corresponds more closely to
|
||||
Python's timedelta and not time. However if you want TIME columns
|
||||
to be treated as time-of-day and not a time offset, then you can
|
||||
use set this function as the converter for FIELD_TYPE.TIME.
|
||||
"""
|
||||
if not PY2 and isinstance(obj, (bytes, bytearray)):
|
||||
obj = obj.decode('ascii')
|
||||
|
||||
m = TIME_RE.match(obj)
|
||||
if not m:
|
||||
return obj
|
||||
|
||||
try:
|
||||
groups = list(m.groups())
|
||||
groups[-1] = _convert_second_fraction(groups[-1])
|
||||
hours, minutes, seconds, microseconds = groups
|
||||
return datetime.time(hour=int(hours), minute=int(minutes),
|
||||
second=int(seconds), microsecond=int(microseconds))
|
||||
except ValueError:
|
||||
return obj
|
||||
|
||||
|
||||
def convert_date(obj):
|
||||
"""Returns a DATE column as a date object:
|
||||
|
||||
>>> date_or_None('2007-02-26')
|
||||
datetime.date(2007, 2, 26)
|
||||
|
||||
Illegal values are returned as None:
|
||||
|
||||
>>> date_or_None('2007-02-31') is None
|
||||
True
|
||||
>>> date_or_None('0000-00-00') is None
|
||||
True
|
||||
|
||||
"""
|
||||
if not PY2 and isinstance(obj, (bytes, bytearray)):
|
||||
obj = obj.decode('ascii')
|
||||
try:
|
||||
return datetime.date(*[ int(x) for x in obj.split('-', 2) ])
|
||||
except ValueError:
|
||||
return obj
|
||||
|
||||
|
||||
def through(x):
|
||||
return x
|
||||
|
||||
|
||||
#def convert_bit(b):
|
||||
# b = "\x00" * (8 - len(b)) + b # pad w/ zeroes
|
||||
# return struct.unpack(">Q", b)[0]
|
||||
#
|
||||
# the snippet above is right, but MySQLdb doesn't process bits,
|
||||
# so we shouldn't either
|
||||
convert_bit = through
|
||||
|
||||
|
||||
encoders = {
|
||||
bool: escape_bool,
|
||||
int: escape_int,
|
||||
long_type: escape_int,
|
||||
float: escape_float,
|
||||
str: escape_str,
|
||||
text_type: escape_unicode,
|
||||
tuple: escape_sequence,
|
||||
list: escape_sequence,
|
||||
set: escape_sequence,
|
||||
frozenset: escape_sequence,
|
||||
dict: escape_dict,
|
||||
type(None): escape_None,
|
||||
datetime.date: escape_date,
|
||||
datetime.datetime: escape_datetime,
|
||||
datetime.timedelta: escape_timedelta,
|
||||
datetime.time: escape_time,
|
||||
time.struct_time: escape_struct_time,
|
||||
Decimal: Decimal2Literal,
|
||||
}
|
||||
|
||||
if not PY2 or JYTHON or IRONPYTHON:
|
||||
encoders[bytes] = escape_bytes
|
||||
|
||||
decoders = {
|
||||
FIELD_TYPE.BIT: convert_bit,
|
||||
FIELD_TYPE.TINY: int,
|
||||
FIELD_TYPE.SHORT: int,
|
||||
FIELD_TYPE.LONG: int,
|
||||
FIELD_TYPE.FLOAT: float,
|
||||
FIELD_TYPE.DOUBLE: float,
|
||||
FIELD_TYPE.LONGLONG: int,
|
||||
FIELD_TYPE.INT24: int,
|
||||
FIELD_TYPE.YEAR: int,
|
||||
FIELD_TYPE.TIMESTAMP: convert_datetime,
|
||||
FIELD_TYPE.DATETIME: convert_datetime,
|
||||
FIELD_TYPE.TIME: convert_timedelta,
|
||||
FIELD_TYPE.DATE: convert_date,
|
||||
FIELD_TYPE.BLOB: through,
|
||||
FIELD_TYPE.TINY_BLOB: through,
|
||||
FIELD_TYPE.MEDIUM_BLOB: through,
|
||||
FIELD_TYPE.LONG_BLOB: through,
|
||||
FIELD_TYPE.STRING: through,
|
||||
FIELD_TYPE.VAR_STRING: through,
|
||||
FIELD_TYPE.VARCHAR: through,
|
||||
FIELD_TYPE.DECIMAL: Decimal,
|
||||
FIELD_TYPE.NEWDECIMAL: Decimal,
|
||||
}
|
||||
|
||||
|
||||
# for MySQLdb compatibility
|
||||
conversions = encoders.copy()
|
||||
conversions.update(decoders)
|
||||
Thing2Literal = escape_str
|
||||
505
venv/lib/python3.9/site-packages/pymysql/cursors.py
Normal file
505
venv/lib/python3.9/site-packages/pymysql/cursors.py
Normal file
|
|
@ -0,0 +1,505 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import print_function, absolute_import
|
||||
from functools import partial
|
||||
import re
|
||||
|
||||
from ._compat import range_type, text_type, PY2
|
||||
from . import err
|
||||
|
||||
|
||||
#: Regular expression for :meth:`Cursor.executemany`.
|
||||
#: executemany only supports simple bulk insert.
|
||||
#: You can use it to load large dataset.
|
||||
RE_INSERT_VALUES = re.compile(
|
||||
r"\s*((?:INSERT|REPLACE)\b.+\bVALUES?\s*)" +
|
||||
r"(\(\s*(?:%s|%\(.+\)s)\s*(?:,\s*(?:%s|%\(.+\)s)\s*)*\))" +
|
||||
r"(\s*(?:ON DUPLICATE.*)?);?\s*\Z",
|
||||
re.IGNORECASE | re.DOTALL)
|
||||
|
||||
|
||||
class Cursor(object):
|
||||
"""
|
||||
This is the object you use to interact with the database.
|
||||
|
||||
Do not create an instance of a Cursor yourself. Call
|
||||
connections.Connection.cursor().
|
||||
|
||||
See `Cursor <https://www.python.org/dev/peps/pep-0249/#cursor-objects>`_ in
|
||||
the specification.
|
||||
"""
|
||||
|
||||
#: Max statement size which :meth:`executemany` generates.
|
||||
#:
|
||||
#: Max size of allowed statement is max_allowed_packet - packet_header_size.
|
||||
#: Default value of max_allowed_packet is 1048576.
|
||||
max_stmt_length = 1024000
|
||||
|
||||
def __init__(self, connection):
|
||||
self.connection = connection
|
||||
self.description = None
|
||||
self.rownumber = 0
|
||||
self.rowcount = -1
|
||||
self.arraysize = 1
|
||||
self._executed = None
|
||||
self._result = None
|
||||
self._rows = None
|
||||
|
||||
def close(self):
|
||||
"""
|
||||
Closing a cursor just exhausts all remaining data.
|
||||
"""
|
||||
conn = self.connection
|
||||
if conn is None:
|
||||
return
|
||||
try:
|
||||
while self.nextset():
|
||||
pass
|
||||
finally:
|
||||
self.connection = None
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, *exc_info):
|
||||
del exc_info
|
||||
self.close()
|
||||
|
||||
def _get_db(self):
|
||||
if not self.connection:
|
||||
raise err.ProgrammingError("Cursor closed")
|
||||
return self.connection
|
||||
|
||||
def _check_executed(self):
|
||||
if not self._executed:
|
||||
raise err.ProgrammingError("execute() first")
|
||||
|
||||
def _conv_row(self, row):
|
||||
return row
|
||||
|
||||
def setinputsizes(self, *args):
|
||||
"""Does nothing, required by DB API."""
|
||||
|
||||
def setoutputsizes(self, *args):
|
||||
"""Does nothing, required by DB API."""
|
||||
|
||||
def _nextset(self, unbuffered=False):
|
||||
"""Get the next query set"""
|
||||
conn = self._get_db()
|
||||
current_result = self._result
|
||||
if current_result is None or current_result is not conn._result:
|
||||
return None
|
||||
if not current_result.has_next:
|
||||
return None
|
||||
self._result = None
|
||||
self._clear_result()
|
||||
conn.next_result(unbuffered=unbuffered)
|
||||
self._do_get_result()
|
||||
return True
|
||||
|
||||
def nextset(self):
|
||||
return self._nextset(False)
|
||||
|
||||
def _ensure_bytes(self, x, encoding=None):
|
||||
if isinstance(x, text_type):
|
||||
x = x.encode(encoding)
|
||||
elif isinstance(x, (tuple, list)):
|
||||
x = type(x)(self._ensure_bytes(v, encoding=encoding) for v in x)
|
||||
return x
|
||||
|
||||
def _escape_args(self, args, conn):
|
||||
ensure_bytes = partial(self._ensure_bytes, encoding=conn.encoding)
|
||||
|
||||
if isinstance(args, (tuple, list)):
|
||||
if PY2:
|
||||
args = tuple(map(ensure_bytes, args))
|
||||
return tuple(conn.literal(arg) for arg in args)
|
||||
elif isinstance(args, dict):
|
||||
if PY2:
|
||||
args = {ensure_bytes(key): ensure_bytes(val) for
|
||||
(key, val) in args.items()}
|
||||
return {key: conn.literal(val) for (key, val) in args.items()}
|
||||
else:
|
||||
# If it's not a dictionary let's try escaping it anyways.
|
||||
# Worst case it will throw a Value error
|
||||
if PY2:
|
||||
args = ensure_bytes(args)
|
||||
return conn.escape(args)
|
||||
|
||||
def mogrify(self, query, args=None):
|
||||
"""
|
||||
Returns the exact string that is sent to the database by calling the
|
||||
execute() method.
|
||||
|
||||
This method follows the extension to the DB API 2.0 followed by Psycopg.
|
||||
"""
|
||||
conn = self._get_db()
|
||||
if PY2: # Use bytes on Python 2 always
|
||||
query = self._ensure_bytes(query, encoding=conn.encoding)
|
||||
|
||||
if args is not None:
|
||||
query = query % self._escape_args(args, conn)
|
||||
|
||||
return query
|
||||
|
||||
def execute(self, query, args=None):
|
||||
"""Execute a query
|
||||
|
||||
:param str query: Query to execute.
|
||||
|
||||
:param args: parameters used with query. (optional)
|
||||
:type args: tuple, list or dict
|
||||
|
||||
:return: Number of affected rows
|
||||
:rtype: int
|
||||
|
||||
If args is a list or tuple, %s can be used as a placeholder in the query.
|
||||
If args is a dict, %(name)s can be used as a placeholder in the query.
|
||||
"""
|
||||
while self.nextset():
|
||||
pass
|
||||
|
||||
query = self.mogrify(query, args)
|
||||
|
||||
result = self._query(query)
|
||||
self._executed = query
|
||||
return result
|
||||
|
||||
def executemany(self, query, args):
|
||||
# type: (str, list) -> int
|
||||
"""Run several data against one query
|
||||
|
||||
:param query: query to execute on server
|
||||
:param args: Sequence of sequences or mappings. It is used as parameter.
|
||||
:return: Number of rows affected, if any.
|
||||
|
||||
This method improves performance on multiple-row INSERT and
|
||||
REPLACE. Otherwise it is equivalent to looping over args with
|
||||
execute().
|
||||
"""
|
||||
if not args:
|
||||
return
|
||||
|
||||
m = RE_INSERT_VALUES.match(query)
|
||||
if m:
|
||||
q_prefix = m.group(1) % ()
|
||||
q_values = m.group(2).rstrip()
|
||||
q_postfix = m.group(3) or ''
|
||||
assert q_values[0] == '(' and q_values[-1] == ')'
|
||||
return self._do_execute_many(q_prefix, q_values, q_postfix, args,
|
||||
self.max_stmt_length,
|
||||
self._get_db().encoding)
|
||||
|
||||
self.rowcount = sum(self.execute(query, arg) for arg in args)
|
||||
return self.rowcount
|
||||
|
||||
def _do_execute_many(self, prefix, values, postfix, args, max_stmt_length, encoding):
|
||||
conn = self._get_db()
|
||||
escape = self._escape_args
|
||||
if isinstance(prefix, text_type):
|
||||
prefix = prefix.encode(encoding)
|
||||
if PY2 and isinstance(values, text_type):
|
||||
values = values.encode(encoding)
|
||||
if isinstance(postfix, text_type):
|
||||
postfix = postfix.encode(encoding)
|
||||
sql = bytearray(prefix)
|
||||
args = iter(args)
|
||||
v = values % escape(next(args), conn)
|
||||
if isinstance(v, text_type):
|
||||
if PY2:
|
||||
v = v.encode(encoding)
|
||||
else:
|
||||
v = v.encode(encoding, 'surrogateescape')
|
||||
sql += v
|
||||
rows = 0
|
||||
for arg in args:
|
||||
v = values % escape(arg, conn)
|
||||
if isinstance(v, text_type):
|
||||
if PY2:
|
||||
v = v.encode(encoding)
|
||||
else:
|
||||
v = v.encode(encoding, 'surrogateescape')
|
||||
if len(sql) + len(v) + len(postfix) + 1 > max_stmt_length:
|
||||
rows += self.execute(sql + postfix)
|
||||
sql = bytearray(prefix)
|
||||
else:
|
||||
sql += b','
|
||||
sql += v
|
||||
rows += self.execute(sql + postfix)
|
||||
self.rowcount = rows
|
||||
return rows
|
||||
|
||||
def callproc(self, procname, args=()):
|
||||
"""Execute stored procedure procname with args
|
||||
|
||||
procname -- string, name of procedure to execute on server
|
||||
|
||||
args -- Sequence of parameters to use with procedure
|
||||
|
||||
Returns the original args.
|
||||
|
||||
Compatibility warning: PEP-249 specifies that any modified
|
||||
parameters must be returned. This is currently impossible
|
||||
as they are only available by storing them in a server
|
||||
variable and then retrieved by a query. Since stored
|
||||
procedures return zero or more result sets, there is no
|
||||
reliable way to get at OUT or INOUT parameters via callproc.
|
||||
The server variables are named @_procname_n, where procname
|
||||
is the parameter above and n is the position of the parameter
|
||||
(from zero). Once all result sets generated by the procedure
|
||||
have been fetched, you can issue a SELECT @_procname_0, ...
|
||||
query using .execute() to get any OUT or INOUT values.
|
||||
|
||||
Compatibility warning: The act of calling a stored procedure
|
||||
itself creates an empty result set. This appears after any
|
||||
result sets generated by the procedure. This is non-standard
|
||||
behavior with respect to the DB-API. Be sure to use nextset()
|
||||
to advance through all result sets; otherwise you may get
|
||||
disconnected.
|
||||
"""
|
||||
conn = self._get_db()
|
||||
if args:
|
||||
fmt = '@_{0}_%d=%s'.format(procname)
|
||||
self._query('SET %s' % ','.join(fmt % (index, conn.escape(arg))
|
||||
for index, arg in enumerate(args)))
|
||||
self.nextset()
|
||||
|
||||
q = "CALL %s(%s)" % (procname,
|
||||
','.join(['@_%s_%d' % (procname, i)
|
||||
for i in range_type(len(args))]))
|
||||
self._query(q)
|
||||
self._executed = q
|
||||
return args
|
||||
|
||||
def fetchone(self):
|
||||
"""Fetch the next row"""
|
||||
self._check_executed()
|
||||
if self._rows is None or self.rownumber >= len(self._rows):
|
||||
return None
|
||||
result = self._rows[self.rownumber]
|
||||
self.rownumber += 1
|
||||
return result
|
||||
|
||||
def fetchmany(self, size=None):
|
||||
"""Fetch several rows"""
|
||||
self._check_executed()
|
||||
if self._rows is None:
|
||||
return ()
|
||||
end = self.rownumber + (size or self.arraysize)
|
||||
result = self._rows[self.rownumber:end]
|
||||
self.rownumber = min(end, len(self._rows))
|
||||
return result
|
||||
|
||||
def fetchall(self):
|
||||
"""Fetch all the rows"""
|
||||
self._check_executed()
|
||||
if self._rows is None:
|
||||
return ()
|
||||
if self.rownumber:
|
||||
result = self._rows[self.rownumber:]
|
||||
else:
|
||||
result = self._rows
|
||||
self.rownumber = len(self._rows)
|
||||
return result
|
||||
|
||||
def scroll(self, value, mode='relative'):
|
||||
self._check_executed()
|
||||
if mode == 'relative':
|
||||
r = self.rownumber + value
|
||||
elif mode == 'absolute':
|
||||
r = value
|
||||
else:
|
||||
raise err.ProgrammingError("unknown scroll mode %s" % mode)
|
||||
|
||||
if not (0 <= r < len(self._rows)):
|
||||
raise IndexError("out of range")
|
||||
self.rownumber = r
|
||||
|
||||
def _query(self, q):
|
||||
conn = self._get_db()
|
||||
self._last_executed = q
|
||||
self._clear_result()
|
||||
conn.query(q)
|
||||
self._do_get_result()
|
||||
return self.rowcount
|
||||
|
||||
def _clear_result(self):
|
||||
self.rownumber = 0
|
||||
self._result = None
|
||||
|
||||
self.rowcount = 0
|
||||
self.description = None
|
||||
self.lastrowid = None
|
||||
self._rows = None
|
||||
|
||||
def _do_get_result(self):
|
||||
conn = self._get_db()
|
||||
|
||||
self._result = result = conn._result
|
||||
|
||||
self.rowcount = result.affected_rows
|
||||
self.description = result.description
|
||||
self.lastrowid = result.insert_id
|
||||
self._rows = result.rows
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.fetchone, None)
|
||||
|
||||
Warning = err.Warning
|
||||
Error = err.Error
|
||||
InterfaceError = err.InterfaceError
|
||||
DatabaseError = err.DatabaseError
|
||||
DataError = err.DataError
|
||||
OperationalError = err.OperationalError
|
||||
IntegrityError = err.IntegrityError
|
||||
InternalError = err.InternalError
|
||||
ProgrammingError = err.ProgrammingError
|
||||
NotSupportedError = err.NotSupportedError
|
||||
|
||||
|
||||
class DictCursorMixin(object):
|
||||
# You can override this to use OrderedDict or other dict-like types.
|
||||
dict_type = dict
|
||||
|
||||
def _do_get_result(self):
|
||||
super(DictCursorMixin, self)._do_get_result()
|
||||
fields = []
|
||||
if self.description:
|
||||
for f in self._result.fields:
|
||||
name = f.name
|
||||
if name in fields:
|
||||
name = f.table_name + '.' + name
|
||||
fields.append(name)
|
||||
self._fields = fields
|
||||
|
||||
if fields and self._rows:
|
||||
self._rows = [self._conv_row(r) for r in self._rows]
|
||||
|
||||
def _conv_row(self, row):
|
||||
if row is None:
|
||||
return None
|
||||
return self.dict_type(zip(self._fields, row))
|
||||
|
||||
|
||||
class DictCursor(DictCursorMixin, Cursor):
|
||||
"""A cursor which returns results as a dictionary"""
|
||||
|
||||
|
||||
class SSCursor(Cursor):
|
||||
"""
|
||||
Unbuffered Cursor, mainly useful for queries that return a lot of data,
|
||||
or for connections to remote servers over a slow network.
|
||||
|
||||
Instead of copying every row of data into a buffer, this will fetch
|
||||
rows as needed. The upside of this is the client uses much less memory,
|
||||
and rows are returned much faster when traveling over a slow network
|
||||
or if the result set is very big.
|
||||
|
||||
There are limitations, though. The MySQL protocol doesn't support
|
||||
returning the total number of rows, so the only way to tell how many rows
|
||||
there are is to iterate over every row returned. Also, it currently isn't
|
||||
possible to scroll backwards, as only the current row is held in memory.
|
||||
"""
|
||||
|
||||
def _conv_row(self, row):
|
||||
return row
|
||||
|
||||
def close(self):
|
||||
conn = self.connection
|
||||
if conn is None:
|
||||
return
|
||||
|
||||
if self._result is not None and self._result is conn._result:
|
||||
self._result._finish_unbuffered_query()
|
||||
|
||||
try:
|
||||
while self.nextset():
|
||||
pass
|
||||
finally:
|
||||
self.connection = None
|
||||
|
||||
__del__ = close
|
||||
|
||||
def _query(self, q):
|
||||
conn = self._get_db()
|
||||
self._last_executed = q
|
||||
self._clear_result()
|
||||
conn.query(q, unbuffered=True)
|
||||
self._do_get_result()
|
||||
return self.rowcount
|
||||
|
||||
def nextset(self):
|
||||
return self._nextset(unbuffered=True)
|
||||
|
||||
def read_next(self):
|
||||
"""Read next row"""
|
||||
return self._conv_row(self._result._read_rowdata_packet_unbuffered())
|
||||
|
||||
def fetchone(self):
|
||||
"""Fetch next row"""
|
||||
self._check_executed()
|
||||
row = self.read_next()
|
||||
if row is None:
|
||||
return None
|
||||
self.rownumber += 1
|
||||
return row
|
||||
|
||||
def fetchall(self):
|
||||
"""
|
||||
Fetch all, as per MySQLdb. Pretty useless for large queries, as
|
||||
it is buffered. See fetchall_unbuffered(), if you want an unbuffered
|
||||
generator version of this method.
|
||||
"""
|
||||
return list(self.fetchall_unbuffered())
|
||||
|
||||
def fetchall_unbuffered(self):
|
||||
"""
|
||||
Fetch all, implemented as a generator, which isn't to standard,
|
||||
however, it doesn't make sense to return everything in a list, as that
|
||||
would use ridiculous memory for large result sets.
|
||||
"""
|
||||
return iter(self.fetchone, None)
|
||||
|
||||
def __iter__(self):
|
||||
return self.fetchall_unbuffered()
|
||||
|
||||
def fetchmany(self, size=None):
|
||||
"""Fetch many"""
|
||||
self._check_executed()
|
||||
if size is None:
|
||||
size = self.arraysize
|
||||
|
||||
rows = []
|
||||
for i in range_type(size):
|
||||
row = self.read_next()
|
||||
if row is None:
|
||||
break
|
||||
rows.append(row)
|
||||
self.rownumber += 1
|
||||
return rows
|
||||
|
||||
def scroll(self, value, mode='relative'):
|
||||
self._check_executed()
|
||||
|
||||
if mode == 'relative':
|
||||
if value < 0:
|
||||
raise err.NotSupportedError(
|
||||
"Backwards scrolling not supported by this cursor")
|
||||
|
||||
for _ in range_type(value):
|
||||
self.read_next()
|
||||
self.rownumber += value
|
||||
elif mode == 'absolute':
|
||||
if value < self.rownumber:
|
||||
raise err.NotSupportedError(
|
||||
"Backwards scrolling not supported by this cursor")
|
||||
|
||||
end = value - self.rownumber
|
||||
for _ in range_type(end):
|
||||
self.read_next()
|
||||
self.rownumber = value
|
||||
else:
|
||||
raise err.ProgrammingError("unknown scroll mode %s" % mode)
|
||||
|
||||
|
||||
class SSDictCursor(DictCursorMixin, SSCursor):
|
||||
"""An unbuffered cursor, which returns results as a dictionary"""
|
||||
107
venv/lib/python3.9/site-packages/pymysql/err.py
Normal file
107
venv/lib/python3.9/site-packages/pymysql/err.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
import struct
|
||||
|
||||
from .constants import ER
|
||||
|
||||
|
||||
class MySQLError(Exception):
|
||||
"""Exception related to operation with MySQL."""
|
||||
|
||||
|
||||
class Warning(Warning, MySQLError):
|
||||
"""Exception raised for important warnings like data truncations
|
||||
while inserting, etc."""
|
||||
|
||||
|
||||
class Error(MySQLError):
|
||||
"""Exception that is the base class of all other error exceptions
|
||||
(not Warning)."""
|
||||
|
||||
|
||||
class InterfaceError(Error):
|
||||
"""Exception raised for errors that are related to the database
|
||||
interface rather than the database itself."""
|
||||
|
||||
|
||||
class DatabaseError(Error):
|
||||
"""Exception raised for errors that are related to the
|
||||
database."""
|
||||
|
||||
|
||||
class DataError(DatabaseError):
|
||||
"""Exception raised for errors that are due to problems with the
|
||||
processed data like division by zero, numeric value out of range,
|
||||
etc."""
|
||||
|
||||
|
||||
class OperationalError(DatabaseError):
|
||||
"""Exception raised for errors that are related to the database's
|
||||
operation and not necessarily under the control of the programmer,
|
||||
e.g. an unexpected disconnect occurs, the data source name is not
|
||||
found, a transaction could not be processed, a memory allocation
|
||||
error occurred during processing, etc."""
|
||||
|
||||
|
||||
class IntegrityError(DatabaseError):
|
||||
"""Exception raised when the relational integrity of the database
|
||||
is affected, e.g. a foreign key check fails, duplicate key,
|
||||
etc."""
|
||||
|
||||
|
||||
class InternalError(DatabaseError):
|
||||
"""Exception raised when the database encounters an internal
|
||||
error, e.g. the cursor is not valid anymore, the transaction is
|
||||
out of sync, etc."""
|
||||
|
||||
|
||||
class ProgrammingError(DatabaseError):
|
||||
"""Exception raised for programming errors, e.g. table not found
|
||||
or already exists, syntax error in the SQL statement, wrong number
|
||||
of parameters specified, etc."""
|
||||
|
||||
|
||||
class NotSupportedError(DatabaseError):
|
||||
"""Exception raised in case a method or database API was used
|
||||
which is not supported by the database, e.g. requesting a
|
||||
.rollback() on a connection that does not support transaction or
|
||||
has transactions turned off."""
|
||||
|
||||
|
||||
error_map = {}
|
||||
|
||||
|
||||
def _map_error(exc, *errors):
|
||||
for error in errors:
|
||||
error_map[error] = exc
|
||||
|
||||
|
||||
_map_error(ProgrammingError, ER.DB_CREATE_EXISTS, ER.SYNTAX_ERROR,
|
||||
ER.PARSE_ERROR, ER.NO_SUCH_TABLE, ER.WRONG_DB_NAME,
|
||||
ER.WRONG_TABLE_NAME, ER.FIELD_SPECIFIED_TWICE,
|
||||
ER.INVALID_GROUP_FUNC_USE, ER.UNSUPPORTED_EXTENSION,
|
||||
ER.TABLE_MUST_HAVE_COLUMNS, ER.CANT_DO_THIS_DURING_AN_TRANSACTION,
|
||||
ER.WRONG_DB_NAME, ER.WRONG_COLUMN_NAME,
|
||||
)
|
||||
_map_error(DataError, ER.WARN_DATA_TRUNCATED, ER.WARN_NULL_TO_NOTNULL,
|
||||
ER.WARN_DATA_OUT_OF_RANGE, ER.NO_DEFAULT, ER.PRIMARY_CANT_HAVE_NULL,
|
||||
ER.DATA_TOO_LONG, ER.DATETIME_FUNCTION_OVERFLOW, ER.TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||
ER.ILLEGAL_VALUE_FOR_TYPE)
|
||||
_map_error(IntegrityError, ER.DUP_ENTRY, ER.NO_REFERENCED_ROW,
|
||||
ER.NO_REFERENCED_ROW_2, ER.ROW_IS_REFERENCED, ER.ROW_IS_REFERENCED_2,
|
||||
ER.CANNOT_ADD_FOREIGN, ER.BAD_NULL_ERROR)
|
||||
_map_error(NotSupportedError, ER.WARNING_NOT_COMPLETE_ROLLBACK,
|
||||
ER.NOT_SUPPORTED_YET, ER.FEATURE_DISABLED, ER.UNKNOWN_STORAGE_ENGINE)
|
||||
_map_error(OperationalError, ER.DBACCESS_DENIED_ERROR, ER.ACCESS_DENIED_ERROR,
|
||||
ER.CON_COUNT_ERROR, ER.TABLEACCESS_DENIED_ERROR,
|
||||
ER.COLUMNACCESS_DENIED_ERROR, ER.CONSTRAINT_FAILED, ER.LOCK_DEADLOCK)
|
||||
|
||||
|
||||
del _map_error, ER
|
||||
|
||||
|
||||
def raise_mysql_exception(data):
|
||||
errno = struct.unpack('<h', data[1:3])[0]
|
||||
errval = data[9:].decode('utf-8', 'replace')
|
||||
errorclass = error_map.get(errno)
|
||||
if errorclass is None:
|
||||
errorclass = InternalError if errno < 1000 else OperationalError
|
||||
raise errorclass(errno, errval)
|
||||
23
venv/lib/python3.9/site-packages/pymysql/optionfile.py
Normal file
23
venv/lib/python3.9/site-packages/pymysql/optionfile.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
from ._compat import PY2
|
||||
|
||||
if PY2:
|
||||
import ConfigParser as configparser
|
||||
else:
|
||||
import configparser
|
||||
|
||||
|
||||
class Parser(configparser.RawConfigParser):
|
||||
def __init__(self, **kwargs):
|
||||
kwargs['allow_no_value'] = True
|
||||
configparser.RawConfigParser.__init__(self, **kwargs)
|
||||
|
||||
def __remove_quotes(self, value):
|
||||
quotes = ["'", "\""]
|
||||
for quote in quotes:
|
||||
if len(value) >= 2 and value[0] == value[-1] == quote:
|
||||
return value[1:-1]
|
||||
return value
|
||||
|
||||
def get(self, section, option):
|
||||
value = configparser.RawConfigParser.get(self, section, option)
|
||||
return self.__remove_quotes(value)
|
||||
344
venv/lib/python3.9/site-packages/pymysql/protocol.py
Normal file
344
venv/lib/python3.9/site-packages/pymysql/protocol.py
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
# Python implementation of low level MySQL client-server protocol
|
||||
# http://dev.mysql.com/doc/internals/en/client-server-protocol.html
|
||||
|
||||
from __future__ import print_function
|
||||
from .charset import MBLENGTH
|
||||
from ._compat import PY2, range_type
|
||||
from .constants import FIELD_TYPE, SERVER_STATUS
|
||||
from . import err
|
||||
from .util import byte2int
|
||||
|
||||
import struct
|
||||
import sys
|
||||
|
||||
|
||||
DEBUG = False
|
||||
|
||||
NULL_COLUMN = 251
|
||||
UNSIGNED_CHAR_COLUMN = 251
|
||||
UNSIGNED_SHORT_COLUMN = 252
|
||||
UNSIGNED_INT24_COLUMN = 253
|
||||
UNSIGNED_INT64_COLUMN = 254
|
||||
|
||||
|
||||
def dump_packet(data): # pragma: no cover
|
||||
def printable(data):
|
||||
if 32 <= byte2int(data) < 127:
|
||||
if isinstance(data, int):
|
||||
return chr(data)
|
||||
return data
|
||||
return '.'
|
||||
|
||||
try:
|
||||
print("packet length:", len(data))
|
||||
for i in range(1, 7):
|
||||
f = sys._getframe(i)
|
||||
print("call[%d]: %s (line %d)" % (i, f.f_code.co_name, f.f_lineno))
|
||||
print("-" * 66)
|
||||
except ValueError:
|
||||
pass
|
||||
dump_data = [data[i:i+16] for i in range_type(0, min(len(data), 256), 16)]
|
||||
for d in dump_data:
|
||||
print(' '.join("{:02X}".format(byte2int(x)) for x in d) +
|
||||
' ' * (16 - len(d)) + ' ' * 2 +
|
||||
''.join(printable(x) for x in d))
|
||||
print("-" * 66)
|
||||
print()
|
||||
|
||||
|
||||
class MysqlPacket(object):
|
||||
"""Representation of a MySQL response packet.
|
||||
|
||||
Provides an interface for reading/parsing the packet results.
|
||||
"""
|
||||
__slots__ = ('_position', '_data')
|
||||
|
||||
def __init__(self, data, encoding):
|
||||
self._position = 0
|
||||
self._data = data
|
||||
|
||||
def get_all_data(self):
|
||||
return self._data
|
||||
|
||||
def read(self, size):
|
||||
"""Read the first 'size' bytes in packet and advance cursor past them."""
|
||||
result = self._data[self._position:(self._position+size)]
|
||||
if len(result) != size:
|
||||
error = ('Result length not requested length:\n'
|
||||
'Expected=%s. Actual=%s. Position: %s. Data Length: %s'
|
||||
% (size, len(result), self._position, len(self._data)))
|
||||
if DEBUG:
|
||||
print(error)
|
||||
self.dump()
|
||||
raise AssertionError(error)
|
||||
self._position += size
|
||||
return result
|
||||
|
||||
def read_all(self):
|
||||
"""Read all remaining data in the packet.
|
||||
|
||||
(Subsequent read() will return errors.)
|
||||
"""
|
||||
result = self._data[self._position:]
|
||||
self._position = None # ensure no subsequent read()
|
||||
return result
|
||||
|
||||
def advance(self, length):
|
||||
"""Advance the cursor in data buffer 'length' bytes."""
|
||||
new_position = self._position + length
|
||||
if new_position < 0 or new_position > len(self._data):
|
||||
raise Exception('Invalid advance amount (%s) for cursor. '
|
||||
'Position=%s' % (length, new_position))
|
||||
self._position = new_position
|
||||
|
||||
def rewind(self, position=0):
|
||||
"""Set the position of the data buffer cursor to 'position'."""
|
||||
if position < 0 or position > len(self._data):
|
||||
raise Exception("Invalid position to rewind cursor to: %s." % position)
|
||||
self._position = position
|
||||
|
||||
def get_bytes(self, position, length=1):
|
||||
"""Get 'length' bytes starting at 'position'.
|
||||
|
||||
Position is start of payload (first four packet header bytes are not
|
||||
included) starting at index '0'.
|
||||
|
||||
No error checking is done. If requesting outside end of buffer
|
||||
an empty string (or string shorter than 'length') may be returned!
|
||||
"""
|
||||
return self._data[position:(position+length)]
|
||||
|
||||
if PY2:
|
||||
def read_uint8(self):
|
||||
result = ord(self._data[self._position])
|
||||
self._position += 1
|
||||
return result
|
||||
else:
|
||||
def read_uint8(self):
|
||||
result = self._data[self._position]
|
||||
self._position += 1
|
||||
return result
|
||||
|
||||
def read_uint16(self):
|
||||
result = struct.unpack_from('<H', self._data, self._position)[0]
|
||||
self._position += 2
|
||||
return result
|
||||
|
||||
def read_uint24(self):
|
||||
low, high = struct.unpack_from('<HB', self._data, self._position)
|
||||
self._position += 3
|
||||
return low + (high << 16)
|
||||
|
||||
def read_uint32(self):
|
||||
result = struct.unpack_from('<I', self._data, self._position)[0]
|
||||
self._position += 4
|
||||
return result
|
||||
|
||||
def read_uint64(self):
|
||||
result = struct.unpack_from('<Q', self._data, self._position)[0]
|
||||
self._position += 8
|
||||
return result
|
||||
|
||||
def read_string(self):
|
||||
end_pos = self._data.find(b'\0', self._position)
|
||||
if end_pos < 0:
|
||||
return None
|
||||
result = self._data[self._position:end_pos]
|
||||
self._position = end_pos + 1
|
||||
return result
|
||||
|
||||
def read_length_encoded_integer(self):
|
||||
"""Read a 'Length Coded Binary' number from the data buffer.
|
||||
|
||||
Length coded numbers can be anywhere from 1 to 9 bytes depending
|
||||
on the value of the first byte.
|
||||
"""
|
||||
c = self.read_uint8()
|
||||
if c == NULL_COLUMN:
|
||||
return None
|
||||
if c < UNSIGNED_CHAR_COLUMN:
|
||||
return c
|
||||
elif c == UNSIGNED_SHORT_COLUMN:
|
||||
return self.read_uint16()
|
||||
elif c == UNSIGNED_INT24_COLUMN:
|
||||
return self.read_uint24()
|
||||
elif c == UNSIGNED_INT64_COLUMN:
|
||||
return self.read_uint64()
|
||||
|
||||
def read_length_coded_string(self):
|
||||
"""Read a 'Length Coded String' from the data buffer.
|
||||
|
||||
A 'Length Coded String' consists first of a length coded
|
||||
(unsigned, positive) integer represented in 1-9 bytes followed by
|
||||
that many bytes of binary data. (For example "cat" would be "3cat".)
|
||||
"""
|
||||
length = self.read_length_encoded_integer()
|
||||
if length is None:
|
||||
return None
|
||||
return self.read(length)
|
||||
|
||||
def read_struct(self, fmt):
|
||||
s = struct.Struct(fmt)
|
||||
result = s.unpack_from(self._data, self._position)
|
||||
self._position += s.size
|
||||
return result
|
||||
|
||||
def is_ok_packet(self):
|
||||
# https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html
|
||||
return self._data[0:1] == b'\0' and len(self._data) >= 7
|
||||
|
||||
def is_eof_packet(self):
|
||||
# http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-EOF_Packet
|
||||
# Caution: \xFE may be LengthEncodedInteger.
|
||||
# If \xFE is LengthEncodedInteger header, 8bytes followed.
|
||||
return self._data[0:1] == b'\xfe' and len(self._data) < 9
|
||||
|
||||
def is_auth_switch_request(self):
|
||||
# http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest
|
||||
return self._data[0:1] == b'\xfe'
|
||||
|
||||
def is_extra_auth_data(self):
|
||||
# https://dev.mysql.com/doc/internals/en/successful-authentication.html
|
||||
return self._data[0:1] == b'\x01'
|
||||
|
||||
def is_resultset_packet(self):
|
||||
field_count = ord(self._data[0:1])
|
||||
return 1 <= field_count <= 250
|
||||
|
||||
def is_load_local_packet(self):
|
||||
return self._data[0:1] == b'\xfb'
|
||||
|
||||
def is_error_packet(self):
|
||||
return self._data[0:1] == b'\xff'
|
||||
|
||||
def check_error(self):
|
||||
if self.is_error_packet():
|
||||
self.raise_for_error()
|
||||
|
||||
def raise_for_error(self):
|
||||
self.rewind()
|
||||
self.advance(1) # field_count == error (we already know that)
|
||||
errno = self.read_uint16()
|
||||
if DEBUG: print("errno =", errno)
|
||||
err.raise_mysql_exception(self._data)
|
||||
|
||||
def dump(self):
|
||||
dump_packet(self._data)
|
||||
|
||||
|
||||
class FieldDescriptorPacket(MysqlPacket):
|
||||
"""A MysqlPacket that represents a specific column's metadata in the result.
|
||||
|
||||
Parsing is automatically done and the results are exported via public
|
||||
attributes on the class such as: db, table_name, name, length, type_code.
|
||||
"""
|
||||
|
||||
def __init__(self, data, encoding):
|
||||
MysqlPacket.__init__(self, data, encoding)
|
||||
self._parse_field_descriptor(encoding)
|
||||
|
||||
def _parse_field_descriptor(self, encoding):
|
||||
"""Parse the 'Field Descriptor' (Metadata) packet.
|
||||
|
||||
This is compatible with MySQL 4.1+ (not compatible with MySQL 4.0).
|
||||
"""
|
||||
self.catalog = self.read_length_coded_string()
|
||||
self.db = self.read_length_coded_string()
|
||||
self.table_name = self.read_length_coded_string().decode(encoding)
|
||||
self.org_table = self.read_length_coded_string().decode(encoding)
|
||||
self.name = self.read_length_coded_string().decode(encoding)
|
||||
self.org_name = self.read_length_coded_string().decode(encoding)
|
||||
self.charsetnr, self.length, self.type_code, self.flags, self.scale = (
|
||||
self.read_struct('<xHIBHBxx'))
|
||||
# 'default' is a length coded binary and is still in the buffer?
|
||||
# not used for normal result sets...
|
||||
|
||||
def description(self):
|
||||
"""Provides a 7-item tuple compatible with the Python PEP249 DB Spec."""
|
||||
return (
|
||||
self.name,
|
||||
self.type_code,
|
||||
None, # TODO: display_length; should this be self.length?
|
||||
self.get_column_length(), # 'internal_size'
|
||||
self.get_column_length(), # 'precision' # TODO: why!?!?
|
||||
self.scale,
|
||||
self.flags % 2 == 0)
|
||||
|
||||
def get_column_length(self):
|
||||
if self.type_code == FIELD_TYPE.VAR_STRING:
|
||||
mblen = MBLENGTH.get(self.charsetnr, 1)
|
||||
return self.length // mblen
|
||||
return self.length
|
||||
|
||||
def __str__(self):
|
||||
return ('%s %r.%r.%r, type=%s, flags=%x'
|
||||
% (self.__class__, self.db, self.table_name, self.name,
|
||||
self.type_code, self.flags))
|
||||
|
||||
|
||||
class OKPacketWrapper(object):
|
||||
"""
|
||||
OK Packet Wrapper. It uses an existing packet object, and wraps
|
||||
around it, exposing useful variables while still providing access
|
||||
to the original packet objects variables and methods.
|
||||
"""
|
||||
|
||||
def __init__(self, from_packet):
|
||||
if not from_packet.is_ok_packet():
|
||||
raise ValueError('Cannot create ' + str(self.__class__.__name__) +
|
||||
' object from invalid packet type')
|
||||
|
||||
self.packet = from_packet
|
||||
self.packet.advance(1)
|
||||
|
||||
self.affected_rows = self.packet.read_length_encoded_integer()
|
||||
self.insert_id = self.packet.read_length_encoded_integer()
|
||||
self.server_status, self.warning_count = self.read_struct('<HH')
|
||||
self.message = self.packet.read_all()
|
||||
self.has_next = self.server_status & SERVER_STATUS.SERVER_MORE_RESULTS_EXISTS
|
||||
|
||||
def __getattr__(self, key):
|
||||
return getattr(self.packet, key)
|
||||
|
||||
|
||||
class EOFPacketWrapper(object):
|
||||
"""
|
||||
EOF Packet Wrapper. It uses an existing packet object, and wraps
|
||||
around it, exposing useful variables while still providing access
|
||||
to the original packet objects variables and methods.
|
||||
"""
|
||||
|
||||
def __init__(self, from_packet):
|
||||
if not from_packet.is_eof_packet():
|
||||
raise ValueError(
|
||||
"Cannot create '{0}' object from invalid packet type".format(
|
||||
self.__class__))
|
||||
|
||||
self.packet = from_packet
|
||||
self.warning_count, self.server_status = self.packet.read_struct('<xhh')
|
||||
if DEBUG: print("server_status=", self.server_status)
|
||||
self.has_next = self.server_status & SERVER_STATUS.SERVER_MORE_RESULTS_EXISTS
|
||||
|
||||
def __getattr__(self, key):
|
||||
return getattr(self.packet, key)
|
||||
|
||||
|
||||
class LoadLocalPacketWrapper(object):
|
||||
"""
|
||||
Load Local Packet Wrapper. It uses an existing packet object, and wraps
|
||||
around it, exposing useful variables while still providing access
|
||||
to the original packet objects variables and methods.
|
||||
"""
|
||||
|
||||
def __init__(self, from_packet):
|
||||
if not from_packet.is_load_local_packet():
|
||||
raise ValueError(
|
||||
"Cannot create '{0}' object from invalid packet type".format(
|
||||
self.__class__))
|
||||
|
||||
self.packet = from_packet
|
||||
self.filename = self.packet.get_all_data()[1:]
|
||||
if DEBUG: print("filename=", self.filename)
|
||||
|
||||
def __getattr__(self, key):
|
||||
return getattr(self.packet, key)
|
||||
20
venv/lib/python3.9/site-packages/pymysql/times.py
Normal file
20
venv/lib/python3.9/site-packages/pymysql/times.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
from time import localtime
|
||||
from datetime import date, datetime, time, timedelta
|
||||
|
||||
|
||||
Date = date
|
||||
Time = time
|
||||
TimeDelta = timedelta
|
||||
Timestamp = datetime
|
||||
|
||||
|
||||
def DateFromTicks(ticks):
|
||||
return date(*localtime(ticks)[:3])
|
||||
|
||||
|
||||
def TimeFromTicks(ticks):
|
||||
return time(*localtime(ticks)[3:6])
|
||||
|
||||
|
||||
def TimestampFromTicks(ticks):
|
||||
return datetime(*localtime(ticks)[:6])
|
||||
13
venv/lib/python3.9/site-packages/pymysql/util.py
Normal file
13
venv/lib/python3.9/site-packages/pymysql/util.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import struct
|
||||
|
||||
|
||||
def byte2int(b):
|
||||
if isinstance(b, int):
|
||||
return b
|
||||
else:
|
||||
return struct.unpack("!B", b)[0]
|
||||
|
||||
|
||||
def int2byte(i):
|
||||
return struct.pack("!B", i)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue