mirror of https://github.com/sgoudham/Enso-Bot.git
Removed MySQL and MySQL connector for Python
parent
228308f4a3
commit
01ddf55f42
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
pip
|
|
@ -1,28 +0,0 @@
|
|||||||
Metadata-Version: 2.1
|
|
||||||
Name: mysql
|
|
||||||
Version: 0.0.2
|
|
||||||
Summary: Virtual package for MySQL-python
|
|
||||||
Home-page: https://github.com/valhallasw/virtual-mysql-pypi-package
|
|
||||||
Author: Merlijn van Deen
|
|
||||||
Author-email: valhallasw@arctus.nl
|
|
||||||
License: ['MIT']
|
|
||||||
Platform: UNKNOWN
|
|
||||||
Requires-Dist: mysqlclient
|
|
||||||
|
|
||||||
----------------------------
|
|
||||||
Virtual MySQL-python package
|
|
||||||
----------------------------
|
|
||||||
|
|
||||||
This package is a 'virtual package', which requires MySQL-python (Python 2)
|
|
||||||
or mysqlclient (Python 3) to install.
|
|
||||||
In effect, this means 'pip install mysql' will actually install MySQL-python.
|
|
||||||
|
|
||||||
Instead of depending on this package, please depend on the relevant package
|
|
||||||
directly.
|
|
||||||
|
|
||||||
See also:
|
|
||||||
- https://pypi.python.org/pypi/MySQL-python
|
|
||||||
- https://pypi.python.org/pypi/mysqlclient
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
|||||||
mysql-0.0.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
|
||||||
mysql-0.0.2.dist-info/METADATA,sha256=BwuJaMEgzpdXVUvmfSnPZF-7FMqOM7BJ1YgpL1eoA_M,750
|
|
||||||
mysql-0.0.2.dist-info/RECORD,,
|
|
||||||
mysql-0.0.2.dist-info/WHEEL,sha256=YUYzQ6UQdoqxXjimOitTqynltBCkwY6qlTfTh2IzqQU,97
|
|
||||||
mysql-0.0.2.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
@ -1,5 +0,0 @@
|
|||||||
Wheel-Version: 1.0
|
|
||||||
Generator: bdist_wheel (0.34.2)
|
|
||||||
Root-Is-Purelib: true
|
|
||||||
Tag: py3-none-any
|
|
||||||
|
|
@ -1,293 +0,0 @@
|
|||||||
# Copyright (c) 2009, 2020, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""
|
|
||||||
MySQL Connector/Python - MySQL driver written in Python
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
import _mysql_connector # pylint: disable=F0401
|
|
||||||
from .connection_cext import CMySQLConnection
|
|
||||||
except ImportError:
|
|
||||||
HAVE_CEXT = False
|
|
||||||
else:
|
|
||||||
HAVE_CEXT = True
|
|
||||||
|
|
||||||
try:
|
|
||||||
import dns.resolver
|
|
||||||
import dns.exception
|
|
||||||
except ImportError:
|
|
||||||
HAVE_DNSPYTHON = False
|
|
||||||
else:
|
|
||||||
HAVE_DNSPYTHON = True
|
|
||||||
|
|
||||||
import random
|
|
||||||
|
|
||||||
from . import version
|
|
||||||
from .connection import MySQLConnection
|
|
||||||
from .constants import DEFAULT_CONFIGURATION
|
|
||||||
from .errors import ( # pylint: disable=W0622
|
|
||||||
Error, Warning, InterfaceError, DatabaseError,
|
|
||||||
NotSupportedError, DataError, IntegrityError, ProgrammingError,
|
|
||||||
OperationalError, InternalError, custom_error_exception, PoolError)
|
|
||||||
from .constants import FieldFlag, FieldType, CharacterSet, \
|
|
||||||
RefreshOption, ClientFlag
|
|
||||||
from .dbapi import (
|
|
||||||
Date, Time, Timestamp, Binary, DateFromTicks,
|
|
||||||
TimestampFromTicks, TimeFromTicks,
|
|
||||||
STRING, BINARY, NUMBER, DATETIME, ROWID,
|
|
||||||
apilevel, threadsafety, paramstyle)
|
|
||||||
from .optionfiles import read_option_files
|
|
||||||
|
|
||||||
_CONNECTION_POOLS = {}
|
|
||||||
|
|
||||||
def _get_pooled_connection(**kwargs):
|
|
||||||
"""Return a pooled MySQL connection"""
|
|
||||||
# If no pool name specified, generate one
|
|
||||||
from .pooling import (
|
|
||||||
MySQLConnectionPool, generate_pool_name,
|
|
||||||
CONNECTION_POOL_LOCK)
|
|
||||||
|
|
||||||
try:
|
|
||||||
pool_name = kwargs['pool_name']
|
|
||||||
except KeyError:
|
|
||||||
pool_name = generate_pool_name(**kwargs)
|
|
||||||
|
|
||||||
# Setup the pool, ensuring only 1 thread can update at a time
|
|
||||||
with CONNECTION_POOL_LOCK:
|
|
||||||
if pool_name not in _CONNECTION_POOLS:
|
|
||||||
_CONNECTION_POOLS[pool_name] = MySQLConnectionPool(**kwargs)
|
|
||||||
elif isinstance(_CONNECTION_POOLS[pool_name], MySQLConnectionPool):
|
|
||||||
# pool_size must be the same
|
|
||||||
check_size = _CONNECTION_POOLS[pool_name].pool_size
|
|
||||||
if ('pool_size' in kwargs
|
|
||||||
and kwargs['pool_size'] != check_size):
|
|
||||||
raise PoolError("Size can not be changed "
|
|
||||||
"for active pools.")
|
|
||||||
|
|
||||||
# Return pooled connection
|
|
||||||
try:
|
|
||||||
return _CONNECTION_POOLS[pool_name].get_connection()
|
|
||||||
except AttributeError:
|
|
||||||
raise InterfaceError(
|
|
||||||
"Failed getting connection from pool '{0}'".format(pool_name))
|
|
||||||
|
|
||||||
|
|
||||||
def _get_failover_connection(**kwargs):
|
|
||||||
"""Return a MySQL connection and try to failover if needed
|
|
||||||
|
|
||||||
An InterfaceError is raise when no MySQL is available. ValueError is
|
|
||||||
raised when the failover server configuration contains an illegal
|
|
||||||
connection argument. Supported arguments are user, password, host, port,
|
|
||||||
unix_socket and database. ValueError is also raised when the failover
|
|
||||||
argument was not provided.
|
|
||||||
|
|
||||||
Returns MySQLConnection instance.
|
|
||||||
"""
|
|
||||||
config = kwargs.copy()
|
|
||||||
try:
|
|
||||||
failover = config['failover']
|
|
||||||
except KeyError:
|
|
||||||
raise ValueError('failover argument not provided')
|
|
||||||
del config['failover']
|
|
||||||
|
|
||||||
support_cnx_args = set(
|
|
||||||
['user', 'password', 'host', 'port', 'unix_socket',
|
|
||||||
'database', 'pool_name', 'pool_size', 'priority'])
|
|
||||||
|
|
||||||
# First check if we can add all use the configuration
|
|
||||||
priority_count = 0
|
|
||||||
for server in failover:
|
|
||||||
diff = set(server.keys()) - support_cnx_args
|
|
||||||
if diff:
|
|
||||||
raise ValueError(
|
|
||||||
"Unsupported connection argument {0} in failover: {1}".format(
|
|
||||||
's' if len(diff) > 1 else '',
|
|
||||||
', '.join(diff)))
|
|
||||||
if hasattr(server, "priority"):
|
|
||||||
priority_count += 1
|
|
||||||
|
|
||||||
server["priority"] = server.get("priority", 100)
|
|
||||||
if server["priority"] < 0 or server["priority"] > 100:
|
|
||||||
raise InterfaceError(
|
|
||||||
"Priority value should be in the range of 0 to 100, "
|
|
||||||
"got : {}".format(server["priority"]))
|
|
||||||
if not isinstance(server["priority"], int):
|
|
||||||
raise InterfaceError(
|
|
||||||
"Priority value should be an integer in the range of 0 to "
|
|
||||||
"100, got : {}".format(server["priority"]))
|
|
||||||
|
|
||||||
if 0 < priority_count < len(failover):
|
|
||||||
raise ProgrammingError("You must either assign no priority to any "
|
|
||||||
"of the routers or give a priority for "
|
|
||||||
"every router")
|
|
||||||
|
|
||||||
failover.sort(key=lambda x: x['priority'], reverse=True)
|
|
||||||
|
|
||||||
server_directory = {}
|
|
||||||
server_priority_list = []
|
|
||||||
for server in failover:
|
|
||||||
if server["priority"] not in server_directory:
|
|
||||||
server_directory[server["priority"]] = [server]
|
|
||||||
server_priority_list.append(server["priority"])
|
|
||||||
else:
|
|
||||||
server_directory[server["priority"]].append(server)
|
|
||||||
|
|
||||||
for priority in server_priority_list:
|
|
||||||
failover_list = server_directory[priority]
|
|
||||||
for _ in range(len(failover_list)):
|
|
||||||
last = len(failover_list) - 1
|
|
||||||
index = random.randint(0, last)
|
|
||||||
server = failover_list.pop(index)
|
|
||||||
new_config = config.copy()
|
|
||||||
new_config.update(server)
|
|
||||||
new_config.pop('priority', None)
|
|
||||||
try:
|
|
||||||
return connect(**new_config)
|
|
||||||
except Error:
|
|
||||||
# If we failed to connect, we try the next server
|
|
||||||
pass
|
|
||||||
|
|
||||||
raise InterfaceError("Unable to connect to any of the target hosts")
|
|
||||||
|
|
||||||
|
|
||||||
def connect(*args, **kwargs):
|
|
||||||
"""Create or get a MySQL connection object
|
|
||||||
|
|
||||||
In its simpliest form, Connect() will open a connection to a
|
|
||||||
MySQL server and return a MySQLConnection object.
|
|
||||||
|
|
||||||
When any connection pooling arguments are given, for example pool_name
|
|
||||||
or pool_size, a pool is created or a previously one is used to return
|
|
||||||
a PooledMySQLConnection.
|
|
||||||
|
|
||||||
Returns MySQLConnection or PooledMySQLConnection.
|
|
||||||
"""
|
|
||||||
# DNS SRV
|
|
||||||
dns_srv = kwargs.pop('dns_srv') if 'dns_srv' in kwargs else False
|
|
||||||
|
|
||||||
if not isinstance(dns_srv, bool):
|
|
||||||
raise InterfaceError("The value of 'dns-srv' must be a boolean")
|
|
||||||
|
|
||||||
if dns_srv:
|
|
||||||
if not HAVE_DNSPYTHON:
|
|
||||||
raise InterfaceError('MySQL host configuration requested DNS '
|
|
||||||
'SRV. This requires the Python dnspython '
|
|
||||||
'module. Please refer to documentation')
|
|
||||||
if 'unix_socket' in kwargs:
|
|
||||||
raise InterfaceError('Using Unix domain sockets with DNS SRV '
|
|
||||||
'lookup is not allowed')
|
|
||||||
if 'port' in kwargs:
|
|
||||||
raise InterfaceError('Specifying a port number with DNS SRV '
|
|
||||||
'lookup is not allowed')
|
|
||||||
if 'failover' in kwargs:
|
|
||||||
raise InterfaceError('Specifying multiple hostnames with DNS '
|
|
||||||
'SRV look up is not allowed')
|
|
||||||
if 'host' not in kwargs:
|
|
||||||
kwargs['host'] = DEFAULT_CONFIGURATION['host']
|
|
||||||
|
|
||||||
try:
|
|
||||||
srv_records = dns.resolver.query(kwargs['host'], 'SRV')
|
|
||||||
except dns.exception.DNSException:
|
|
||||||
raise InterfaceError("Unable to locate any hosts for '{0}'"
|
|
||||||
"".format(kwargs['host']))
|
|
||||||
|
|
||||||
failover = []
|
|
||||||
for srv in srv_records:
|
|
||||||
failover.append({
|
|
||||||
'host': srv.target.to_text(omit_final_dot=True),
|
|
||||||
'port': srv.port,
|
|
||||||
'priority': srv.priority,
|
|
||||||
'weight': srv.weight
|
|
||||||
})
|
|
||||||
|
|
||||||
failover.sort(key=lambda x: (x['priority'], -x['weight']))
|
|
||||||
kwargs['failover'] = [{'host': srv['host'],
|
|
||||||
'port': srv['port']} for srv in failover]
|
|
||||||
|
|
||||||
# Option files
|
|
||||||
if 'read_default_file' in kwargs:
|
|
||||||
kwargs['option_files'] = kwargs['read_default_file']
|
|
||||||
kwargs.pop('read_default_file')
|
|
||||||
|
|
||||||
if 'option_files' in kwargs:
|
|
||||||
new_config = read_option_files(**kwargs)
|
|
||||||
return connect(**new_config)
|
|
||||||
|
|
||||||
# Failover
|
|
||||||
if 'failover' in kwargs:
|
|
||||||
return _get_failover_connection(**kwargs)
|
|
||||||
|
|
||||||
# Pooled connections
|
|
||||||
try:
|
|
||||||
from .constants import CNX_POOL_ARGS
|
|
||||||
if any([key in kwargs for key in CNX_POOL_ARGS]):
|
|
||||||
return _get_pooled_connection(**kwargs)
|
|
||||||
except NameError:
|
|
||||||
# No pooling
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Use C Extension by default
|
|
||||||
use_pure = kwargs.get('use_pure', False)
|
|
||||||
if 'use_pure' in kwargs:
|
|
||||||
del kwargs['use_pure'] # Remove 'use_pure' from kwargs
|
|
||||||
if not use_pure and not HAVE_CEXT:
|
|
||||||
raise ImportError("MySQL Connector/Python C Extension not "
|
|
||||||
"available")
|
|
||||||
|
|
||||||
if HAVE_CEXT and not use_pure:
|
|
||||||
return CMySQLConnection(*args, **kwargs)
|
|
||||||
return MySQLConnection(*args, **kwargs)
|
|
||||||
Connect = connect # pylint: disable=C0103
|
|
||||||
|
|
||||||
__version_info__ = version.VERSION
|
|
||||||
__version__ = version.VERSION_TEXT
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'MySQLConnection', 'Connect', 'custom_error_exception',
|
|
||||||
|
|
||||||
# Some useful constants
|
|
||||||
'FieldType', 'FieldFlag', 'ClientFlag', 'CharacterSet', 'RefreshOption',
|
|
||||||
'HAVE_CEXT',
|
|
||||||
|
|
||||||
# Error handling
|
|
||||||
'Error', 'Warning',
|
|
||||||
'InterfaceError', 'DatabaseError',
|
|
||||||
'NotSupportedError', 'DataError', 'IntegrityError', 'ProgrammingError',
|
|
||||||
'OperationalError', 'InternalError',
|
|
||||||
|
|
||||||
# DBAPI PEP 249 required exports
|
|
||||||
'connect', 'apilevel', 'threadsafety', 'paramstyle',
|
|
||||||
'Date', 'Time', 'Timestamp', 'Binary',
|
|
||||||
'DateFromTicks', 'DateFromTicks', 'TimestampFromTicks', 'TimeFromTicks',
|
|
||||||
'STRING', 'BINARY', 'NUMBER',
|
|
||||||
'DATETIME', 'ROWID',
|
|
||||||
|
|
||||||
# C Extension
|
|
||||||
'CMySQLConnection',
|
|
||||||
]
|
|
File diff suppressed because it is too large
Load Diff
@ -1,272 +0,0 @@
|
|||||||
# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Implementing support for MySQL Authentication Plugins"""
|
|
||||||
|
|
||||||
from hashlib import sha1, sha256
|
|
||||||
import struct
|
|
||||||
|
|
||||||
from . import errors
|
|
||||||
from .catch23 import PY2, isstr, UNICODE_TYPES
|
|
||||||
|
|
||||||
|
|
||||||
class BaseAuthPlugin(object):
|
|
||||||
"""Base class for authentication plugins
|
|
||||||
|
|
||||||
|
|
||||||
Classes inheriting from BaseAuthPlugin should implement the method
|
|
||||||
prepare_password(). When instantiating, auth_data argument is
|
|
||||||
required. The username, password and database are optional. The
|
|
||||||
ssl_enabled argument can be used to tell the plugin whether SSL is
|
|
||||||
active or not.
|
|
||||||
|
|
||||||
The method auth_response() method is used to retrieve the password
|
|
||||||
which was prepared by prepare_password().
|
|
||||||
"""
|
|
||||||
|
|
||||||
requires_ssl = False
|
|
||||||
plugin_name = ''
|
|
||||||
|
|
||||||
def __init__(self, auth_data, username=None, password=None, database=None,
|
|
||||||
ssl_enabled=False):
|
|
||||||
"""Initialization"""
|
|
||||||
self._auth_data = auth_data
|
|
||||||
self._username = username
|
|
||||||
self._password = password
|
|
||||||
self._database = database
|
|
||||||
self._ssl_enabled = ssl_enabled
|
|
||||||
|
|
||||||
def prepare_password(self):
|
|
||||||
"""Prepares and returns password to be send to MySQL
|
|
||||||
|
|
||||||
This method needs to be implemented by classes inheriting from
|
|
||||||
this class. It is used by the auth_response() method.
|
|
||||||
|
|
||||||
Raises NotImplementedError.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def auth_response(self):
|
|
||||||
"""Returns the prepared password to send to MySQL
|
|
||||||
|
|
||||||
Raises InterfaceError on errors. For example, when SSL is required
|
|
||||||
by not enabled.
|
|
||||||
|
|
||||||
Returns str
|
|
||||||
"""
|
|
||||||
if self.requires_ssl and not self._ssl_enabled:
|
|
||||||
raise errors.InterfaceError("{name} requires SSL".format(
|
|
||||||
name=self.plugin_name))
|
|
||||||
return self.prepare_password()
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLNativePasswordAuthPlugin(BaseAuthPlugin):
|
|
||||||
"""Class implementing the MySQL Native Password authentication plugin"""
|
|
||||||
|
|
||||||
requires_ssl = False
|
|
||||||
plugin_name = 'mysql_native_password'
|
|
||||||
|
|
||||||
def prepare_password(self):
|
|
||||||
"""Prepares and returns password as native MySQL 4.1+ password"""
|
|
||||||
if not self._auth_data:
|
|
||||||
raise errors.InterfaceError("Missing authentication data (seed)")
|
|
||||||
|
|
||||||
if not self._password:
|
|
||||||
return b''
|
|
||||||
password = self._password
|
|
||||||
|
|
||||||
if isstr(self._password):
|
|
||||||
password = self._password.encode('utf-8')
|
|
||||||
else:
|
|
||||||
password = self._password
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
password = buffer(password) # pylint: disable=E0602
|
|
||||||
try:
|
|
||||||
auth_data = buffer(self._auth_data) # pylint: disable=E0602
|
|
||||||
except TypeError:
|
|
||||||
raise errors.InterfaceError("Authentication data incorrect")
|
|
||||||
else:
|
|
||||||
password = password
|
|
||||||
auth_data = self._auth_data
|
|
||||||
|
|
||||||
hash4 = None
|
|
||||||
try:
|
|
||||||
hash1 = sha1(password).digest()
|
|
||||||
hash2 = sha1(hash1).digest()
|
|
||||||
hash3 = sha1(auth_data + hash2).digest()
|
|
||||||
if PY2:
|
|
||||||
xored = [ord(h1) ^ ord(h3) for (h1, h3) in zip(hash1, hash3)]
|
|
||||||
else:
|
|
||||||
xored = [h1 ^ h3 for (h1, h3) in zip(hash1, hash3)]
|
|
||||||
hash4 = struct.pack('20B', *xored)
|
|
||||||
except Exception as exc:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
"Failed scrambling password; {0}".format(exc))
|
|
||||||
|
|
||||||
return hash4
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLClearPasswordAuthPlugin(BaseAuthPlugin):
|
|
||||||
"""Class implementing the MySQL Clear Password authentication plugin"""
|
|
||||||
|
|
||||||
requires_ssl = True
|
|
||||||
plugin_name = 'mysql_clear_password'
|
|
||||||
|
|
||||||
def prepare_password(self):
|
|
||||||
"""Returns password as as clear text"""
|
|
||||||
if not self._password:
|
|
||||||
return b'\x00'
|
|
||||||
password = self._password
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
if isinstance(password, unicode): # pylint: disable=E0602
|
|
||||||
password = password.encode('utf8')
|
|
||||||
elif isinstance(password, str):
|
|
||||||
password = password.encode('utf8')
|
|
||||||
|
|
||||||
return password + b'\x00'
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLSHA256PasswordAuthPlugin(BaseAuthPlugin):
|
|
||||||
"""Class implementing the MySQL SHA256 authentication plugin
|
|
||||||
|
|
||||||
Note that encrypting using RSA is not supported since the Python
|
|
||||||
Standard Library does not provide this OpenSSL functionality.
|
|
||||||
"""
|
|
||||||
|
|
||||||
requires_ssl = True
|
|
||||||
plugin_name = 'sha256_password'
|
|
||||||
|
|
||||||
def prepare_password(self):
|
|
||||||
"""Returns password as as clear text"""
|
|
||||||
if not self._password:
|
|
||||||
return b'\x00'
|
|
||||||
password = self._password
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
if isinstance(password, unicode): # pylint: disable=E0602
|
|
||||||
password = password.encode('utf8')
|
|
||||||
elif isinstance(password, str):
|
|
||||||
password = password.encode('utf8')
|
|
||||||
|
|
||||||
return password + b'\x00'
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLCachingSHA2PasswordAuthPlugin(BaseAuthPlugin):
|
|
||||||
"""Class implementing the MySQL caching_sha2_password authentication plugin
|
|
||||||
|
|
||||||
Note that encrypting using RSA is not supported since the Python
|
|
||||||
Standard Library does not provide this OpenSSL functionality.
|
|
||||||
"""
|
|
||||||
requires_ssl = False
|
|
||||||
plugin_name = 'caching_sha2_password'
|
|
||||||
perform_full_authentication = 4
|
|
||||||
fast_auth_success = 3
|
|
||||||
|
|
||||||
def _scramble(self):
|
|
||||||
""" Returns a scramble of the password using a Nonce sent by the
|
|
||||||
server.
|
|
||||||
|
|
||||||
The scramble is of the form:
|
|
||||||
XOR(SHA2(password), SHA2(SHA2(SHA2(password)), Nonce))
|
|
||||||
"""
|
|
||||||
if not self._auth_data:
|
|
||||||
raise errors.InterfaceError("Missing authentication data (seed)")
|
|
||||||
|
|
||||||
if not self._password:
|
|
||||||
return b''
|
|
||||||
|
|
||||||
password = self._password.encode('utf-8') \
|
|
||||||
if isinstance(self._password, UNICODE_TYPES) else self._password
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
password = buffer(password) # pylint: disable=E0602
|
|
||||||
try:
|
|
||||||
auth_data = buffer(self._auth_data) # pylint: disable=E0602
|
|
||||||
except TypeError:
|
|
||||||
raise errors.InterfaceError("Authentication data incorrect")
|
|
||||||
else:
|
|
||||||
password = password
|
|
||||||
auth_data = self._auth_data
|
|
||||||
|
|
||||||
hash1 = sha256(password).digest()
|
|
||||||
hash2 = sha256()
|
|
||||||
hash2.update(sha256(hash1).digest())
|
|
||||||
hash2.update(auth_data)
|
|
||||||
hash2 = hash2.digest()
|
|
||||||
if PY2:
|
|
||||||
xored = [ord(h1) ^ ord(h2) for (h1, h2) in zip(hash1, hash2)]
|
|
||||||
else:
|
|
||||||
xored = [h1 ^ h2 for (h1, h2) in zip(hash1, hash2)]
|
|
||||||
hash3 = struct.pack('32B', *xored)
|
|
||||||
|
|
||||||
return hash3
|
|
||||||
|
|
||||||
def prepare_password(self):
|
|
||||||
if len(self._auth_data) > 1:
|
|
||||||
return self._scramble()
|
|
||||||
elif self._auth_data[0] == self.perform_full_authentication:
|
|
||||||
return self._full_authentication()
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _full_authentication(self):
|
|
||||||
"""Returns password as as clear text"""
|
|
||||||
if not self._ssl_enabled:
|
|
||||||
raise errors.InterfaceError("{name} requires SSL".format(
|
|
||||||
name=self.plugin_name))
|
|
||||||
|
|
||||||
if not self._password:
|
|
||||||
return b'\x00'
|
|
||||||
password = self._password
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
if isinstance(password, unicode): # pylint: disable=E0602
|
|
||||||
password = password.encode('utf8')
|
|
||||||
elif isinstance(password, str):
|
|
||||||
password = password.encode('utf8')
|
|
||||||
|
|
||||||
return password + b'\x00'
|
|
||||||
|
|
||||||
|
|
||||||
def get_auth_plugin(plugin_name):
|
|
||||||
"""Return authentication class based on plugin name
|
|
||||||
|
|
||||||
This function returns the class for the authentication plugin plugin_name.
|
|
||||||
The returned class is a subclass of BaseAuthPlugin.
|
|
||||||
|
|
||||||
Raises errors.NotSupportedError when plugin_name is not supported.
|
|
||||||
|
|
||||||
Returns subclass of BaseAuthPlugin.
|
|
||||||
"""
|
|
||||||
for authclass in BaseAuthPlugin.__subclasses__(): # pylint: disable=E1101
|
|
||||||
if authclass.plugin_name == plugin_name:
|
|
||||||
return authclass
|
|
||||||
|
|
||||||
raise errors.NotSupportedError(
|
|
||||||
"Authentication plugin '{0}' is not supported".format(plugin_name))
|
|
@ -1,116 +0,0 @@
|
|||||||
# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Python v2 to v3 migration module"""
|
|
||||||
|
|
||||||
from decimal import Decimal
|
|
||||||
import struct
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from .custom_types import HexLiteral
|
|
||||||
|
|
||||||
# pylint: disable=E0602,E1103
|
|
||||||
|
|
||||||
PY2 = sys.version_info[0] == 2
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
NUMERIC_TYPES = (int, float, Decimal, HexLiteral, long)
|
|
||||||
INT_TYPES = (int, long)
|
|
||||||
UNICODE_TYPES = (unicode,)
|
|
||||||
STRING_TYPES = (str, unicode)
|
|
||||||
BYTE_TYPES = (bytearray,)
|
|
||||||
else:
|
|
||||||
NUMERIC_TYPES = (int, float, Decimal, HexLiteral)
|
|
||||||
INT_TYPES = (int,)
|
|
||||||
UNICODE_TYPES = (str,)
|
|
||||||
STRING_TYPES = (str,)
|
|
||||||
BYTE_TYPES = (bytearray, bytes)
|
|
||||||
|
|
||||||
|
|
||||||
def init_bytearray(payload=b'', encoding='utf-8'):
|
|
||||||
"""Initializes a bytearray from the payload"""
|
|
||||||
if isinstance(payload, bytearray):
|
|
||||||
return payload
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
return bytearray(payload)
|
|
||||||
|
|
||||||
if isinstance(payload, int):
|
|
||||||
return bytearray(payload)
|
|
||||||
elif not isinstance(payload, bytes):
|
|
||||||
try:
|
|
||||||
return bytearray(payload.encode(encoding=encoding))
|
|
||||||
except AttributeError:
|
|
||||||
raise ValueError("payload must be a str or bytes")
|
|
||||||
|
|
||||||
return bytearray(payload)
|
|
||||||
|
|
||||||
|
|
||||||
def isstr(obj):
|
|
||||||
"""Returns whether a variable is a string"""
|
|
||||||
if PY2:
|
|
||||||
return isinstance(obj, basestring)
|
|
||||||
return isinstance(obj, str)
|
|
||||||
|
|
||||||
def isunicode(obj):
|
|
||||||
"""Returns whether a variable is a of unicode type"""
|
|
||||||
if PY2:
|
|
||||||
return isinstance(obj, unicode)
|
|
||||||
return isinstance(obj, str)
|
|
||||||
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
def struct_unpack(fmt, buf):
|
|
||||||
"""Wrapper around struct.unpack handling buffer as bytes and strings"""
|
|
||||||
if isinstance(buf, (bytearray, bytes)):
|
|
||||||
return struct.unpack_from(fmt, buffer(buf))
|
|
||||||
return struct.unpack_from(fmt, buf)
|
|
||||||
else:
|
|
||||||
struct_unpack = struct.unpack # pylint: disable=C0103
|
|
||||||
|
|
||||||
|
|
||||||
def make_abc(base_class):
|
|
||||||
"""Decorator used to create a abstract base class
|
|
||||||
|
|
||||||
We use this decorator to create abstract base classes instead of
|
|
||||||
using the abc-module. The decorator makes it possible to do the
|
|
||||||
same in both Python v2 and v3 code.
|
|
||||||
"""
|
|
||||||
def wrapper(class_):
|
|
||||||
"""Wrapper"""
|
|
||||||
attrs = class_.__dict__.copy()
|
|
||||||
for attr in '__dict__', '__weakref__':
|
|
||||||
attrs.pop(attr, None) # ignore missing attributes
|
|
||||||
|
|
||||||
bases = class_.__bases__
|
|
||||||
if PY2:
|
|
||||||
attrs['__metaclass__'] = class_
|
|
||||||
else:
|
|
||||||
bases = (class_,) + bases
|
|
||||||
return base_class(class_.__name__, bases, attrs)
|
|
||||||
return wrapper
|
|
@ -1,350 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
# This file was auto-generated.
|
|
||||||
_GENERATED_ON = '2019-04-29'
|
|
||||||
_MYSQL_VERSION = (8, 0, 17)
|
|
||||||
|
|
||||||
"""This module contains the MySQL Server Character Sets"""
|
|
||||||
|
|
||||||
MYSQL_CHARACTER_SETS = [
|
|
||||||
# (character set name, collation, default)
|
|
||||||
None,
|
|
||||||
("big5", "big5_chinese_ci", True), # 1
|
|
||||||
("latin2", "latin2_czech_cs", False), # 2
|
|
||||||
("dec8", "dec8_swedish_ci", True), # 3
|
|
||||||
("cp850", "cp850_general_ci", True), # 4
|
|
||||||
("latin1", "latin1_german1_ci", False), # 5
|
|
||||||
("hp8", "hp8_english_ci", True), # 6
|
|
||||||
("koi8r", "koi8r_general_ci", True), # 7
|
|
||||||
("latin1", "latin1_swedish_ci", True), # 8
|
|
||||||
("latin2", "latin2_general_ci", True), # 9
|
|
||||||
("swe7", "swe7_swedish_ci", True), # 10
|
|
||||||
("ascii", "ascii_general_ci", True), # 11
|
|
||||||
("ujis", "ujis_japanese_ci", True), # 12
|
|
||||||
("sjis", "sjis_japanese_ci", True), # 13
|
|
||||||
("cp1251", "cp1251_bulgarian_ci", False), # 14
|
|
||||||
("latin1", "latin1_danish_ci", False), # 15
|
|
||||||
("hebrew", "hebrew_general_ci", True), # 16
|
|
||||||
None,
|
|
||||||
("tis620", "tis620_thai_ci", True), # 18
|
|
||||||
("euckr", "euckr_korean_ci", True), # 19
|
|
||||||
("latin7", "latin7_estonian_cs", False), # 20
|
|
||||||
("latin2", "latin2_hungarian_ci", False), # 21
|
|
||||||
("koi8u", "koi8u_general_ci", True), # 22
|
|
||||||
("cp1251", "cp1251_ukrainian_ci", False), # 23
|
|
||||||
("gb2312", "gb2312_chinese_ci", True), # 24
|
|
||||||
("greek", "greek_general_ci", True), # 25
|
|
||||||
("cp1250", "cp1250_general_ci", True), # 26
|
|
||||||
("latin2", "latin2_croatian_ci", False), # 27
|
|
||||||
("gbk", "gbk_chinese_ci", True), # 28
|
|
||||||
("cp1257", "cp1257_lithuanian_ci", False), # 29
|
|
||||||
("latin5", "latin5_turkish_ci", True), # 30
|
|
||||||
("latin1", "latin1_german2_ci", False), # 31
|
|
||||||
("armscii8", "armscii8_general_ci", True), # 32
|
|
||||||
("utf8", "utf8_general_ci", True), # 33
|
|
||||||
("cp1250", "cp1250_czech_cs", False), # 34
|
|
||||||
("ucs2", "ucs2_general_ci", True), # 35
|
|
||||||
("cp866", "cp866_general_ci", True), # 36
|
|
||||||
("keybcs2", "keybcs2_general_ci", True), # 37
|
|
||||||
("macce", "macce_general_ci", True), # 38
|
|
||||||
("macroman", "macroman_general_ci", True), # 39
|
|
||||||
("cp852", "cp852_general_ci", True), # 40
|
|
||||||
("latin7", "latin7_general_ci", True), # 41
|
|
||||||
("latin7", "latin7_general_cs", False), # 42
|
|
||||||
("macce", "macce_bin", False), # 43
|
|
||||||
("cp1250", "cp1250_croatian_ci", False), # 44
|
|
||||||
("utf8mb4", "utf8mb4_general_ci", False), # 45
|
|
||||||
("utf8mb4", "utf8mb4_bin", False), # 46
|
|
||||||
("latin1", "latin1_bin", False), # 47
|
|
||||||
("latin1", "latin1_general_ci", False), # 48
|
|
||||||
("latin1", "latin1_general_cs", False), # 49
|
|
||||||
("cp1251", "cp1251_bin", False), # 50
|
|
||||||
("cp1251", "cp1251_general_ci", True), # 51
|
|
||||||
("cp1251", "cp1251_general_cs", False), # 52
|
|
||||||
("macroman", "macroman_bin", False), # 53
|
|
||||||
("utf16", "utf16_general_ci", True), # 54
|
|
||||||
("utf16", "utf16_bin", False), # 55
|
|
||||||
("utf16le", "utf16le_general_ci", True), # 56
|
|
||||||
("cp1256", "cp1256_general_ci", True), # 57
|
|
||||||
("cp1257", "cp1257_bin", False), # 58
|
|
||||||
("cp1257", "cp1257_general_ci", True), # 59
|
|
||||||
("utf32", "utf32_general_ci", True), # 60
|
|
||||||
("utf32", "utf32_bin", False), # 61
|
|
||||||
("utf16le", "utf16le_bin", False), # 62
|
|
||||||
("binary", "binary", True), # 63
|
|
||||||
("armscii8", "armscii8_bin", False), # 64
|
|
||||||
("ascii", "ascii_bin", False), # 65
|
|
||||||
("cp1250", "cp1250_bin", False), # 66
|
|
||||||
("cp1256", "cp1256_bin", False), # 67
|
|
||||||
("cp866", "cp866_bin", False), # 68
|
|
||||||
("dec8", "dec8_bin", False), # 69
|
|
||||||
("greek", "greek_bin", False), # 70
|
|
||||||
("hebrew", "hebrew_bin", False), # 71
|
|
||||||
("hp8", "hp8_bin", False), # 72
|
|
||||||
("keybcs2", "keybcs2_bin", False), # 73
|
|
||||||
("koi8r", "koi8r_bin", False), # 74
|
|
||||||
("koi8u", "koi8u_bin", False), # 75
|
|
||||||
("utf8", "utf8_tolower_ci", False), # 76
|
|
||||||
("latin2", "latin2_bin", False), # 77
|
|
||||||
("latin5", "latin5_bin", False), # 78
|
|
||||||
("latin7", "latin7_bin", False), # 79
|
|
||||||
("cp850", "cp850_bin", False), # 80
|
|
||||||
("cp852", "cp852_bin", False), # 81
|
|
||||||
("swe7", "swe7_bin", False), # 82
|
|
||||||
("utf8", "utf8_bin", False), # 83
|
|
||||||
("big5", "big5_bin", False), # 84
|
|
||||||
("euckr", "euckr_bin", False), # 85
|
|
||||||
("gb2312", "gb2312_bin", False), # 86
|
|
||||||
("gbk", "gbk_bin", False), # 87
|
|
||||||
("sjis", "sjis_bin", False), # 88
|
|
||||||
("tis620", "tis620_bin", False), # 89
|
|
||||||
("ucs2", "ucs2_bin", False), # 90
|
|
||||||
("ujis", "ujis_bin", False), # 91
|
|
||||||
("geostd8", "geostd8_general_ci", True), # 92
|
|
||||||
("geostd8", "geostd8_bin", False), # 93
|
|
||||||
("latin1", "latin1_spanish_ci", False), # 94
|
|
||||||
("cp932", "cp932_japanese_ci", True), # 95
|
|
||||||
("cp932", "cp932_bin", False), # 96
|
|
||||||
("eucjpms", "eucjpms_japanese_ci", True), # 97
|
|
||||||
("eucjpms", "eucjpms_bin", False), # 98
|
|
||||||
("cp1250", "cp1250_polish_ci", False), # 99
|
|
||||||
None,
|
|
||||||
("utf16", "utf16_unicode_ci", False), # 101
|
|
||||||
("utf16", "utf16_icelandic_ci", False), # 102
|
|
||||||
("utf16", "utf16_latvian_ci", False), # 103
|
|
||||||
("utf16", "utf16_romanian_ci", False), # 104
|
|
||||||
("utf16", "utf16_slovenian_ci", False), # 105
|
|
||||||
("utf16", "utf16_polish_ci", False), # 106
|
|
||||||
("utf16", "utf16_estonian_ci", False), # 107
|
|
||||||
("utf16", "utf16_spanish_ci", False), # 108
|
|
||||||
("utf16", "utf16_swedish_ci", False), # 109
|
|
||||||
("utf16", "utf16_turkish_ci", False), # 110
|
|
||||||
("utf16", "utf16_czech_ci", False), # 111
|
|
||||||
("utf16", "utf16_danish_ci", False), # 112
|
|
||||||
("utf16", "utf16_lithuanian_ci", False), # 113
|
|
||||||
("utf16", "utf16_slovak_ci", False), # 114
|
|
||||||
("utf16", "utf16_spanish2_ci", False), # 115
|
|
||||||
("utf16", "utf16_roman_ci", False), # 116
|
|
||||||
("utf16", "utf16_persian_ci", False), # 117
|
|
||||||
("utf16", "utf16_esperanto_ci", False), # 118
|
|
||||||
("utf16", "utf16_hungarian_ci", False), # 119
|
|
||||||
("utf16", "utf16_sinhala_ci", False), # 120
|
|
||||||
("utf16", "utf16_german2_ci", False), # 121
|
|
||||||
("utf16", "utf16_croatian_ci", False), # 122
|
|
||||||
("utf16", "utf16_unicode_520_ci", False), # 123
|
|
||||||
("utf16", "utf16_vietnamese_ci", False), # 124
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("ucs2", "ucs2_unicode_ci", False), # 128
|
|
||||||
("ucs2", "ucs2_icelandic_ci", False), # 129
|
|
||||||
("ucs2", "ucs2_latvian_ci", False), # 130
|
|
||||||
("ucs2", "ucs2_romanian_ci", False), # 131
|
|
||||||
("ucs2", "ucs2_slovenian_ci", False), # 132
|
|
||||||
("ucs2", "ucs2_polish_ci", False), # 133
|
|
||||||
("ucs2", "ucs2_estonian_ci", False), # 134
|
|
||||||
("ucs2", "ucs2_spanish_ci", False), # 135
|
|
||||||
("ucs2", "ucs2_swedish_ci", False), # 136
|
|
||||||
("ucs2", "ucs2_turkish_ci", False), # 137
|
|
||||||
("ucs2", "ucs2_czech_ci", False), # 138
|
|
||||||
("ucs2", "ucs2_danish_ci", False), # 139
|
|
||||||
("ucs2", "ucs2_lithuanian_ci", False), # 140
|
|
||||||
("ucs2", "ucs2_slovak_ci", False), # 141
|
|
||||||
("ucs2", "ucs2_spanish2_ci", False), # 142
|
|
||||||
("ucs2", "ucs2_roman_ci", False), # 143
|
|
||||||
("ucs2", "ucs2_persian_ci", False), # 144
|
|
||||||
("ucs2", "ucs2_esperanto_ci", False), # 145
|
|
||||||
("ucs2", "ucs2_hungarian_ci", False), # 146
|
|
||||||
("ucs2", "ucs2_sinhala_ci", False), # 147
|
|
||||||
("ucs2", "ucs2_german2_ci", False), # 148
|
|
||||||
("ucs2", "ucs2_croatian_ci", False), # 149
|
|
||||||
("ucs2", "ucs2_unicode_520_ci", False), # 150
|
|
||||||
("ucs2", "ucs2_vietnamese_ci", False), # 151
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("ucs2", "ucs2_general_mysql500_ci", False), # 159
|
|
||||||
("utf32", "utf32_unicode_ci", False), # 160
|
|
||||||
("utf32", "utf32_icelandic_ci", False), # 161
|
|
||||||
("utf32", "utf32_latvian_ci", False), # 162
|
|
||||||
("utf32", "utf32_romanian_ci", False), # 163
|
|
||||||
("utf32", "utf32_slovenian_ci", False), # 164
|
|
||||||
("utf32", "utf32_polish_ci", False), # 165
|
|
||||||
("utf32", "utf32_estonian_ci", False), # 166
|
|
||||||
("utf32", "utf32_spanish_ci", False), # 167
|
|
||||||
("utf32", "utf32_swedish_ci", False), # 168
|
|
||||||
("utf32", "utf32_turkish_ci", False), # 169
|
|
||||||
("utf32", "utf32_czech_ci", False), # 170
|
|
||||||
("utf32", "utf32_danish_ci", False), # 171
|
|
||||||
("utf32", "utf32_lithuanian_ci", False), # 172
|
|
||||||
("utf32", "utf32_slovak_ci", False), # 173
|
|
||||||
("utf32", "utf32_spanish2_ci", False), # 174
|
|
||||||
("utf32", "utf32_roman_ci", False), # 175
|
|
||||||
("utf32", "utf32_persian_ci", False), # 176
|
|
||||||
("utf32", "utf32_esperanto_ci", False), # 177
|
|
||||||
("utf32", "utf32_hungarian_ci", False), # 178
|
|
||||||
("utf32", "utf32_sinhala_ci", False), # 179
|
|
||||||
("utf32", "utf32_german2_ci", False), # 180
|
|
||||||
("utf32", "utf32_croatian_ci", False), # 181
|
|
||||||
("utf32", "utf32_unicode_520_ci", False), # 182
|
|
||||||
("utf32", "utf32_vietnamese_ci", False), # 183
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("utf8", "utf8_unicode_ci", False), # 192
|
|
||||||
("utf8", "utf8_icelandic_ci", False), # 193
|
|
||||||
("utf8", "utf8_latvian_ci", False), # 194
|
|
||||||
("utf8", "utf8_romanian_ci", False), # 195
|
|
||||||
("utf8", "utf8_slovenian_ci", False), # 196
|
|
||||||
("utf8", "utf8_polish_ci", False), # 197
|
|
||||||
("utf8", "utf8_estonian_ci", False), # 198
|
|
||||||
("utf8", "utf8_spanish_ci", False), # 199
|
|
||||||
("utf8", "utf8_swedish_ci", False), # 200
|
|
||||||
("utf8", "utf8_turkish_ci", False), # 201
|
|
||||||
("utf8", "utf8_czech_ci", False), # 202
|
|
||||||
("utf8", "utf8_danish_ci", False), # 203
|
|
||||||
("utf8", "utf8_lithuanian_ci", False), # 204
|
|
||||||
("utf8", "utf8_slovak_ci", False), # 205
|
|
||||||
("utf8", "utf8_spanish2_ci", False), # 206
|
|
||||||
("utf8", "utf8_roman_ci", False), # 207
|
|
||||||
("utf8", "utf8_persian_ci", False), # 208
|
|
||||||
("utf8", "utf8_esperanto_ci", False), # 209
|
|
||||||
("utf8", "utf8_hungarian_ci", False), # 210
|
|
||||||
("utf8", "utf8_sinhala_ci", False), # 211
|
|
||||||
("utf8", "utf8_german2_ci", False), # 212
|
|
||||||
("utf8", "utf8_croatian_ci", False), # 213
|
|
||||||
("utf8", "utf8_unicode_520_ci", False), # 214
|
|
||||||
("utf8", "utf8_vietnamese_ci", False), # 215
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("utf8", "utf8_general_mysql500_ci", False), # 223
|
|
||||||
("utf8mb4", "utf8mb4_unicode_ci", False), # 224
|
|
||||||
("utf8mb4", "utf8mb4_icelandic_ci", False), # 225
|
|
||||||
("utf8mb4", "utf8mb4_latvian_ci", False), # 226
|
|
||||||
("utf8mb4", "utf8mb4_romanian_ci", False), # 227
|
|
||||||
("utf8mb4", "utf8mb4_slovenian_ci", False), # 228
|
|
||||||
("utf8mb4", "utf8mb4_polish_ci", False), # 229
|
|
||||||
("utf8mb4", "utf8mb4_estonian_ci", False), # 230
|
|
||||||
("utf8mb4", "utf8mb4_spanish_ci", False), # 231
|
|
||||||
("utf8mb4", "utf8mb4_swedish_ci", False), # 232
|
|
||||||
("utf8mb4", "utf8mb4_turkish_ci", False), # 233
|
|
||||||
("utf8mb4", "utf8mb4_czech_ci", False), # 234
|
|
||||||
("utf8mb4", "utf8mb4_danish_ci", False), # 235
|
|
||||||
("utf8mb4", "utf8mb4_lithuanian_ci", False), # 236
|
|
||||||
("utf8mb4", "utf8mb4_slovak_ci", False), # 237
|
|
||||||
("utf8mb4", "utf8mb4_spanish2_ci", False), # 238
|
|
||||||
("utf8mb4", "utf8mb4_roman_ci", False), # 239
|
|
||||||
("utf8mb4", "utf8mb4_persian_ci", False), # 240
|
|
||||||
("utf8mb4", "utf8mb4_esperanto_ci", False), # 241
|
|
||||||
("utf8mb4", "utf8mb4_hungarian_ci", False), # 242
|
|
||||||
("utf8mb4", "utf8mb4_sinhala_ci", False), # 243
|
|
||||||
("utf8mb4", "utf8mb4_german2_ci", False), # 244
|
|
||||||
("utf8mb4", "utf8mb4_croatian_ci", False), # 245
|
|
||||||
("utf8mb4", "utf8mb4_unicode_520_ci", False), # 246
|
|
||||||
("utf8mb4", "utf8mb4_vietnamese_ci", False), # 247
|
|
||||||
("gb18030", "gb18030_chinese_ci", True), # 248
|
|
||||||
("gb18030", "gb18030_bin", False), # 249
|
|
||||||
("gb18030", "gb18030_unicode_520_ci", False), # 250
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_0900_ai_ci", True), # 255
|
|
||||||
("utf8mb4", "utf8mb4_de_pb_0900_ai_ci", False), # 256
|
|
||||||
("utf8mb4", "utf8mb4_is_0900_ai_ci", False), # 257
|
|
||||||
("utf8mb4", "utf8mb4_lv_0900_ai_ci", False), # 258
|
|
||||||
("utf8mb4", "utf8mb4_ro_0900_ai_ci", False), # 259
|
|
||||||
("utf8mb4", "utf8mb4_sl_0900_ai_ci", False), # 260
|
|
||||||
("utf8mb4", "utf8mb4_pl_0900_ai_ci", False), # 261
|
|
||||||
("utf8mb4", "utf8mb4_et_0900_ai_ci", False), # 262
|
|
||||||
("utf8mb4", "utf8mb4_es_0900_ai_ci", False), # 263
|
|
||||||
("utf8mb4", "utf8mb4_sv_0900_ai_ci", False), # 264
|
|
||||||
("utf8mb4", "utf8mb4_tr_0900_ai_ci", False), # 265
|
|
||||||
("utf8mb4", "utf8mb4_cs_0900_ai_ci", False), # 266
|
|
||||||
("utf8mb4", "utf8mb4_da_0900_ai_ci", False), # 267
|
|
||||||
("utf8mb4", "utf8mb4_lt_0900_ai_ci", False), # 268
|
|
||||||
("utf8mb4", "utf8mb4_sk_0900_ai_ci", False), # 269
|
|
||||||
("utf8mb4", "utf8mb4_es_trad_0900_ai_ci", False), # 270
|
|
||||||
("utf8mb4", "utf8mb4_la_0900_ai_ci", False), # 271
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_eo_0900_ai_ci", False), # 273
|
|
||||||
("utf8mb4", "utf8mb4_hu_0900_ai_ci", False), # 274
|
|
||||||
("utf8mb4", "utf8mb4_hr_0900_ai_ci", False), # 275
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_vi_0900_ai_ci", False), # 277
|
|
||||||
("utf8mb4", "utf8mb4_0900_as_cs", False), # 278
|
|
||||||
("utf8mb4", "utf8mb4_de_pb_0900_as_cs", False), # 279
|
|
||||||
("utf8mb4", "utf8mb4_is_0900_as_cs", False), # 280
|
|
||||||
("utf8mb4", "utf8mb4_lv_0900_as_cs", False), # 281
|
|
||||||
("utf8mb4", "utf8mb4_ro_0900_as_cs", False), # 282
|
|
||||||
("utf8mb4", "utf8mb4_sl_0900_as_cs", False), # 283
|
|
||||||
("utf8mb4", "utf8mb4_pl_0900_as_cs", False), # 284
|
|
||||||
("utf8mb4", "utf8mb4_et_0900_as_cs", False), # 285
|
|
||||||
("utf8mb4", "utf8mb4_es_0900_as_cs", False), # 286
|
|
||||||
("utf8mb4", "utf8mb4_sv_0900_as_cs", False), # 287
|
|
||||||
("utf8mb4", "utf8mb4_tr_0900_as_cs", False), # 288
|
|
||||||
("utf8mb4", "utf8mb4_cs_0900_as_cs", False), # 289
|
|
||||||
("utf8mb4", "utf8mb4_da_0900_as_cs", False), # 290
|
|
||||||
("utf8mb4", "utf8mb4_lt_0900_as_cs", False), # 291
|
|
||||||
("utf8mb4", "utf8mb4_sk_0900_as_cs", False), # 292
|
|
||||||
("utf8mb4", "utf8mb4_es_trad_0900_as_cs", False), # 293
|
|
||||||
("utf8mb4", "utf8mb4_la_0900_as_cs", False), # 294
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_eo_0900_as_cs", False), # 296
|
|
||||||
("utf8mb4", "utf8mb4_hu_0900_as_cs", False), # 297
|
|
||||||
("utf8mb4", "utf8mb4_hr_0900_as_cs", False), # 298
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_vi_0900_as_cs", False), # 300
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_ja_0900_as_cs", False), # 303
|
|
||||||
("utf8mb4", "utf8mb4_ja_0900_as_cs_ks", False), # 304
|
|
||||||
("utf8mb4", "utf8mb4_0900_as_ci", False), # 305
|
|
||||||
("utf8mb4", "utf8mb4_ru_0900_ai_ci", False), # 306
|
|
||||||
("utf8mb4", "utf8mb4_ru_0900_as_cs", False), # 307
|
|
||||||
("utf8mb4", "utf8mb4_zh_0900_as_cs", False), # 308
|
|
||||||
("utf8mb4", "utf8mb4_0900_bin", False), # 309
|
|
||||||
]
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,712 +0,0 @@
|
|||||||
# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Connection class using the C Extension
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Detection of abstract methods in pylint is not working correctly
|
|
||||||
#pylint: disable=W0223
|
|
||||||
|
|
||||||
import socket
|
|
||||||
|
|
||||||
from . import errors, version
|
|
||||||
from .catch23 import INT_TYPES
|
|
||||||
from .constants import (
|
|
||||||
CharacterSet, FieldFlag, ServerFlag, ShutdownType, ClientFlag
|
|
||||||
)
|
|
||||||
from .abstracts import MySQLConnectionAbstract, MySQLCursorAbstract
|
|
||||||
from .protocol import MySQLProtocol
|
|
||||||
|
|
||||||
HAVE_CMYSQL = False
|
|
||||||
# pylint: disable=F0401,C0413
|
|
||||||
try:
|
|
||||||
import _mysql_connector
|
|
||||||
from .cursor_cext import (
|
|
||||||
CMySQLCursor, CMySQLCursorRaw,
|
|
||||||
CMySQLCursorBuffered, CMySQLCursorBufferedRaw, CMySQLCursorPrepared,
|
|
||||||
CMySQLCursorDict, CMySQLCursorBufferedDict, CMySQLCursorNamedTuple,
|
|
||||||
CMySQLCursorBufferedNamedTuple)
|
|
||||||
from _mysql_connector import MySQLInterfaceError # pylint: disable=F0401
|
|
||||||
except ImportError as exc:
|
|
||||||
raise ImportError(
|
|
||||||
"MySQL Connector/Python C Extension not available ({0})".format(
|
|
||||||
str(exc)
|
|
||||||
))
|
|
||||||
else:
|
|
||||||
HAVE_CMYSQL = True
|
|
||||||
# pylint: enable=F0401,C0413
|
|
||||||
|
|
||||||
|
|
||||||
class CMySQLConnection(MySQLConnectionAbstract):
|
|
||||||
|
|
||||||
"""Class initiating a MySQL Connection using Connector/C"""
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
"""Initialization"""
|
|
||||||
if not HAVE_CMYSQL:
|
|
||||||
raise RuntimeError(
|
|
||||||
"MySQL Connector/Python C Extension not available")
|
|
||||||
self._cmysql = None
|
|
||||||
self._columns = []
|
|
||||||
self.converter = None
|
|
||||||
super(CMySQLConnection, self).__init__(**kwargs)
|
|
||||||
|
|
||||||
if kwargs:
|
|
||||||
self.connect(**kwargs)
|
|
||||||
|
|
||||||
def _add_default_conn_attrs(self):
|
|
||||||
"""Add default connection attributes"""
|
|
||||||
license_chunks = version.LICENSE.split(" ")
|
|
||||||
if license_chunks[0] == "GPLv2":
|
|
||||||
client_license = "GPL-2.0"
|
|
||||||
else:
|
|
||||||
client_license = "Commercial"
|
|
||||||
|
|
||||||
self._conn_attrs.update({
|
|
||||||
"_connector_name": "mysql-connector-python",
|
|
||||||
"_connector_license": client_license,
|
|
||||||
"_connector_version": ".".join(
|
|
||||||
[str(x) for x in version.VERSION[0:3]]),
|
|
||||||
"_source_host": socket.gethostname()
|
|
||||||
})
|
|
||||||
|
|
||||||
def _do_handshake(self):
|
|
||||||
"""Gather information of the MySQL server before authentication"""
|
|
||||||
self._handshake = {
|
|
||||||
'protocol': self._cmysql.get_proto_info(),
|
|
||||||
'server_version_original': self._cmysql.get_server_info(),
|
|
||||||
'server_threadid': self._cmysql.thread_id(),
|
|
||||||
'charset': None,
|
|
||||||
'server_status': None,
|
|
||||||
'auth_plugin': None,
|
|
||||||
'auth_data': None,
|
|
||||||
'capabilities': self._cmysql.st_server_capabilities(),
|
|
||||||
}
|
|
||||||
|
|
||||||
self._server_version = self._check_server_version(
|
|
||||||
self._handshake['server_version_original']
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def _server_status(self):
|
|
||||||
"""Returns the server status attribute of MYSQL structure"""
|
|
||||||
return self._cmysql.st_server_status()
|
|
||||||
|
|
||||||
def set_unicode(self, value=True):
|
|
||||||
"""Toggle unicode mode
|
|
||||||
|
|
||||||
Set whether we return string fields as unicode or not.
|
|
||||||
Default is True.
|
|
||||||
"""
|
|
||||||
self._use_unicode = value
|
|
||||||
if self._cmysql:
|
|
||||||
self._cmysql.use_unicode(value)
|
|
||||||
if self.converter:
|
|
||||||
self.converter.set_unicode(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def autocommit(self):
|
|
||||||
"""Get whether autocommit is on or off"""
|
|
||||||
value = self.info_query("SELECT @@session.autocommit")[0]
|
|
||||||
return True if value == 1 else False
|
|
||||||
|
|
||||||
@autocommit.setter
|
|
||||||
def autocommit(self, value): # pylint: disable=W0221
|
|
||||||
"""Toggle autocommit"""
|
|
||||||
try:
|
|
||||||
self._cmysql.autocommit(value)
|
|
||||||
self._autocommit = value
|
|
||||||
except MySQLInterfaceError as exc:
|
|
||||||
raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def database(self):
|
|
||||||
"""Get the current database"""
|
|
||||||
return self.info_query("SELECT DATABASE()")[0]
|
|
||||||
|
|
||||||
@database.setter
|
|
||||||
def database(self, value): # pylint: disable=W0221
|
|
||||||
"""Set the current database"""
|
|
||||||
self._cmysql.select_db(value)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def in_transaction(self):
|
|
||||||
"""MySQL session has started a transaction"""
|
|
||||||
return self._server_status & ServerFlag.STATUS_IN_TRANS
|
|
||||||
|
|
||||||
def _open_connection(self):
|
|
||||||
charset_name = CharacterSet.get_info(self._charset_id)[0]
|
|
||||||
self._cmysql = _mysql_connector.MySQL( # pylint: disable=E1101,I1101
|
|
||||||
buffered=self._buffered,
|
|
||||||
raw=self._raw,
|
|
||||||
charset_name=charset_name,
|
|
||||||
connection_timeout=(self._connection_timeout or 0),
|
|
||||||
use_unicode=self._use_unicode,
|
|
||||||
auth_plugin=self._auth_plugin)
|
|
||||||
|
|
||||||
if not self.isset_client_flag(ClientFlag.CONNECT_ARGS):
|
|
||||||
self._conn_attrs = {}
|
|
||||||
cnx_kwargs = {
|
|
||||||
'host': self._host,
|
|
||||||
'user': self._user,
|
|
||||||
'password': self._password,
|
|
||||||
'database': self._database,
|
|
||||||
'port': self._port,
|
|
||||||
'client_flags': self._client_flags,
|
|
||||||
'unix_socket': self._unix_socket,
|
|
||||||
'compress': self.isset_client_flag(ClientFlag.COMPRESS),
|
|
||||||
'ssl_disabled': True,
|
|
||||||
"conn_attrs": self._conn_attrs
|
|
||||||
}
|
|
||||||
|
|
||||||
tls_versions = self._ssl.get('tls_versions')
|
|
||||||
if tls_versions is not None:
|
|
||||||
tls_versions.sort(reverse=True)
|
|
||||||
tls_versions = ",".join(tls_versions)
|
|
||||||
if self._ssl.get('tls_ciphersuites') is not None:
|
|
||||||
ssl_ciphersuites = self._ssl.get('tls_ciphersuites')[0]
|
|
||||||
tls_ciphersuites = self._ssl.get('tls_ciphersuites')[1]
|
|
||||||
else:
|
|
||||||
ssl_ciphersuites = None
|
|
||||||
tls_ciphersuites = None
|
|
||||||
if tls_versions is not None and "TLSv1.3" in tls_versions and \
|
|
||||||
not tls_ciphersuites:
|
|
||||||
tls_ciphersuites = "TLS_AES_256_GCM_SHA384"
|
|
||||||
if not self._ssl_disabled:
|
|
||||||
cnx_kwargs.update({
|
|
||||||
'ssl_ca': self._ssl.get('ca'),
|
|
||||||
'ssl_cert': self._ssl.get('cert'),
|
|
||||||
'ssl_key': self._ssl.get('key'),
|
|
||||||
'ssl_cipher_suites': ssl_ciphersuites,
|
|
||||||
'tls_versions': tls_versions,
|
|
||||||
'tls_cipher_suites': tls_ciphersuites,
|
|
||||||
'ssl_verify_cert': self._ssl.get('verify_cert') or False,
|
|
||||||
'ssl_verify_identity':
|
|
||||||
self._ssl.get('verify_identity') or False,
|
|
||||||
'ssl_disabled': self._ssl_disabled
|
|
||||||
})
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._cmysql.connect(**cnx_kwargs)
|
|
||||||
except MySQLInterfaceError as exc:
|
|
||||||
raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
|
|
||||||
self._do_handshake()
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
"""Disconnect from the MySQL server"""
|
|
||||||
if self._cmysql:
|
|
||||||
try:
|
|
||||||
self.free_result()
|
|
||||||
self._cmysql.close()
|
|
||||||
except MySQLInterfaceError as exc:
|
|
||||||
raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
self._cmysql = None
|
|
||||||
disconnect = close
|
|
||||||
|
|
||||||
def is_connected(self):
|
|
||||||
"""Reports whether the connection to MySQL Server is available"""
|
|
||||||
if self._cmysql:
|
|
||||||
return self._cmysql.ping()
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def ping(self, reconnect=False, attempts=1, delay=0):
|
|
||||||
"""Check availability of the MySQL server
|
|
||||||
|
|
||||||
When reconnect is set to True, one or more attempts are made to try
|
|
||||||
to reconnect to the MySQL server using the reconnect()-method.
|
|
||||||
|
|
||||||
delay is the number of seconds to wait between each retry.
|
|
||||||
|
|
||||||
When the connection is not available, an InterfaceError is raised. Use
|
|
||||||
the is_connected()-method if you just want to check the connection
|
|
||||||
without raising an error.
|
|
||||||
|
|
||||||
Raises InterfaceError on errors.
|
|
||||||
"""
|
|
||||||
errmsg = "Connection to MySQL is not available"
|
|
||||||
|
|
||||||
try:
|
|
||||||
connected = self._cmysql.ping()
|
|
||||||
except AttributeError:
|
|
||||||
pass # Raise or reconnect later
|
|
||||||
else:
|
|
||||||
if connected:
|
|
||||||
return
|
|
||||||
|
|
||||||
if reconnect:
|
|
||||||
self.reconnect(attempts=attempts, delay=delay)
|
|
||||||
else:
|
|
||||||
raise errors.InterfaceError(errmsg)
|
|
||||||
|
|
||||||
def set_character_set_name(self, charset):
|
|
||||||
"""Sets the default character set name for current connection.
|
|
||||||
"""
|
|
||||||
self._cmysql.set_character_set(charset)
|
|
||||||
|
|
||||||
def info_query(self, query):
|
|
||||||
"""Send a query which only returns 1 row"""
|
|
||||||
self._cmysql.query(query)
|
|
||||||
first_row = ()
|
|
||||||
if self._cmysql.have_result_set:
|
|
||||||
first_row = self._cmysql.fetch_row()
|
|
||||||
if self._cmysql.fetch_row():
|
|
||||||
self._cmysql.free_result()
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
"Query should not return more than 1 row")
|
|
||||||
self._cmysql.free_result()
|
|
||||||
|
|
||||||
return first_row
|
|
||||||
|
|
||||||
@property
|
|
||||||
def connection_id(self):
|
|
||||||
"""MySQL connection ID"""
|
|
||||||
try:
|
|
||||||
return self._cmysql.thread_id()
|
|
||||||
except MySQLInterfaceError:
|
|
||||||
pass # Just return None
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_rows(self, count=None, binary=False, columns=None, raw=None,
|
|
||||||
prep_stmt=None):
|
|
||||||
"""Get all or a subset of rows returned by the MySQL server"""
|
|
||||||
unread_result = prep_stmt.have_result_set if prep_stmt \
|
|
||||||
else self.unread_result
|
|
||||||
if not (self._cmysql and unread_result):
|
|
||||||
raise errors.InternalError("No result set available")
|
|
||||||
|
|
||||||
if raw is None:
|
|
||||||
raw = self._raw
|
|
||||||
|
|
||||||
rows = []
|
|
||||||
if count is not None and count <= 0:
|
|
||||||
raise AttributeError("count should be 1 or higher, or None")
|
|
||||||
|
|
||||||
counter = 0
|
|
||||||
try:
|
|
||||||
row = prep_stmt.fetch_row() if prep_stmt \
|
|
||||||
else self._cmysql.fetch_row()
|
|
||||||
while row:
|
|
||||||
if not self._raw and self.converter:
|
|
||||||
row = list(row)
|
|
||||||
for i, _ in enumerate(row):
|
|
||||||
if not raw:
|
|
||||||
row[i] = self.converter.to_python(self._columns[i],
|
|
||||||
row[i])
|
|
||||||
row = tuple(row)
|
|
||||||
rows.append(row)
|
|
||||||
counter += 1
|
|
||||||
if count and counter == count:
|
|
||||||
break
|
|
||||||
row = prep_stmt.fetch_row() if prep_stmt \
|
|
||||||
else self._cmysql.fetch_row()
|
|
||||||
if not row:
|
|
||||||
_eof = self.fetch_eof_columns(prep_stmt)['eof']
|
|
||||||
if prep_stmt:
|
|
||||||
prep_stmt.free_result()
|
|
||||||
self._unread_result = False
|
|
||||||
else:
|
|
||||||
self.free_result()
|
|
||||||
else:
|
|
||||||
_eof = None
|
|
||||||
except MySQLInterfaceError as exc:
|
|
||||||
if prep_stmt:
|
|
||||||
prep_stmt.free_result()
|
|
||||||
raise errors.InterfaceError(str(exc))
|
|
||||||
else:
|
|
||||||
self.free_result()
|
|
||||||
raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
|
|
||||||
return rows, _eof
|
|
||||||
|
|
||||||
def get_row(self, binary=False, columns=None, raw=None, prep_stmt=None):
|
|
||||||
"""Get the next rows returned by the MySQL server"""
|
|
||||||
try:
|
|
||||||
rows, eof = self.get_rows(count=1, binary=binary, columns=columns,
|
|
||||||
raw=raw, prep_stmt=prep_stmt)
|
|
||||||
if rows:
|
|
||||||
return (rows[0], eof)
|
|
||||||
return (None, eof)
|
|
||||||
except IndexError:
|
|
||||||
# No row available
|
|
||||||
return (None, None)
|
|
||||||
|
|
||||||
def next_result(self):
|
|
||||||
"""Reads the next result"""
|
|
||||||
if self._cmysql:
|
|
||||||
self._cmysql.consume_result()
|
|
||||||
return self._cmysql.next_result()
|
|
||||||
return None
|
|
||||||
|
|
||||||
def free_result(self):
|
|
||||||
"""Frees the result"""
|
|
||||||
if self._cmysql:
|
|
||||||
self._cmysql.free_result()
|
|
||||||
|
|
||||||
def commit(self):
|
|
||||||
"""Commit current transaction"""
|
|
||||||
if self._cmysql:
|
|
||||||
self._cmysql.commit()
|
|
||||||
|
|
||||||
def rollback(self):
|
|
||||||
"""Rollback current transaction"""
|
|
||||||
if self._cmysql:
|
|
||||||
self._cmysql.consume_result()
|
|
||||||
self._cmysql.rollback()
|
|
||||||
|
|
||||||
def cmd_init_db(self, database):
|
|
||||||
"""Change the current database"""
|
|
||||||
try:
|
|
||||||
self._cmysql.select_db(database)
|
|
||||||
except MySQLInterfaceError as exc:
|
|
||||||
raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
|
|
||||||
def fetch_eof_columns(self, prep_stmt=None):
|
|
||||||
"""Fetch EOF and column information"""
|
|
||||||
have_result_set = prep_stmt.have_result_set if prep_stmt \
|
|
||||||
else self._cmysql.have_result_set
|
|
||||||
if not have_result_set:
|
|
||||||
raise errors.InterfaceError("No result set")
|
|
||||||
|
|
||||||
fields = prep_stmt.fetch_fields() if prep_stmt \
|
|
||||||
else self._cmysql.fetch_fields()
|
|
||||||
self._columns = []
|
|
||||||
for col in fields:
|
|
||||||
self._columns.append((
|
|
||||||
col[4],
|
|
||||||
int(col[8]),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
~int(col[9]) & FieldFlag.NOT_NULL,
|
|
||||||
int(col[9])
|
|
||||||
))
|
|
||||||
|
|
||||||
return {
|
|
||||||
'eof': {
|
|
||||||
'status_flag': self._server_status,
|
|
||||||
'warning_count': self._cmysql.st_warning_count(),
|
|
||||||
},
|
|
||||||
'columns': self._columns,
|
|
||||||
}
|
|
||||||
|
|
||||||
def fetch_eof_status(self):
|
|
||||||
"""Fetch EOF and status information"""
|
|
||||||
if self._cmysql:
|
|
||||||
return {
|
|
||||||
'warning_count': self._cmysql.st_warning_count(),
|
|
||||||
'field_count': self._cmysql.st_field_count(),
|
|
||||||
'insert_id': self._cmysql.insert_id(),
|
|
||||||
'affected_rows': self._cmysql.affected_rows(),
|
|
||||||
'server_status': self._server_status,
|
|
||||||
}
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def cmd_stmt_prepare(self, statement):
|
|
||||||
"""Prepares the SQL statement"""
|
|
||||||
if not self._cmysql:
|
|
||||||
raise errors.OperationalError("MySQL Connection not available")
|
|
||||||
|
|
||||||
try:
|
|
||||||
return self._cmysql.stmt_prepare(statement)
|
|
||||||
except MySQLInterfaceError as err:
|
|
||||||
raise errors.InterfaceError(str(err))
|
|
||||||
|
|
||||||
# pylint: disable=W0221
|
|
||||||
def cmd_stmt_execute(self, prep_stmt, *args):
|
|
||||||
"""Executes the prepared statement"""
|
|
||||||
try:
|
|
||||||
prep_stmt.stmt_execute(*args)
|
|
||||||
except MySQLInterfaceError as err:
|
|
||||||
raise errors.InterfaceError(str(err))
|
|
||||||
|
|
||||||
self._columns = []
|
|
||||||
if not prep_stmt.have_result_set:
|
|
||||||
# No result
|
|
||||||
self._unread_result = False
|
|
||||||
return self.fetch_eof_status()
|
|
||||||
|
|
||||||
self._unread_result = True
|
|
||||||
return self.fetch_eof_columns(prep_stmt)
|
|
||||||
|
|
||||||
def cmd_stmt_close(self, prep_stmt):
|
|
||||||
"""Closes the prepared statement"""
|
|
||||||
if self._unread_result:
|
|
||||||
raise errors.InternalError("Unread result found")
|
|
||||||
prep_stmt.stmt_close()
|
|
||||||
|
|
||||||
def cmd_stmt_reset(self, prep_stmt):
|
|
||||||
"""Resets the prepared statement"""
|
|
||||||
if self._unread_result:
|
|
||||||
raise errors.InternalError("Unread result found")
|
|
||||||
prep_stmt.stmt_reset()
|
|
||||||
# pylint: enable=W0221
|
|
||||||
|
|
||||||
def cmd_query(self, query, raw=None, buffered=False, raw_as_string=False):
|
|
||||||
"""Send a query to the MySQL server"""
|
|
||||||
self.handle_unread_result()
|
|
||||||
if raw is None:
|
|
||||||
raw = self._raw
|
|
||||||
try:
|
|
||||||
if not isinstance(query, bytes):
|
|
||||||
query = query.encode('utf-8')
|
|
||||||
self._cmysql.query(query,
|
|
||||||
raw=raw, buffered=buffered,
|
|
||||||
raw_as_string=raw_as_string)
|
|
||||||
except MySQLInterfaceError as exc:
|
|
||||||
raise errors.get_mysql_exception(exc.errno, msg=exc.msg,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
except AttributeError:
|
|
||||||
if self._unix_socket:
|
|
||||||
addr = self._unix_socket
|
|
||||||
else:
|
|
||||||
addr = self._host + ':' + str(self._port)
|
|
||||||
raise errors.OperationalError(
|
|
||||||
errno=2055, values=(addr, 'Connection not available.'))
|
|
||||||
|
|
||||||
self._columns = []
|
|
||||||
if not self._cmysql.have_result_set:
|
|
||||||
# No result
|
|
||||||
return self.fetch_eof_status()
|
|
||||||
|
|
||||||
return self.fetch_eof_columns()
|
|
||||||
_execute_query = cmd_query
|
|
||||||
|
|
||||||
def cursor(self, buffered=None, raw=None, prepared=None, cursor_class=None,
|
|
||||||
dictionary=None, named_tuple=None):
|
|
||||||
"""Instantiates and returns a cursor using C Extension
|
|
||||||
|
|
||||||
By default, CMySQLCursor is returned. Depending on the options
|
|
||||||
while connecting, a buffered and/or raw cursor is instantiated
|
|
||||||
instead. Also depending upon the cursor options, rows can be
|
|
||||||
returned as dictionary or named tuple.
|
|
||||||
|
|
||||||
Dictionary and namedtuple based cursors are available with buffered
|
|
||||||
output but not raw.
|
|
||||||
|
|
||||||
It is possible to also give a custom cursor through the
|
|
||||||
cursor_class parameter, but it needs to be a subclass of
|
|
||||||
mysql.connector.cursor_cext.CMySQLCursor.
|
|
||||||
|
|
||||||
Raises ProgrammingError when cursor_class is not a subclass of
|
|
||||||
CursorBase. Raises ValueError when cursor is not available.
|
|
||||||
|
|
||||||
Returns instance of CMySQLCursor or subclass.
|
|
||||||
|
|
||||||
:param buffered: Return a buffering cursor
|
|
||||||
:param raw: Return a raw cursor
|
|
||||||
:param prepared: Return a cursor which uses prepared statements
|
|
||||||
:param cursor_class: Use a custom cursor class
|
|
||||||
:param dictionary: Rows are returned as dictionary
|
|
||||||
:param named_tuple: Rows are returned as named tuple
|
|
||||||
:return: Subclass of CMySQLCursor
|
|
||||||
:rtype: CMySQLCursor or subclass
|
|
||||||
"""
|
|
||||||
self.handle_unread_result(prepared)
|
|
||||||
if not self.is_connected():
|
|
||||||
raise errors.OperationalError("MySQL Connection not available.")
|
|
||||||
if cursor_class is not None:
|
|
||||||
if not issubclass(cursor_class, MySQLCursorAbstract):
|
|
||||||
raise errors.ProgrammingError(
|
|
||||||
"Cursor class needs be to subclass"
|
|
||||||
" of cursor_cext.CMySQLCursor")
|
|
||||||
return (cursor_class)(self)
|
|
||||||
|
|
||||||
buffered = buffered or self._buffered
|
|
||||||
raw = raw or self._raw
|
|
||||||
|
|
||||||
cursor_type = 0
|
|
||||||
if buffered is True:
|
|
||||||
cursor_type |= 1
|
|
||||||
if raw is True:
|
|
||||||
cursor_type |= 2
|
|
||||||
if dictionary is True:
|
|
||||||
cursor_type |= 4
|
|
||||||
if named_tuple is True:
|
|
||||||
cursor_type |= 8
|
|
||||||
if prepared is True:
|
|
||||||
cursor_type |= 16
|
|
||||||
|
|
||||||
types = {
|
|
||||||
0: CMySQLCursor, # 0
|
|
||||||
1: CMySQLCursorBuffered,
|
|
||||||
2: CMySQLCursorRaw,
|
|
||||||
3: CMySQLCursorBufferedRaw,
|
|
||||||
4: CMySQLCursorDict,
|
|
||||||
5: CMySQLCursorBufferedDict,
|
|
||||||
8: CMySQLCursorNamedTuple,
|
|
||||||
9: CMySQLCursorBufferedNamedTuple,
|
|
||||||
16: CMySQLCursorPrepared
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
return (types[cursor_type])(self)
|
|
||||||
except KeyError:
|
|
||||||
args = ('buffered', 'raw', 'dictionary', 'named_tuple', 'prepared')
|
|
||||||
raise ValueError('Cursor not available with given criteria: ' +
|
|
||||||
', '.join([args[i] for i in range(5)
|
|
||||||
if cursor_type & (1 << i) != 0]))
|
|
||||||
|
|
||||||
@property
|
|
||||||
def num_rows(self):
|
|
||||||
"""Returns number of rows of current result set"""
|
|
||||||
if not self._cmysql.have_result_set:
|
|
||||||
raise errors.InterfaceError("No result set")
|
|
||||||
|
|
||||||
return self._cmysql.num_rows()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def warning_count(self):
|
|
||||||
"""Returns number of warnings"""
|
|
||||||
if not self._cmysql:
|
|
||||||
return 0
|
|
||||||
|
|
||||||
return self._cmysql.warning_count()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def result_set_available(self):
|
|
||||||
"""Check if a result set is available"""
|
|
||||||
if not self._cmysql:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return self._cmysql.have_result_set
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unread_result(self):
|
|
||||||
"""Check if there are unread results or rows"""
|
|
||||||
return self.result_set_available
|
|
||||||
|
|
||||||
@property
|
|
||||||
def more_results(self):
|
|
||||||
"""Check if there are more results"""
|
|
||||||
return self._cmysql.more_results()
|
|
||||||
|
|
||||||
def prepare_for_mysql(self, params):
|
|
||||||
"""Prepare parameters for statements
|
|
||||||
|
|
||||||
This method is use by cursors to prepared parameters found in the
|
|
||||||
list (or tuple) params.
|
|
||||||
|
|
||||||
Returns dict.
|
|
||||||
"""
|
|
||||||
if isinstance(params, (list, tuple)):
|
|
||||||
result = self._cmysql.convert_to_mysql(*params)
|
|
||||||
elif isinstance(params, dict):
|
|
||||||
result = {}
|
|
||||||
for key, value in params.items():
|
|
||||||
result[key] = self._cmysql.convert_to_mysql(value)[0]
|
|
||||||
else:
|
|
||||||
raise ValueError("Could not process parameters")
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def consume_results(self):
|
|
||||||
"""Consume the current result
|
|
||||||
|
|
||||||
This method consume the result by reading (consuming) all rows.
|
|
||||||
"""
|
|
||||||
self._cmysql.consume_result()
|
|
||||||
|
|
||||||
def cmd_change_user(self, username='', password='', database='',
|
|
||||||
charset=45):
|
|
||||||
"""Change the current logged in user"""
|
|
||||||
try:
|
|
||||||
self._cmysql.change_user(username, password, database)
|
|
||||||
except MySQLInterfaceError as exc:
|
|
||||||
raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
|
|
||||||
self._charset_id = charset
|
|
||||||
self._post_connection()
|
|
||||||
|
|
||||||
def cmd_refresh(self, options):
|
|
||||||
"""Send the Refresh command to the MySQL server"""
|
|
||||||
try:
|
|
||||||
self._cmysql.refresh(options)
|
|
||||||
except MySQLInterfaceError as exc:
|
|
||||||
raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
|
|
||||||
return self.fetch_eof_status()
|
|
||||||
|
|
||||||
def cmd_quit(self):
|
|
||||||
"""Close the current connection with the server"""
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def cmd_shutdown(self, shutdown_type=None):
|
|
||||||
"""Shut down the MySQL Server"""
|
|
||||||
if not self._cmysql:
|
|
||||||
raise errors.OperationalError("MySQL Connection not available")
|
|
||||||
|
|
||||||
if shutdown_type:
|
|
||||||
if not ShutdownType.get_info(shutdown_type):
|
|
||||||
raise errors.InterfaceError("Invalid shutdown type")
|
|
||||||
level = shutdown_type
|
|
||||||
else:
|
|
||||||
level = ShutdownType.SHUTDOWN_DEFAULT
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._cmysql.shutdown(level)
|
|
||||||
except MySQLInterfaceError as exc:
|
|
||||||
raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def cmd_statistics(self):
|
|
||||||
"""Return statistics from the MySQL server"""
|
|
||||||
self.handle_unread_result()
|
|
||||||
|
|
||||||
try:
|
|
||||||
stat = self._cmysql.stat()
|
|
||||||
return MySQLProtocol().parse_statistics(stat, with_header=False)
|
|
||||||
except (MySQLInterfaceError, errors.InterfaceError) as exc:
|
|
||||||
raise errors.get_mysql_exception(msg=exc.msg, errno=exc.errno,
|
|
||||||
sqlstate=exc.sqlstate)
|
|
||||||
|
|
||||||
def cmd_process_kill(self, mysql_pid):
|
|
||||||
"""Kill a MySQL process"""
|
|
||||||
if not isinstance(mysql_pid, INT_TYPES):
|
|
||||||
raise ValueError("MySQL PID must be int")
|
|
||||||
self.info_query("KILL {0}".format(mysql_pid))
|
|
||||||
|
|
||||||
def handle_unread_result(self, prepared=False):
|
|
||||||
"""Check whether there is an unread result"""
|
|
||||||
unread_result = self._unread_result if prepared is True \
|
|
||||||
else self.unread_result
|
|
||||||
if self.can_consume_results:
|
|
||||||
self.consume_results()
|
|
||||||
elif unread_result:
|
|
||||||
raise errors.InternalError("Unread result found")
|
|
File diff suppressed because it is too large
Load Diff
@ -1,685 +0,0 @@
|
|||||||
# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Converting MySQL and Python types
|
|
||||||
"""
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
import time
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
from .constants import FieldType, FieldFlag, CharacterSet
|
|
||||||
from .catch23 import PY2, NUMERIC_TYPES, struct_unpack
|
|
||||||
from .custom_types import HexLiteral
|
|
||||||
|
|
||||||
CONVERT_ERROR = "Could not convert '{value}' to python {pytype}"
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLConverterBase(object):
|
|
||||||
"""Base class for conversion classes
|
|
||||||
|
|
||||||
All class dealing with converting to and from MySQL data types must
|
|
||||||
be a subclass of this class.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, charset='utf8', use_unicode=True):
|
|
||||||
self.python_types = None
|
|
||||||
self.mysql_types = None
|
|
||||||
self.charset = None
|
|
||||||
self.charset_id = 0
|
|
||||||
self.use_unicode = None
|
|
||||||
self.set_charset(charset)
|
|
||||||
self.set_unicode(use_unicode)
|
|
||||||
self._cache_field_types = {}
|
|
||||||
|
|
||||||
def set_charset(self, charset):
|
|
||||||
"""Set character set"""
|
|
||||||
if charset == 'utf8mb4':
|
|
||||||
charset = 'utf8'
|
|
||||||
if charset is not None:
|
|
||||||
self.charset = charset
|
|
||||||
else:
|
|
||||||
# default to utf8
|
|
||||||
self.charset = 'utf8'
|
|
||||||
self.charset_id = CharacterSet.get_charset_info(self.charset)[0]
|
|
||||||
|
|
||||||
def set_unicode(self, value=True):
|
|
||||||
"""Set whether to use Unicode"""
|
|
||||||
self.use_unicode = value
|
|
||||||
|
|
||||||
def to_mysql(self, value):
|
|
||||||
"""Convert Python data type to MySQL"""
|
|
||||||
type_name = value.__class__.__name__.lower()
|
|
||||||
try:
|
|
||||||
return getattr(self, "_{0}_to_mysql".format(type_name))(value)
|
|
||||||
except AttributeError:
|
|
||||||
return value
|
|
||||||
|
|
||||||
def to_python(self, vtype, value):
|
|
||||||
"""Convert MySQL data type to Python"""
|
|
||||||
|
|
||||||
if (value == b'\x00' or value is None) and vtype[1] != FieldType.BIT:
|
|
||||||
# Don't go further when we hit a NULL value
|
|
||||||
return None
|
|
||||||
|
|
||||||
if not self._cache_field_types:
|
|
||||||
self._cache_field_types = {}
|
|
||||||
for name, info in FieldType.desc.items():
|
|
||||||
try:
|
|
||||||
self._cache_field_types[info[0]] = getattr(
|
|
||||||
self, '_{0}_to_python'.format(name))
|
|
||||||
except AttributeError:
|
|
||||||
# We ignore field types which has no method
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
return self._cache_field_types[vtype[1]](value, vtype)
|
|
||||||
except KeyError:
|
|
||||||
return value
|
|
||||||
|
|
||||||
def escape(self, value):
|
|
||||||
"""Escape buffer for sending to MySQL"""
|
|
||||||
return value
|
|
||||||
|
|
||||||
def quote(self, buf):
|
|
||||||
"""Quote buffer for sending to MySQL"""
|
|
||||||
return str(buf)
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLConverter(MySQLConverterBase):
|
|
||||||
"""Default conversion class for MySQL Connector/Python.
|
|
||||||
|
|
||||||
o escape method: for escaping values send to MySQL
|
|
||||||
o quoting method: for quoting values send to MySQL in statements
|
|
||||||
o conversion mapping: maps Python and MySQL data types to
|
|
||||||
function for converting them.
|
|
||||||
|
|
||||||
Whenever one needs to convert values differently, a converter_class
|
|
||||||
argument can be given while instantiating a new connection like
|
|
||||||
cnx.connect(converter_class=CustomMySQLConverterClass).
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, charset=None, use_unicode=True):
|
|
||||||
MySQLConverterBase.__init__(self, charset, use_unicode)
|
|
||||||
self._cache_field_types = {}
|
|
||||||
|
|
||||||
def escape(self, value):
|
|
||||||
"""
|
|
||||||
Escapes special characters as they are expected to by when MySQL
|
|
||||||
receives them.
|
|
||||||
As found in MySQL source mysys/charset.c
|
|
||||||
|
|
||||||
Returns the value if not a string, or the escaped string.
|
|
||||||
"""
|
|
||||||
if value is None:
|
|
||||||
return value
|
|
||||||
elif isinstance(value, NUMERIC_TYPES):
|
|
||||||
return value
|
|
||||||
if isinstance(value, (bytes, bytearray)):
|
|
||||||
value = value.replace(b'\\', b'\\\\')
|
|
||||||
value = value.replace(b'\n', b'\\n')
|
|
||||||
value = value.replace(b'\r', b'\\r')
|
|
||||||
value = value.replace(b'\047', b'\134\047') # single quotes
|
|
||||||
value = value.replace(b'\042', b'\134\042') # double quotes
|
|
||||||
value = value.replace(b'\032', b'\134\032') # for Win32
|
|
||||||
else:
|
|
||||||
value = value.replace('\\', '\\\\')
|
|
||||||
value = value.replace('\n', '\\n')
|
|
||||||
value = value.replace('\r', '\\r')
|
|
||||||
value = value.replace('\047', '\134\047') # single quotes
|
|
||||||
value = value.replace('\042', '\134\042') # double quotes
|
|
||||||
value = value.replace('\032', '\134\032') # for Win32
|
|
||||||
return value
|
|
||||||
|
|
||||||
def quote(self, buf):
|
|
||||||
"""
|
|
||||||
Quote the parameters for commands. General rules:
|
|
||||||
o numbers are returns as bytes using ascii codec
|
|
||||||
o None is returned as bytearray(b'NULL')
|
|
||||||
o Everything else is single quoted '<buf>'
|
|
||||||
|
|
||||||
Returns a bytearray object.
|
|
||||||
"""
|
|
||||||
if isinstance(buf, NUMERIC_TYPES):
|
|
||||||
if PY2:
|
|
||||||
if isinstance(buf, float):
|
|
||||||
return repr(buf)
|
|
||||||
return str(buf)
|
|
||||||
return str(buf).encode('ascii')
|
|
||||||
elif isinstance(buf, type(None)):
|
|
||||||
return bytearray(b"NULL")
|
|
||||||
return bytearray(b"'" + buf + b"'")
|
|
||||||
|
|
||||||
def to_mysql(self, value):
|
|
||||||
"""Convert Python data type to MySQL"""
|
|
||||||
type_name = value.__class__.__name__.lower()
|
|
||||||
try:
|
|
||||||
return getattr(self, "_{0}_to_mysql".format(type_name))(value)
|
|
||||||
except AttributeError:
|
|
||||||
raise TypeError("Python '{0}' cannot be converted to a "
|
|
||||||
"MySQL type".format(type_name))
|
|
||||||
|
|
||||||
def to_python(self, vtype, value):
|
|
||||||
"""Convert MySQL data type to Python"""
|
|
||||||
if value == 0 and vtype[1] != FieldType.BIT: # \x00
|
|
||||||
# Don't go further when we hit a NULL value
|
|
||||||
return None
|
|
||||||
if value is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if not self._cache_field_types:
|
|
||||||
self._cache_field_types = {}
|
|
||||||
for name, info in FieldType.desc.items():
|
|
||||||
try:
|
|
||||||
self._cache_field_types[info[0]] = getattr(
|
|
||||||
self, '_{0}_to_python'.format(name))
|
|
||||||
except AttributeError:
|
|
||||||
# We ignore field types which has no method
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
return self._cache_field_types[vtype[1]](value, vtype)
|
|
||||||
except KeyError:
|
|
||||||
# If one type is not defined, we just return the value as str
|
|
||||||
try:
|
|
||||||
return value.decode('utf-8')
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
return value
|
|
||||||
except ValueError as err:
|
|
||||||
raise ValueError("%s (field %s)" % (err, vtype[0]))
|
|
||||||
except TypeError as err:
|
|
||||||
raise TypeError("%s (field %s)" % (err, vtype[0]))
|
|
||||||
except:
|
|
||||||
raise
|
|
||||||
|
|
||||||
def _int_to_mysql(self, value):
|
|
||||||
"""Convert value to int"""
|
|
||||||
return int(value)
|
|
||||||
|
|
||||||
def _long_to_mysql(self, value):
|
|
||||||
"""Convert value to int"""
|
|
||||||
return int(value)
|
|
||||||
|
|
||||||
def _float_to_mysql(self, value):
|
|
||||||
"""Convert value to float"""
|
|
||||||
return float(value)
|
|
||||||
|
|
||||||
def _str_to_mysql(self, value):
|
|
||||||
"""Convert value to string"""
|
|
||||||
if PY2:
|
|
||||||
return str(value)
|
|
||||||
return self._unicode_to_mysql(value)
|
|
||||||
|
|
||||||
def _unicode_to_mysql(self, value):
|
|
||||||
"""Convert unicode"""
|
|
||||||
charset = self.charset
|
|
||||||
charset_id = self.charset_id
|
|
||||||
if charset == 'binary':
|
|
||||||
charset = 'utf8'
|
|
||||||
charset_id = CharacterSet.get_charset_info(charset)[0]
|
|
||||||
encoded = value.encode(charset)
|
|
||||||
if charset_id in CharacterSet.slash_charsets:
|
|
||||||
if b'\x5c' in encoded:
|
|
||||||
return HexLiteral(value, charset)
|
|
||||||
return encoded
|
|
||||||
|
|
||||||
def _bytes_to_mysql(self, value):
|
|
||||||
"""Convert value to bytes"""
|
|
||||||
return value
|
|
||||||
|
|
||||||
def _bytearray_to_mysql(self, value):
|
|
||||||
"""Convert value to bytes"""
|
|
||||||
return bytes(value)
|
|
||||||
|
|
||||||
def _bool_to_mysql(self, value):
|
|
||||||
"""Convert value to boolean"""
|
|
||||||
if value:
|
|
||||||
return 1
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def _nonetype_to_mysql(self, value):
|
|
||||||
"""
|
|
||||||
This would return what None would be in MySQL, but instead we
|
|
||||||
leave it None and return it right away. The actual conversion
|
|
||||||
from None to NULL happens in the quoting functionality.
|
|
||||||
|
|
||||||
Return None.
|
|
||||||
"""
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _datetime_to_mysql(self, value):
|
|
||||||
"""
|
|
||||||
Converts a datetime instance to a string suitable for MySQL.
|
|
||||||
The returned string has format: %Y-%m-%d %H:%M:%S[.%f]
|
|
||||||
|
|
||||||
If the instance isn't a datetime.datetime type, it return None.
|
|
||||||
|
|
||||||
Returns a bytes.
|
|
||||||
"""
|
|
||||||
if value.microsecond:
|
|
||||||
fmt = '{0:d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}.{6:06d}'
|
|
||||||
return fmt.format(
|
|
||||||
value.year, value.month, value.day,
|
|
||||||
value.hour, value.minute, value.second,
|
|
||||||
value.microsecond).encode('ascii')
|
|
||||||
|
|
||||||
fmt = '{0:d}-{1:02d}-{2:02d} {3:02d}:{4:02d}:{5:02d}'
|
|
||||||
return fmt.format(
|
|
||||||
value.year, value.month, value.day,
|
|
||||||
value.hour, value.minute, value.second).encode('ascii')
|
|
||||||
|
|
||||||
def _date_to_mysql(self, value):
|
|
||||||
"""
|
|
||||||
Converts a date instance to a string suitable for MySQL.
|
|
||||||
The returned string has format: %Y-%m-%d
|
|
||||||
|
|
||||||
If the instance isn't a datetime.date type, it return None.
|
|
||||||
|
|
||||||
Returns a bytes.
|
|
||||||
"""
|
|
||||||
return '{0:d}-{1:02d}-{2:02d}'.format(value.year, value.month,
|
|
||||||
value.day).encode('ascii')
|
|
||||||
|
|
||||||
def _time_to_mysql(self, value):
|
|
||||||
"""
|
|
||||||
Converts a time instance to a string suitable for MySQL.
|
|
||||||
The returned string has format: %H:%M:%S[.%f]
|
|
||||||
|
|
||||||
If the instance isn't a datetime.time type, it return None.
|
|
||||||
|
|
||||||
Returns a bytes.
|
|
||||||
"""
|
|
||||||
if value.microsecond:
|
|
||||||
return value.strftime('%H:%M:%S.%f').encode('ascii')
|
|
||||||
return value.strftime('%H:%M:%S').encode('ascii')
|
|
||||||
|
|
||||||
def _struct_time_to_mysql(self, value):
|
|
||||||
"""
|
|
||||||
Converts a time.struct_time sequence to a string suitable
|
|
||||||
for MySQL.
|
|
||||||
The returned string has format: %Y-%m-%d %H:%M:%S
|
|
||||||
|
|
||||||
Returns a bytes or None when not valid.
|
|
||||||
"""
|
|
||||||
return time.strftime('%Y-%m-%d %H:%M:%S', value).encode('ascii')
|
|
||||||
|
|
||||||
def _timedelta_to_mysql(self, value):
|
|
||||||
"""
|
|
||||||
Converts a timedelta instance to a string suitable for MySQL.
|
|
||||||
The returned string has format: %H:%M:%S
|
|
||||||
|
|
||||||
Returns a bytes.
|
|
||||||
"""
|
|
||||||
seconds = abs(value.days * 86400 + value.seconds)
|
|
||||||
|
|
||||||
if value.microseconds:
|
|
||||||
fmt = '{0:02d}:{1:02d}:{2:02d}.{3:06d}'
|
|
||||||
if value.days < 0:
|
|
||||||
mcs = 1000000 - value.microseconds
|
|
||||||
seconds -= 1
|
|
||||||
else:
|
|
||||||
mcs = value.microseconds
|
|
||||||
else:
|
|
||||||
fmt = '{0:02d}:{1:02d}:{2:02d}'
|
|
||||||
|
|
||||||
if value.days < 0:
|
|
||||||
fmt = '-' + fmt
|
|
||||||
|
|
||||||
(hours, remainder) = divmod(seconds, 3600)
|
|
||||||
(mins, secs) = divmod(remainder, 60)
|
|
||||||
|
|
||||||
if value.microseconds:
|
|
||||||
result = fmt.format(hours, mins, secs, mcs)
|
|
||||||
else:
|
|
||||||
result = fmt.format(hours, mins, secs)
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
return result
|
|
||||||
return result.encode('ascii')
|
|
||||||
|
|
||||||
def _decimal_to_mysql(self, value):
|
|
||||||
"""
|
|
||||||
Converts a decimal.Decimal instance to a string suitable for
|
|
||||||
MySQL.
|
|
||||||
|
|
||||||
Returns a bytes or None when not valid.
|
|
||||||
"""
|
|
||||||
if isinstance(value, Decimal):
|
|
||||||
return str(value).encode('ascii')
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def row_to_python(self, row, fields):
|
|
||||||
"""Convert a MySQL text result row to Python types
|
|
||||||
|
|
||||||
The row argument is a sequence containing text result returned
|
|
||||||
by a MySQL server. Each value of the row is converted to the
|
|
||||||
using the field type information in the fields argument.
|
|
||||||
|
|
||||||
Returns a tuple.
|
|
||||||
"""
|
|
||||||
i = 0
|
|
||||||
result = [None]*len(fields)
|
|
||||||
|
|
||||||
if not self._cache_field_types:
|
|
||||||
self._cache_field_types = {}
|
|
||||||
for name, info in FieldType.desc.items():
|
|
||||||
try:
|
|
||||||
self._cache_field_types[info[0]] = getattr(
|
|
||||||
self, '_{0}_to_python'.format(name))
|
|
||||||
except AttributeError:
|
|
||||||
# We ignore field types which has no method
|
|
||||||
pass
|
|
||||||
|
|
||||||
for field in fields:
|
|
||||||
field_type = field[1]
|
|
||||||
|
|
||||||
if (row[i] == 0 and field_type != FieldType.BIT) or row[i] is None:
|
|
||||||
# Don't convert NULL value
|
|
||||||
i += 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
try:
|
|
||||||
result[i] = self._cache_field_types[field_type](row[i], field)
|
|
||||||
except KeyError:
|
|
||||||
# If one type is not defined, we just return the value as str
|
|
||||||
try:
|
|
||||||
result[i] = row[i].decode('utf-8')
|
|
||||||
except UnicodeDecodeError:
|
|
||||||
result[i] = row[i]
|
|
||||||
except (ValueError, TypeError) as err:
|
|
||||||
err.message = "{0} (field {1})".format(str(err), field[0])
|
|
||||||
raise
|
|
||||||
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
return tuple(result)
|
|
||||||
|
|
||||||
def _FLOAT_to_python(self, value, desc=None): # pylint: disable=C0103
|
|
||||||
"""
|
|
||||||
Returns value as float type.
|
|
||||||
"""
|
|
||||||
return float(value)
|
|
||||||
|
|
||||||
_DOUBLE_to_python = _FLOAT_to_python
|
|
||||||
|
|
||||||
def _INT_to_python(self, value, desc=None): # pylint: disable=C0103
|
|
||||||
"""
|
|
||||||
Returns value as int type.
|
|
||||||
"""
|
|
||||||
return int(value)
|
|
||||||
|
|
||||||
_TINY_to_python = _INT_to_python
|
|
||||||
_SHORT_to_python = _INT_to_python
|
|
||||||
_INT24_to_python = _INT_to_python
|
|
||||||
_LONG_to_python = _INT_to_python
|
|
||||||
_LONGLONG_to_python = _INT_to_python
|
|
||||||
|
|
||||||
def _DECIMAL_to_python(self, value, desc=None): # pylint: disable=C0103
|
|
||||||
"""
|
|
||||||
Returns value as a decimal.Decimal.
|
|
||||||
"""
|
|
||||||
val = value.decode(self.charset)
|
|
||||||
return Decimal(val)
|
|
||||||
|
|
||||||
_NEWDECIMAL_to_python = _DECIMAL_to_python
|
|
||||||
|
|
||||||
def _str(self, value, desc=None):
|
|
||||||
"""
|
|
||||||
Returns value as str type.
|
|
||||||
"""
|
|
||||||
return str(value)
|
|
||||||
|
|
||||||
def _BIT_to_python(self, value, dsc=None): # pylint: disable=C0103
|
|
||||||
"""Returns BIT columntype as integer"""
|
|
||||||
int_val = value
|
|
||||||
if len(int_val) < 8:
|
|
||||||
int_val = b'\x00' * (8 - len(int_val)) + int_val
|
|
||||||
return struct_unpack('>Q', int_val)[0]
|
|
||||||
|
|
||||||
def _DATE_to_python(self, value, dsc=None): # pylint: disable=C0103
|
|
||||||
"""Converts TIME column MySQL to a python datetime.datetime type.
|
|
||||||
|
|
||||||
Raises ValueError if the value can not be converted.
|
|
||||||
|
|
||||||
Returns DATE column type as datetime.date type.
|
|
||||||
"""
|
|
||||||
if isinstance(value, datetime.date):
|
|
||||||
return value
|
|
||||||
try:
|
|
||||||
parts = value.split(b'-')
|
|
||||||
if len(parts) != 3:
|
|
||||||
raise ValueError("invalid datetime format: {} len: {}"
|
|
||||||
"".format(parts, len(parts)))
|
|
||||||
try:
|
|
||||||
return datetime.date(int(parts[0]), int(parts[1]), int(parts[2]))
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
except (IndexError, ValueError):
|
|
||||||
raise ValueError(
|
|
||||||
"Could not convert {0} to python datetime.timedelta".format(
|
|
||||||
value))
|
|
||||||
|
|
||||||
_NEWDATE_to_python = _DATE_to_python
|
|
||||||
|
|
||||||
def _TIME_to_python(self, value, dsc=None): # pylint: disable=C0103
|
|
||||||
"""Converts TIME column value to python datetime.time value type.
|
|
||||||
|
|
||||||
Converts the TIME column MySQL type passed as bytes to a python
|
|
||||||
datetime.datetime type.
|
|
||||||
|
|
||||||
Raises ValueError if the value can not be converted.
|
|
||||||
|
|
||||||
Returns datetime.time type.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
(hms, mcs) = value.split(b'.')
|
|
||||||
mcs = int(mcs.ljust(6, b'0'))
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
hms = value
|
|
||||||
mcs = 0
|
|
||||||
try:
|
|
||||||
(hours, mins, secs) = [int(d) for d in hms.split(b':')]
|
|
||||||
if value[0] == 45 or value[0] == '-': # if PY3 or PY2
|
|
||||||
mins, secs, mcs = -mins, -secs, -mcs
|
|
||||||
return datetime.timedelta(hours=hours, minutes=mins,
|
|
||||||
seconds=secs, microseconds=mcs)
|
|
||||||
except (IndexError, TypeError, ValueError):
|
|
||||||
raise ValueError(CONVERT_ERROR.format(value=value,
|
|
||||||
pytype="datetime.timedelta"))
|
|
||||||
|
|
||||||
def _DATETIME_to_python(self, value, dsc=None): # pylint: disable=C0103
|
|
||||||
""""Converts DATETIME column value to python datetime.time value type.
|
|
||||||
|
|
||||||
Converts the DATETIME column MySQL type passed as bytes to a python
|
|
||||||
datetime.datetime type.
|
|
||||||
|
|
||||||
Returns: datetime.datetime type.
|
|
||||||
"""
|
|
||||||
if isinstance(value, datetime.datetime):
|
|
||||||
return value
|
|
||||||
datetime_val = None
|
|
||||||
try:
|
|
||||||
(date_, time_) = value.split(b' ')
|
|
||||||
if len(time_) > 8:
|
|
||||||
(hms, mcs) = time_.split(b'.')
|
|
||||||
mcs = int(mcs.ljust(6, b'0'))
|
|
||||||
else:
|
|
||||||
hms = time_
|
|
||||||
mcs = 0
|
|
||||||
dtval = [int(i) for i in date_.split(b'-')] + \
|
|
||||||
[int(i) for i in hms.split(b':')] + [mcs, ]
|
|
||||||
if len(dtval) < 6:
|
|
||||||
raise ValueError("invalid datetime format: {} len: {}"
|
|
||||||
"".format(dtval, len(dtval)))
|
|
||||||
else:
|
|
||||||
# Note that by default MySQL accepts invalid timestamps
|
|
||||||
# (this is also backward compatibility).
|
|
||||||
# Traditionaly C/py returns None for this well formed but
|
|
||||||
# invalid datetime for python like '0000-00-00 HH:MM:SS'.
|
|
||||||
try:
|
|
||||||
datetime_val = datetime.datetime(*dtval)
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
except (IndexError, TypeError):
|
|
||||||
raise ValueError(CONVERT_ERROR.format(value=value,
|
|
||||||
pytype="datetime.timedelta"))
|
|
||||||
|
|
||||||
return datetime_val
|
|
||||||
|
|
||||||
_TIMESTAMP_to_python = _DATETIME_to_python
|
|
||||||
|
|
||||||
def _YEAR_to_python(self, value, desc=None): # pylint: disable=C0103
|
|
||||||
"""Returns YEAR column type as integer"""
|
|
||||||
try:
|
|
||||||
year = int(value)
|
|
||||||
except ValueError:
|
|
||||||
raise ValueError("Failed converting YEAR to int (%s)" % value)
|
|
||||||
|
|
||||||
return year
|
|
||||||
|
|
||||||
def _SET_to_python(self, value, dsc=None): # pylint: disable=C0103
|
|
||||||
"""Returns SET column type as set
|
|
||||||
|
|
||||||
Actually, MySQL protocol sees a SET as a string type field. So this
|
|
||||||
code isn't called directly, but used by STRING_to_python() method.
|
|
||||||
|
|
||||||
Returns SET column type as a set.
|
|
||||||
"""
|
|
||||||
set_type = None
|
|
||||||
val = value.decode(self.charset)
|
|
||||||
if not val:
|
|
||||||
return set()
|
|
||||||
try:
|
|
||||||
set_type = set(val.split(','))
|
|
||||||
except ValueError:
|
|
||||||
raise ValueError("Could not convert set %s to a sequence." % value)
|
|
||||||
return set_type
|
|
||||||
|
|
||||||
def _JSON_to_python(self, value, dsc=None): # pylint: disable=C0103
|
|
||||||
"""Returns JSON column type as python type
|
|
||||||
|
|
||||||
Returns JSON column type as python type.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
num = float(value)
|
|
||||||
if num.is_integer():
|
|
||||||
return int(value)
|
|
||||||
return num
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if value == b'true':
|
|
||||||
return True
|
|
||||||
elif value == b'false':
|
|
||||||
return False
|
|
||||||
|
|
||||||
# The following types are returned between double quotes or
|
|
||||||
# bytearray(b'"')[0] or int 34 for shortness.
|
|
||||||
if value[0] == 34 and value[-1] == 34:
|
|
||||||
value_nq = value[1:-1]
|
|
||||||
|
|
||||||
try:
|
|
||||||
value_datetime = self._DATETIME_to_python(value_nq)
|
|
||||||
if value_datetime is not None:
|
|
||||||
return value_datetime
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
value_date = self._DATE_to_python(value_nq)
|
|
||||||
if value_date is not None:
|
|
||||||
return value_date
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
try:
|
|
||||||
value_time = self._TIME_to_python(value_nq)
|
|
||||||
if value_time is not None:
|
|
||||||
return value_time
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if isinstance(value, (bytes, bytearray)):
|
|
||||||
return value.decode(self.charset)
|
|
||||||
|
|
||||||
if dsc is not None:
|
|
||||||
# Check if we deal with a SET
|
|
||||||
if dsc[7] & FieldFlag.SET:
|
|
||||||
return self._SET_to_python(value, dsc)
|
|
||||||
if dsc[7] & FieldFlag.BINARY:
|
|
||||||
if self.charset != 'binary' and not isinstance(value, str):
|
|
||||||
try:
|
|
||||||
return value.decode(self.charset)
|
|
||||||
except (LookupError, UnicodeDecodeError):
|
|
||||||
return value
|
|
||||||
else:
|
|
||||||
return value
|
|
||||||
|
|
||||||
return self._STRING_to_python(value, dsc)
|
|
||||||
|
|
||||||
def _STRING_to_python(self, value, dsc=None): # pylint: disable=C0103
|
|
||||||
"""
|
|
||||||
Note that a SET is a string too, but using the FieldFlag we can see
|
|
||||||
whether we have to split it.
|
|
||||||
|
|
||||||
Returns string typed columns as string type.
|
|
||||||
"""
|
|
||||||
if dsc is not None:
|
|
||||||
# Check if we deal with a SET
|
|
||||||
if dsc[7] & FieldFlag.SET:
|
|
||||||
return self._SET_to_python(value, dsc)
|
|
||||||
if dsc[7] & FieldFlag.BINARY:
|
|
||||||
if self.charset != 'binary' and not isinstance(value, str):
|
|
||||||
try:
|
|
||||||
return value.decode(self.charset)
|
|
||||||
except (LookupError, UnicodeDecodeError):
|
|
||||||
return value
|
|
||||||
else:
|
|
||||||
return value
|
|
||||||
|
|
||||||
if self.charset == 'binary':
|
|
||||||
return value
|
|
||||||
if isinstance(value, (bytes, bytearray)) and self.use_unicode:
|
|
||||||
return value.decode(self.charset)
|
|
||||||
|
|
||||||
return value
|
|
||||||
|
|
||||||
_VAR_STRING_to_python = _STRING_to_python
|
|
||||||
|
|
||||||
def _BLOB_to_python(self, value, dsc=None): # pylint: disable=C0103
|
|
||||||
"""Convert BLOB data type to Python"""
|
|
||||||
if not value:
|
|
||||||
# This is an empty BLOB
|
|
||||||
return ""
|
|
||||||
# JSON Values are stored in LONG BLOB, but the blob values recived
|
|
||||||
# from the server are not dilutable, check for JSON values.
|
|
||||||
return self._JSON_to_python(value, dsc)
|
|
||||||
|
|
||||||
_LONG_BLOB_to_python = _BLOB_to_python
|
|
||||||
_MEDIUM_BLOB_to_python = _BLOB_to_python
|
|
||||||
_TINY_BLOB_to_python = _BLOB_to_python
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,50 +0,0 @@
|
|||||||
# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Custom Python types used by MySQL Connector/Python"""
|
|
||||||
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
class HexLiteral(str):
|
|
||||||
|
|
||||||
"""Class holding MySQL hex literals"""
|
|
||||||
|
|
||||||
def __new__(cls, str_, charset='utf8'):
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
hexed = ["%02x" % ord(i) for i in str_.encode(charset)]
|
|
||||||
else:
|
|
||||||
hexed = ["%02x" % i for i in str_.encode(charset)]
|
|
||||||
obj = str.__new__(cls, ''.join(hexed))
|
|
||||||
obj.charset = charset
|
|
||||||
obj.original = str_
|
|
||||||
return obj
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return '0x' + self
|
|
@ -1,80 +0,0 @@
|
|||||||
# Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""
|
|
||||||
This module implements some constructors and singletons as required by the
|
|
||||||
DB API v2.0 (PEP-249).
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Python Db API v2
|
|
||||||
apilevel = '2.0'
|
|
||||||
threadsafety = 1
|
|
||||||
paramstyle = 'pyformat'
|
|
||||||
|
|
||||||
import time
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
from . import constants
|
|
||||||
|
|
||||||
class _DBAPITypeObject(object):
|
|
||||||
|
|
||||||
def __init__(self, *values):
|
|
||||||
self.values = values
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
if other in self.values:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def __ne__(self, other):
|
|
||||||
if other in self.values:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
Date = datetime.date
|
|
||||||
Time = datetime.time
|
|
||||||
Timestamp = datetime.datetime
|
|
||||||
|
|
||||||
def DateFromTicks(ticks):
|
|
||||||
return Date(*time.localtime(ticks)[:3])
|
|
||||||
|
|
||||||
def TimeFromTicks(ticks):
|
|
||||||
return Time(*time.localtime(ticks)[3:6])
|
|
||||||
|
|
||||||
def TimestampFromTicks(ticks):
|
|
||||||
return Timestamp(*time.localtime(ticks)[:6])
|
|
||||||
|
|
||||||
Binary = bytes
|
|
||||||
|
|
||||||
STRING = _DBAPITypeObject(*constants.FieldType.get_string_types())
|
|
||||||
BINARY = _DBAPITypeObject(*constants.FieldType.get_binary_types())
|
|
||||||
NUMBER = _DBAPITypeObject(*constants.FieldType.get_number_types())
|
|
||||||
DATETIME = _DBAPITypeObject(*constants.FieldType.get_timestamp_types())
|
|
||||||
ROWID = _DBAPITypeObject()
|
|
@ -1,546 +0,0 @@
|
|||||||
# MySQL Connector/Python - MySQL driver written in Python.
|
|
||||||
|
|
||||||
"""Django database Backend using MySQL Connector/Python
|
|
||||||
|
|
||||||
This Django database backend is heavily based on the MySQL backend coming
|
|
||||||
with Django.
|
|
||||||
|
|
||||||
Changes include:
|
|
||||||
* Support for microseconds (MySQL 5.6.3 and later)
|
|
||||||
* Using INFORMATION_SCHEMA where possible
|
|
||||||
* Using new defaults for, for example SQL_AUTO_IS_NULL
|
|
||||||
|
|
||||||
Requires and comes with MySQL Connector/Python v1.1 and later:
|
|
||||||
http://dev.mysql.com/downloads/connector/python/
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
import django
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
|
||||||
from django.utils.functional import cached_property
|
|
||||||
|
|
||||||
try:
|
|
||||||
import mysql.connector
|
|
||||||
from mysql.connector.conversion import MySQLConverter, MySQLConverterBase
|
|
||||||
from mysql.connector.catch23 import PY2
|
|
||||||
except ImportError as err:
|
|
||||||
raise ImproperlyConfigured(
|
|
||||||
"Error loading mysql.connector module: {0}".format(err))
|
|
||||||
|
|
||||||
try:
|
|
||||||
version = mysql.connector.__version_info__[0:3]
|
|
||||||
except AttributeError:
|
|
||||||
from mysql.connector.version import VERSION
|
|
||||||
version = VERSION[0:3]
|
|
||||||
|
|
||||||
try:
|
|
||||||
from _mysql_connector import datetime_to_mysql, time_to_mysql
|
|
||||||
except ImportError:
|
|
||||||
HAVE_CEXT = False
|
|
||||||
else:
|
|
||||||
HAVE_CEXT = True
|
|
||||||
|
|
||||||
if version < (1, 11):
|
|
||||||
raise ImproperlyConfigured(
|
|
||||||
"MySQL Connector/Python v1.11.0 or newer "
|
|
||||||
"is required; you have %s" % mysql.connector.__version__)
|
|
||||||
|
|
||||||
from django.db import utils
|
|
||||||
from django.db.backends import utils as backend_utils
|
|
||||||
from django.db.backends.base.base import BaseDatabaseWrapper
|
|
||||||
from django.db.backends.signals import connection_created
|
|
||||||
from django.utils import (six, timezone, dateparse)
|
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
from mysql.connector.django.client import DatabaseClient
|
|
||||||
from mysql.connector.django.creation import DatabaseCreation
|
|
||||||
from mysql.connector.django.introspection import DatabaseIntrospection
|
|
||||||
from mysql.connector.django.validation import DatabaseValidation
|
|
||||||
from mysql.connector.django.features import DatabaseFeatures
|
|
||||||
from mysql.connector.django.operations import DatabaseOperations
|
|
||||||
from mysql.connector.django.schema import DatabaseSchemaEditor
|
|
||||||
|
|
||||||
|
|
||||||
DatabaseError = mysql.connector.DatabaseError
|
|
||||||
IntegrityError = mysql.connector.IntegrityError
|
|
||||||
NotSupportedError = mysql.connector.NotSupportedError
|
|
||||||
|
|
||||||
|
|
||||||
def adapt_datetime_with_timezone_support(value):
|
|
||||||
# Equivalent to DateTimeField.get_db_prep_value. Used only by raw SQL.
|
|
||||||
if settings.USE_TZ:
|
|
||||||
if timezone.is_naive(value):
|
|
||||||
warnings.warn("MySQL received a naive datetime (%s)"
|
|
||||||
" while time zone support is active." % value,
|
|
||||||
RuntimeWarning)
|
|
||||||
default_timezone = timezone.get_default_timezone()
|
|
||||||
value = timezone.make_aware(value, default_timezone)
|
|
||||||
value = value.astimezone(timezone.utc).replace(tzinfo=None)
|
|
||||||
if HAVE_CEXT:
|
|
||||||
return datetime_to_mysql(value)
|
|
||||||
else:
|
|
||||||
return value.strftime("%Y-%m-%d %H:%M:%S.%f")
|
|
||||||
|
|
||||||
|
|
||||||
class DjangoMySQLConverter(MySQLConverter):
|
|
||||||
"""Custom converter for Django for MySQLConnection"""
|
|
||||||
def _TIME_to_python(self, value, dsc=None):
|
|
||||||
"""Return MySQL TIME data type as datetime.time()
|
|
||||||
|
|
||||||
Returns datetime.time()
|
|
||||||
"""
|
|
||||||
return dateparse.parse_time(value.decode('utf-8'))
|
|
||||||
|
|
||||||
def _DATETIME_to_python(self, value, dsc=None):
|
|
||||||
"""Connector/Python always returns naive datetime.datetime
|
|
||||||
|
|
||||||
Connector/Python always returns naive timestamps since MySQL has
|
|
||||||
no time zone support. Since Django needs non-naive, we need to add
|
|
||||||
the UTC time zone.
|
|
||||||
|
|
||||||
Returns datetime.datetime()
|
|
||||||
"""
|
|
||||||
if not value:
|
|
||||||
return None
|
|
||||||
dt = MySQLConverter._DATETIME_to_python(self, value)
|
|
||||||
if dt is None:
|
|
||||||
return None
|
|
||||||
if settings.USE_TZ and timezone.is_naive(dt):
|
|
||||||
dt = dt.replace(tzinfo=timezone.utc)
|
|
||||||
return dt
|
|
||||||
|
|
||||||
def _safetext_to_mysql(self, value):
|
|
||||||
if PY2:
|
|
||||||
return self._unicode_to_mysql(value)
|
|
||||||
else:
|
|
||||||
return self._str_to_mysql(value)
|
|
||||||
|
|
||||||
def _safebytes_to_mysql(self, value):
|
|
||||||
return self._bytes_to_mysql(value)
|
|
||||||
|
|
||||||
|
|
||||||
class DjangoCMySQLConverter(MySQLConverterBase):
|
|
||||||
"""Custom converter for Django for CMySQLConnection"""
|
|
||||||
def _TIME_to_python(self, value, dsc=None):
|
|
||||||
"""Return MySQL TIME data type as datetime.time()
|
|
||||||
|
|
||||||
Returns datetime.time()
|
|
||||||
"""
|
|
||||||
return dateparse.parse_time(str(value))
|
|
||||||
|
|
||||||
def _DATETIME_to_python(self, value, dsc=None):
|
|
||||||
"""Connector/Python always returns naive datetime.datetime
|
|
||||||
|
|
||||||
Connector/Python always returns naive timestamps since MySQL has
|
|
||||||
no time zone support. Since Django needs non-naive, we need to add
|
|
||||||
the UTC time zone.
|
|
||||||
|
|
||||||
Returns datetime.datetime()
|
|
||||||
"""
|
|
||||||
if not value:
|
|
||||||
return None
|
|
||||||
if settings.USE_TZ and timezone.is_naive(value):
|
|
||||||
value = value.replace(tzinfo=timezone.utc)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
class CursorWrapper(object):
|
|
||||||
"""Wrapper around MySQL Connector/Python's cursor class.
|
|
||||||
|
|
||||||
The cursor class is defined by the options passed to MySQL
|
|
||||||
Connector/Python. If buffered option is True in those options,
|
|
||||||
MySQLCursorBuffered will be used.
|
|
||||||
"""
|
|
||||||
codes_for_integrityerror = (1048,)
|
|
||||||
|
|
||||||
def __init__(self, cursor):
|
|
||||||
self.cursor = cursor
|
|
||||||
|
|
||||||
def _execute_wrapper(self, method, query, args):
|
|
||||||
"""Wrapper around execute() and executemany()"""
|
|
||||||
try:
|
|
||||||
return method(query, args)
|
|
||||||
except (mysql.connector.ProgrammingError) as err:
|
|
||||||
six.reraise(utils.ProgrammingError,
|
|
||||||
utils.ProgrammingError(err.msg), sys.exc_info()[2])
|
|
||||||
except (mysql.connector.IntegrityError) as err:
|
|
||||||
six.reraise(utils.IntegrityError,
|
|
||||||
utils.IntegrityError(err.msg), sys.exc_info()[2])
|
|
||||||
except mysql.connector.OperationalError as err:
|
|
||||||
# Map some error codes to IntegrityError, since they seem to be
|
|
||||||
# misclassified and Django would prefer the more logical place.
|
|
||||||
if err.args[0] in self.codes_for_integrityerror:
|
|
||||||
six.reraise(utils.IntegrityError,
|
|
||||||
utils.IntegrityError(err.msg), sys.exc_info()[2])
|
|
||||||
else:
|
|
||||||
six.reraise(utils.DatabaseError,
|
|
||||||
utils.DatabaseError(err.msg), sys.exc_info()[2])
|
|
||||||
except mysql.connector.DatabaseError as err:
|
|
||||||
six.reraise(utils.DatabaseError,
|
|
||||||
utils.DatabaseError(err.msg), sys.exc_info()[2])
|
|
||||||
|
|
||||||
def _adapt_execute_args_dict(self, args):
|
|
||||||
if not args:
|
|
||||||
return args
|
|
||||||
new_args = dict(args)
|
|
||||||
for key, value in args.items():
|
|
||||||
if isinstance(value, datetime):
|
|
||||||
new_args[key] = adapt_datetime_with_timezone_support(value)
|
|
||||||
|
|
||||||
return new_args
|
|
||||||
|
|
||||||
def _adapt_execute_args(self, args):
|
|
||||||
if not args:
|
|
||||||
return args
|
|
||||||
new_args = list(args)
|
|
||||||
for i, arg in enumerate(args):
|
|
||||||
if isinstance(arg, datetime):
|
|
||||||
new_args[i] = adapt_datetime_with_timezone_support(arg)
|
|
||||||
|
|
||||||
return tuple(new_args)
|
|
||||||
|
|
||||||
def execute(self, query, args=None):
|
|
||||||
"""Executes the given operation
|
|
||||||
|
|
||||||
This wrapper method around the execute()-method of the cursor is
|
|
||||||
mainly needed to re-raise using different exceptions.
|
|
||||||
"""
|
|
||||||
if isinstance(args, dict):
|
|
||||||
new_args = self._adapt_execute_args_dict(args)
|
|
||||||
else:
|
|
||||||
new_args = self._adapt_execute_args(args)
|
|
||||||
return self._execute_wrapper(self.cursor.execute, query, new_args)
|
|
||||||
|
|
||||||
def executemany(self, query, args):
|
|
||||||
"""Executes the given operation
|
|
||||||
|
|
||||||
This wrapper method around the executemany()-method of the cursor is
|
|
||||||
mainly needed to re-raise using different exceptions.
|
|
||||||
"""
|
|
||||||
return self._execute_wrapper(self.cursor.executemany, query, args)
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
"""Return attribute of wrapped cursor"""
|
|
||||||
return getattr(self.cursor, attr)
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
"""Returns iterator over wrapped cursor"""
|
|
||||||
return iter(self.cursor)
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, exc_traceback):
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseWrapper(BaseDatabaseWrapper):
|
|
||||||
vendor = 'mysql'
|
|
||||||
# This dictionary maps Field objects to their associated MySQL column
|
|
||||||
# types, as strings. Column-type strings can contain format strings; they'll
|
|
||||||
# be interpolated against the values of Field.__dict__ before being output.
|
|
||||||
# If a column type is set to None, it won't be included in the output.
|
|
||||||
|
|
||||||
_data_types = {
|
|
||||||
'AutoField': 'integer AUTO_INCREMENT',
|
|
||||||
'BinaryField': 'longblob',
|
|
||||||
'BooleanField': 'bool',
|
|
||||||
'CharField': 'varchar(%(max_length)s)',
|
|
||||||
'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
|
|
||||||
'DateField': 'date',
|
|
||||||
'DateTimeField': 'datetime',
|
|
||||||
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
|
|
||||||
'DurationField': 'bigint',
|
|
||||||
'FileField': 'varchar(%(max_length)s)',
|
|
||||||
'FilePathField': 'varchar(%(max_length)s)',
|
|
||||||
'FloatField': 'double precision',
|
|
||||||
'IntegerField': 'integer',
|
|
||||||
'BigIntegerField': 'bigint',
|
|
||||||
'IPAddressField': 'char(15)',
|
|
||||||
'GenericIPAddressField': 'char(39)',
|
|
||||||
'NullBooleanField': 'bool',
|
|
||||||
'OneToOneField': 'integer',
|
|
||||||
'PositiveIntegerField': 'integer UNSIGNED',
|
|
||||||
'PositiveSmallIntegerField': 'smallint UNSIGNED',
|
|
||||||
'SlugField': 'varchar(%(max_length)s)',
|
|
||||||
'SmallIntegerField': 'smallint',
|
|
||||||
'TextField': 'longtext',
|
|
||||||
'TimeField': 'time',
|
|
||||||
'UUIDField': 'char(32)',
|
|
||||||
}
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def data_types(self):
|
|
||||||
if self.features.supports_microsecond_precision:
|
|
||||||
return dict(self._data_types, DateTimeField='datetime(6)',
|
|
||||||
TimeField='time(6)')
|
|
||||||
else:
|
|
||||||
return self._data_types
|
|
||||||
|
|
||||||
operators = {
|
|
||||||
'exact': '= %s',
|
|
||||||
'iexact': 'LIKE %s',
|
|
||||||
'contains': 'LIKE BINARY %s',
|
|
||||||
'icontains': 'LIKE %s',
|
|
||||||
'regex': 'REGEXP BINARY %s',
|
|
||||||
'iregex': 'REGEXP %s',
|
|
||||||
'gt': '> %s',
|
|
||||||
'gte': '>= %s',
|
|
||||||
'lt': '< %s',
|
|
||||||
'lte': '<= %s',
|
|
||||||
'startswith': 'LIKE BINARY %s',
|
|
||||||
'endswith': 'LIKE BINARY %s',
|
|
||||||
'istartswith': 'LIKE %s',
|
|
||||||
'iendswith': 'LIKE %s',
|
|
||||||
}
|
|
||||||
|
|
||||||
# The patterns below are used to generate SQL pattern lookup clauses when
|
|
||||||
# the right-hand side of the lookup isn't a raw string (it might be an
|
|
||||||
# expression or the result of a bilateral transformation).
|
|
||||||
# In those cases, special characters for LIKE operators (e.g. \, *, _)
|
|
||||||
# should be escaped on database side.
|
|
||||||
#
|
|
||||||
# Note: we use str.format() here for readability as '%' is used as a
|
|
||||||
# wildcard for the LIKE operator.
|
|
||||||
pattern_esc = (r"REPLACE(REPLACE(REPLACE({}, '\\', '\\\\'),"
|
|
||||||
r" '%%', '\%%'), '_', '\_')")
|
|
||||||
pattern_ops = {
|
|
||||||
'contains': "LIKE BINARY CONCAT('%%', {}, '%%')",
|
|
||||||
'icontains': "LIKE CONCAT('%%', {}, '%%')",
|
|
||||||
'startswith': "LIKE BINARY CONCAT({}, '%%')",
|
|
||||||
'istartswith': "LIKE CONCAT({}, '%%')",
|
|
||||||
'endswith': "LIKE BINARY CONCAT('%%', {})",
|
|
||||||
'iendswith': "LIKE CONCAT('%%', {})",
|
|
||||||
}
|
|
||||||
|
|
||||||
SchemaEditorClass = DatabaseSchemaEditor
|
|
||||||
Database = mysql.connector
|
|
||||||
|
|
||||||
client_class = DatabaseClient
|
|
||||||
creation_class = DatabaseCreation
|
|
||||||
features_class = DatabaseFeatures
|
|
||||||
introspection_class = DatabaseIntrospection
|
|
||||||
ops_class = DatabaseOperations
|
|
||||||
validation_class = DatabaseValidation
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super(DatabaseWrapper, self).__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._use_pure = self.settings_dict['OPTIONS']['use_pure']
|
|
||||||
except KeyError:
|
|
||||||
self._use_pure = True
|
|
||||||
|
|
||||||
if not self.use_pure:
|
|
||||||
self.converter = DjangoCMySQLConverter()
|
|
||||||
else:
|
|
||||||
self.converter = DjangoMySQLConverter()
|
|
||||||
|
|
||||||
def _valid_connection(self):
|
|
||||||
if self.connection:
|
|
||||||
return self.connection.is_connected()
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_connection_params(self):
|
|
||||||
kwargs = {
|
|
||||||
'charset': 'utf8',
|
|
||||||
'use_unicode': True,
|
|
||||||
'buffered': False,
|
|
||||||
'consume_results': True,
|
|
||||||
}
|
|
||||||
|
|
||||||
settings_dict = self.settings_dict
|
|
||||||
|
|
||||||
if settings_dict['USER']:
|
|
||||||
kwargs['user'] = settings_dict['USER']
|
|
||||||
if settings_dict['NAME']:
|
|
||||||
kwargs['database'] = settings_dict['NAME']
|
|
||||||
if settings_dict['PASSWORD']:
|
|
||||||
kwargs['passwd'] = settings_dict['PASSWORD']
|
|
||||||
if settings_dict['HOST'].startswith('/'):
|
|
||||||
kwargs['unix_socket'] = settings_dict['HOST']
|
|
||||||
elif settings_dict['HOST']:
|
|
||||||
kwargs['host'] = settings_dict['HOST']
|
|
||||||
if settings_dict['PORT']:
|
|
||||||
kwargs['port'] = int(settings_dict['PORT'])
|
|
||||||
|
|
||||||
# Raise exceptions for database warnings if DEBUG is on
|
|
||||||
kwargs['raise_on_warnings'] = settings.DEBUG
|
|
||||||
|
|
||||||
kwargs['client_flags'] = [
|
|
||||||
# Need potentially affected rows on UPDATE
|
|
||||||
mysql.connector.constants.ClientFlag.FOUND_ROWS,
|
|
||||||
]
|
|
||||||
try:
|
|
||||||
kwargs.update(settings_dict['OPTIONS'])
|
|
||||||
except KeyError:
|
|
||||||
# OPTIONS missing is OK
|
|
||||||
pass
|
|
||||||
|
|
||||||
return kwargs
|
|
||||||
|
|
||||||
def get_new_connection(self, conn_params):
|
|
||||||
if not self.use_pure:
|
|
||||||
conn_params['converter_class'] = DjangoCMySQLConverter
|
|
||||||
else:
|
|
||||||
conn_params['converter_class'] = DjangoMySQLConverter
|
|
||||||
cnx = mysql.connector.connect(**conn_params)
|
|
||||||
|
|
||||||
return cnx
|
|
||||||
|
|
||||||
def init_connection_state(self):
|
|
||||||
if self.mysql_version < (5, 5, 3):
|
|
||||||
# See sysvar_sql_auto_is_null in MySQL Reference manual
|
|
||||||
self.connection.cmd_query("SET SQL_AUTO_IS_NULL = 0")
|
|
||||||
|
|
||||||
if 'AUTOCOMMIT' in self.settings_dict:
|
|
||||||
try:
|
|
||||||
self.set_autocommit(self.settings_dict['AUTOCOMMIT'])
|
|
||||||
except AttributeError:
|
|
||||||
self._set_autocommit(self.settings_dict['AUTOCOMMIT'])
|
|
||||||
|
|
||||||
def create_cursor(self, name=None):
|
|
||||||
cursor = self.connection.cursor()
|
|
||||||
return CursorWrapper(cursor)
|
|
||||||
|
|
||||||
def _connect(self):
|
|
||||||
"""Setup the connection with MySQL"""
|
|
||||||
self.connection = self.get_new_connection(self.get_connection_params())
|
|
||||||
connection_created.send(sender=self.__class__, connection=self)
|
|
||||||
self.init_connection_state()
|
|
||||||
|
|
||||||
def _cursor(self):
|
|
||||||
"""Return a CursorWrapper object
|
|
||||||
|
|
||||||
Returns a CursorWrapper
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return super(DatabaseWrapper, self)._cursor()
|
|
||||||
except AttributeError:
|
|
||||||
if not self.connection:
|
|
||||||
self._connect()
|
|
||||||
return self.create_cursor()
|
|
||||||
|
|
||||||
def get_server_version(self):
|
|
||||||
"""Returns the MySQL server version of current connection
|
|
||||||
|
|
||||||
Returns a tuple
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
self.ensure_connection()
|
|
||||||
except AttributeError:
|
|
||||||
if not self.connection:
|
|
||||||
self._connect()
|
|
||||||
|
|
||||||
return self.connection.get_server_version()
|
|
||||||
|
|
||||||
def disable_constraint_checking(self):
|
|
||||||
"""Disables foreign key checks
|
|
||||||
|
|
||||||
Disables foreign key checks, primarily for use in adding rows with
|
|
||||||
forward references. Always returns True,
|
|
||||||
to indicate constraint checks need to be re-enabled.
|
|
||||||
|
|
||||||
Returns True
|
|
||||||
"""
|
|
||||||
self.cursor().execute('SET @@session.foreign_key_checks = 0')
|
|
||||||
return True
|
|
||||||
|
|
||||||
def enable_constraint_checking(self):
|
|
||||||
"""Re-enable foreign key checks
|
|
||||||
|
|
||||||
Re-enable foreign key checks after they have been disabled.
|
|
||||||
"""
|
|
||||||
# Override needs_rollback in case constraint_checks_disabled is
|
|
||||||
# nested inside transaction.atomic.
|
|
||||||
self.needs_rollback, needs_rollback = False, self.needs_rollback
|
|
||||||
try:
|
|
||||||
self.cursor().execute('SET @@session.foreign_key_checks = 1')
|
|
||||||
finally:
|
|
||||||
self.needs_rollback = needs_rollback
|
|
||||||
|
|
||||||
def check_constraints(self, table_names=None):
|
|
||||||
"""Check rows in tables for invalid foreign key references
|
|
||||||
|
|
||||||
Checks each table name in `table_names` for rows with invalid foreign
|
|
||||||
key references. This method is intended to be used in conjunction with
|
|
||||||
`disable_constraint_checking()` and `enable_constraint_checking()`, to
|
|
||||||
determine if rows with invalid references were entered while
|
|
||||||
constraint checks were off.
|
|
||||||
|
|
||||||
Raises an IntegrityError on the first invalid foreign key reference
|
|
||||||
encountered (if any) and provides detailed information about the
|
|
||||||
invalid reference in the error message.
|
|
||||||
|
|
||||||
Backends can override this method if they can more directly apply
|
|
||||||
constraint checking (e.g. via "SET CONSTRAINTS ALL IMMEDIATE")
|
|
||||||
"""
|
|
||||||
ref_query = """
|
|
||||||
SELECT REFERRING.`{0}`, REFERRING.`{1}` FROM `{2}` as REFERRING
|
|
||||||
LEFT JOIN `{3}` as REFERRED
|
|
||||||
ON (REFERRING.`{4}` = REFERRED.`{5}`)
|
|
||||||
WHERE REFERRING.`{6}` IS NOT NULL AND REFERRED.`{7}` IS NULL"""
|
|
||||||
cursor = self.cursor()
|
|
||||||
if table_names is None:
|
|
||||||
table_names = self.introspection.table_names(cursor)
|
|
||||||
for table_name in table_names:
|
|
||||||
primary_key_column_name = \
|
|
||||||
self.introspection.get_primary_key_column(cursor, table_name)
|
|
||||||
if not primary_key_column_name:
|
|
||||||
continue
|
|
||||||
key_columns = self.introspection.get_key_columns(cursor,
|
|
||||||
table_name)
|
|
||||||
for column_name, referenced_table_name, referenced_column_name \
|
|
||||||
in key_columns:
|
|
||||||
cursor.execute(ref_query.format(primary_key_column_name,
|
|
||||||
column_name, table_name,
|
|
||||||
referenced_table_name,
|
|
||||||
column_name,
|
|
||||||
referenced_column_name,
|
|
||||||
column_name,
|
|
||||||
referenced_column_name))
|
|
||||||
for bad_row in cursor.fetchall():
|
|
||||||
msg = ("The row in table '{0}' with primary key '{1}' has "
|
|
||||||
"an invalid foreign key: {2}.{3} contains a value "
|
|
||||||
"'{4}' that does not have a corresponding value in "
|
|
||||||
"{5}.{6}.".format(table_name, bad_row[0],
|
|
||||||
table_name, column_name,
|
|
||||||
bad_row[1], referenced_table_name,
|
|
||||||
referenced_column_name))
|
|
||||||
raise utils.IntegrityError(msg)
|
|
||||||
|
|
||||||
def _rollback(self):
|
|
||||||
try:
|
|
||||||
BaseDatabaseWrapper._rollback(self)
|
|
||||||
except NotSupportedError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _set_autocommit(self, autocommit):
|
|
||||||
with self.wrap_database_errors:
|
|
||||||
self.connection.autocommit = autocommit
|
|
||||||
|
|
||||||
def schema_editor(self, *args, **kwargs):
|
|
||||||
"""Returns a new instance of this backend's SchemaEditor"""
|
|
||||||
return DatabaseSchemaEditor(self, *args, **kwargs)
|
|
||||||
|
|
||||||
def is_usable(self):
|
|
||||||
return self.connection.is_connected()
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def mysql_version(self):
|
|
||||||
config = self.get_connection_params()
|
|
||||||
temp_conn = mysql.connector.connect(**config)
|
|
||||||
server_version = temp_conn.get_server_version()
|
|
||||||
temp_conn.close()
|
|
||||||
|
|
||||||
return server_version
|
|
||||||
|
|
||||||
@property
|
|
||||||
def use_pure(self):
|
|
||||||
return not HAVE_CEXT or self._use_pure
|
|
@ -1,54 +0,0 @@
|
|||||||
# MySQL Connector/Python - MySQL driver written in Python.
|
|
||||||
|
|
||||||
import django
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from django.db.backends.base.client import BaseDatabaseClient
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseClient(BaseDatabaseClient):
|
|
||||||
executable_name = 'mysql'
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def settings_to_cmd_args(cls, settings_dict):
|
|
||||||
args = [cls.executable_name]
|
|
||||||
|
|
||||||
db = settings_dict['OPTIONS'].get('database', settings_dict['NAME'])
|
|
||||||
user = settings_dict['OPTIONS'].get('user',
|
|
||||||
settings_dict['USER'])
|
|
||||||
passwd = settings_dict['OPTIONS'].get('password',
|
|
||||||
settings_dict['PASSWORD'])
|
|
||||||
host = settings_dict['OPTIONS'].get('host', settings_dict['HOST'])
|
|
||||||
port = settings_dict['OPTIONS'].get('port', settings_dict['PORT'])
|
|
||||||
defaults_file = settings_dict['OPTIONS'].get('read_default_file')
|
|
||||||
|
|
||||||
# --defaults-file should always be the first option
|
|
||||||
if defaults_file:
|
|
||||||
args.append("--defaults-file={0}".format(defaults_file))
|
|
||||||
|
|
||||||
# We force SQL_MODE to TRADITIONAL
|
|
||||||
args.append("--init-command=SET @@session.SQL_MODE=TRADITIONAL")
|
|
||||||
|
|
||||||
if user:
|
|
||||||
args.append("--user={0}".format(user))
|
|
||||||
if passwd:
|
|
||||||
args.append("--password={0}".format(passwd))
|
|
||||||
|
|
||||||
if host:
|
|
||||||
if '/' in host:
|
|
||||||
args.append("--socket={0}".format(host))
|
|
||||||
else:
|
|
||||||
args.append("--host={0}".format(host))
|
|
||||||
|
|
||||||
if port:
|
|
||||||
args.append("--port={0}".format(port))
|
|
||||||
|
|
||||||
if db:
|
|
||||||
args.append("--database={0}".format(db))
|
|
||||||
|
|
||||||
return args
|
|
||||||
|
|
||||||
def runshell(self):
|
|
||||||
args = DatabaseClient.settings_to_cmd_args(
|
|
||||||
self.connection.settings_dict)
|
|
||||||
subprocess.call(args)
|
|
@ -1,41 +0,0 @@
|
|||||||
# MySQL Connector/Python - MySQL driver written in Python.
|
|
||||||
|
|
||||||
|
|
||||||
import django
|
|
||||||
from django.db.models.sql import compiler
|
|
||||||
from django.utils.six.moves import zip_longest
|
|
||||||
|
|
||||||
|
|
||||||
class SQLCompiler(compiler.SQLCompiler):
|
|
||||||
def resolve_columns(self, row, fields=()):
|
|
||||||
values = []
|
|
||||||
index_extra_select = len(self.query.extra_select)
|
|
||||||
bool_fields = ("BooleanField", "NullBooleanField")
|
|
||||||
for value, field in zip_longest(row[index_extra_select:], fields):
|
|
||||||
if (field and field.get_internal_type() in bool_fields and
|
|
||||||
value in (0, 1)):
|
|
||||||
value = bool(value)
|
|
||||||
values.append(value)
|
|
||||||
return row[:index_extra_select] + tuple(values)
|
|
||||||
|
|
||||||
def as_subquery_condition(self, alias, columns, compiler):
|
|
||||||
qn = compiler.quote_name_unless_alias
|
|
||||||
qn2 = self.connection.ops.quote_name
|
|
||||||
sql, params = self.as_sql()
|
|
||||||
return '(%s) IN (%s)' % (', '.join('%s.%s' % (qn(alias), qn2(column)) for column in columns), sql), params
|
|
||||||
|
|
||||||
|
|
||||||
class SQLInsertCompiler(compiler.SQLInsertCompiler, SQLCompiler):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SQLDeleteCompiler(compiler.SQLDeleteCompiler, SQLCompiler):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SQLUpdateCompiler(compiler.SQLUpdateCompiler, SQLCompiler):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SQLAggregateCompiler(compiler.SQLAggregateCompiler, SQLCompiler):
|
|
||||||
pass
|
|
@ -1,84 +0,0 @@
|
|||||||
# MySQL Connector/Python - MySQL driver written in Python.
|
|
||||||
|
|
||||||
import django
|
|
||||||
from django.db import models
|
|
||||||
|
|
||||||
from django.db.backends.base.creation import BaseDatabaseCreation
|
|
||||||
from django.db.backends.utils import truncate_name
|
|
||||||
|
|
||||||
class DatabaseCreation(BaseDatabaseCreation):
|
|
||||||
"""Maps Django Field object with MySQL data types
|
|
||||||
"""
|
|
||||||
def __init__(self, connection):
|
|
||||||
super(DatabaseCreation, self).__init__(connection)
|
|
||||||
|
|
||||||
def sql_table_creation_suffix(self):
|
|
||||||
suffix = []
|
|
||||||
test_settings = self.connection.settings_dict['TEST']
|
|
||||||
if test_settings['CHARSET']:
|
|
||||||
suffix.append('CHARACTER SET %s' % test_settings['CHARSET'])
|
|
||||||
if test_settings['COLLATION']:
|
|
||||||
suffix.append('COLLATE %s' % test_settings['COLLATION'])
|
|
||||||
|
|
||||||
return ' '.join(suffix)
|
|
||||||
|
|
||||||
def sql_for_inline_foreign_key_references(self, model, field,
|
|
||||||
known_models, style):
|
|
||||||
"All inline references are pending under MySQL"
|
|
||||||
return [], True
|
|
||||||
|
|
||||||
def sql_for_inline_many_to_many_references(self, model, field, style):
|
|
||||||
opts = model._meta
|
|
||||||
qn = self.connection.ops.quote_name
|
|
||||||
|
|
||||||
columndef = ' {column} {type} {options},'
|
|
||||||
table_output = [
|
|
||||||
columndef.format(
|
|
||||||
column=style.SQL_FIELD(qn(field.m2m_column_name())),
|
|
||||||
type=style.SQL_COLTYPE(models.ForeignKey(model).db_type(
|
|
||||||
connection=self.connection)),
|
|
||||||
options=style.SQL_KEYWORD('NOT NULL')
|
|
||||||
),
|
|
||||||
columndef.format(
|
|
||||||
column=style.SQL_FIELD(qn(field.m2m_reverse_name())),
|
|
||||||
type=style.SQL_COLTYPE(models.ForeignKey(field.rel.to).db_type(
|
|
||||||
connection=self.connection)),
|
|
||||||
options=style.SQL_KEYWORD('NOT NULL')
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
||||||
deferred = [
|
|
||||||
(field.m2m_db_table(), field.m2m_column_name(), opts.db_table,
|
|
||||||
opts.pk.column),
|
|
||||||
(field.m2m_db_table(), field.m2m_reverse_name(),
|
|
||||||
field.rel.to._meta.db_table, field.rel.to._meta.pk.column)
|
|
||||||
]
|
|
||||||
return table_output, deferred
|
|
||||||
|
|
||||||
def sql_destroy_indexes_for_fields(self, model, fields, style):
|
|
||||||
if len(fields) == 1 and fields[0].db_tablespace:
|
|
||||||
tablespace_sql = self.connection.ops.tablespace_sql(
|
|
||||||
fields[0].db_tablespace)
|
|
||||||
elif model._meta.db_tablespace:
|
|
||||||
tablespace_sql = self.connection.ops.tablespace_sql(
|
|
||||||
model._meta.db_tablespace)
|
|
||||||
else:
|
|
||||||
tablespace_sql = ""
|
|
||||||
if tablespace_sql:
|
|
||||||
tablespace_sql = " " + tablespace_sql
|
|
||||||
|
|
||||||
field_names = []
|
|
||||||
qn = self.connection.ops.quote_name
|
|
||||||
for f in fields:
|
|
||||||
field_names.append(style.SQL_FIELD(qn(f.column)))
|
|
||||||
|
|
||||||
index_name = "{0}_{1}".format(model._meta.db_table,
|
|
||||||
self._digest([f.name for f in fields]))
|
|
||||||
|
|
||||||
return [
|
|
||||||
style.SQL_KEYWORD("DROP INDEX") + " " +
|
|
||||||
style.SQL_TABLE(qn(truncate_name(index_name,
|
|
||||||
self.connection.ops.max_name_length()))) + " " +
|
|
||||||
style.SQL_KEYWORD("ON") + " " +
|
|
||||||
style.SQL_TABLE(qn(model._meta.db_table)) + ";",
|
|
||||||
]
|
|
@ -1,115 +0,0 @@
|
|||||||
# MySQL Connector/Python - MySQL driver written in Python.
|
|
||||||
|
|
||||||
import django
|
|
||||||
from django.db.backends.base.features import BaseDatabaseFeatures
|
|
||||||
from django.utils.functional import cached_property
|
|
||||||
from django.utils import six
|
|
||||||
|
|
||||||
try:
|
|
||||||
import pytz
|
|
||||||
HAVE_PYTZ = True
|
|
||||||
except ImportError:
|
|
||||||
HAVE_PYTZ = False
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseFeatures(BaseDatabaseFeatures):
|
|
||||||
"""Features specific to MySQL
|
|
||||||
|
|
||||||
Microsecond precision is supported since MySQL 5.6.3 and turned on
|
|
||||||
by default if this MySQL version is used.
|
|
||||||
"""
|
|
||||||
empty_fetchmany_value = []
|
|
||||||
update_can_self_select = False
|
|
||||||
allows_group_by_pk = True
|
|
||||||
related_fields_match_type = True
|
|
||||||
allow_sliced_subqueries = False
|
|
||||||
has_bulk_insert = True
|
|
||||||
has_select_for_update = True
|
|
||||||
has_select_for_update_nowait = False
|
|
||||||
supports_forward_references = False
|
|
||||||
supports_regex_backreferencing = False
|
|
||||||
supports_date_lookup_using_string = False
|
|
||||||
can_introspect_autofield = True
|
|
||||||
can_introspect_binary_field = False
|
|
||||||
can_introspect_small_integer_field = True
|
|
||||||
supports_timezones = False
|
|
||||||
requires_explicit_null_ordering_when_grouping = True
|
|
||||||
allows_auto_pk_0 = False
|
|
||||||
allows_primary_key_0 = False
|
|
||||||
uses_savepoints = True
|
|
||||||
atomic_transactions = False
|
|
||||||
supports_column_check_constraints = False
|
|
||||||
|
|
||||||
def __init__(self, connection):
|
|
||||||
super(DatabaseFeatures, self).__init__(connection)
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def supports_microsecond_precision(self):
|
|
||||||
if self.connection.mysql_version >= (5, 6, 3):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def mysql_storage_engine(self):
|
|
||||||
"""Get default storage engine of MySQL
|
|
||||||
|
|
||||||
This method creates a table without ENGINE table option and inspects
|
|
||||||
which engine was used.
|
|
||||||
|
|
||||||
Used by Django tests.
|
|
||||||
"""
|
|
||||||
tblname = 'INTROSPECT_TEST'
|
|
||||||
|
|
||||||
droptable = 'DROP TABLE IF EXISTS {table}'.format(table=tblname)
|
|
||||||
with self.connection.cursor() as cursor:
|
|
||||||
cursor.execute(droptable)
|
|
||||||
cursor.execute('CREATE TABLE {table} (X INT)'.format(table=tblname))
|
|
||||||
|
|
||||||
if self.connection.mysql_version >= (5, 0, 0):
|
|
||||||
cursor.execute(
|
|
||||||
"SELECT ENGINE FROM INFORMATION_SCHEMA.TABLES "
|
|
||||||
"WHERE TABLE_SCHEMA = %s AND TABLE_NAME = %s",
|
|
||||||
(self.connection.settings_dict['NAME'], tblname))
|
|
||||||
engine = cursor.fetchone()[0]
|
|
||||||
else:
|
|
||||||
# Very old MySQL servers..
|
|
||||||
cursor.execute("SHOW TABLE STATUS WHERE Name='{table}'".format(
|
|
||||||
table=tblname))
|
|
||||||
engine = cursor.fetchone()[1]
|
|
||||||
cursor.execute(droptable)
|
|
||||||
|
|
||||||
self._cached_storage_engine = engine
|
|
||||||
return engine
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def _disabled_supports_transactions(self):
|
|
||||||
return self.mysql_storage_engine == 'InnoDB'
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def can_introspect_foreign_keys(self):
|
|
||||||
"""Confirm support for introspected foreign keys
|
|
||||||
|
|
||||||
Only the InnoDB storage engine supports Foreigen Key (not taking
|
|
||||||
into account MySQL Cluster here).
|
|
||||||
"""
|
|
||||||
return self.mysql_storage_engine == 'InnoDB'
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def has_zoneinfo_database(self):
|
|
||||||
"""Tests if the time zone definitions are installed
|
|
||||||
|
|
||||||
MySQL accepts full time zones names (eg. Africa/Nairobi) but rejects
|
|
||||||
abbreviations (eg. EAT). When pytz isn't installed and the current
|
|
||||||
time zone is LocalTimezone (the only sensible value in this context),
|
|
||||||
the current time zone name will be an abbreviation. As a consequence,
|
|
||||||
MySQL cannot perform time zone conversions reliably.
|
|
||||||
"""
|
|
||||||
if not HAVE_PYTZ:
|
|
||||||
return False
|
|
||||||
|
|
||||||
with self.connection.cursor() as cursor:
|
|
||||||
cursor.execute("SELECT 1 FROM mysql.time_zone LIMIT 1")
|
|
||||||
return cursor.fetchall() != []
|
|
||||||
|
|
||||||
def introspected_boolean_field_type(self, *args, **kwargs):
|
|
||||||
return 'IntegerField'
|
|
@ -1,255 +0,0 @@
|
|||||||
# MySQL Connector/Python - MySQL driver written in Python.
|
|
||||||
|
|
||||||
|
|
||||||
import re
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
import django
|
|
||||||
from django.db.backends.base.introspection import (
|
|
||||||
BaseDatabaseIntrospection, FieldInfo, TableInfo
|
|
||||||
)
|
|
||||||
from django.utils.encoding import force_text
|
|
||||||
from django.utils.datastructures import OrderedSet
|
|
||||||
|
|
||||||
from mysql.connector.constants import FieldType
|
|
||||||
|
|
||||||
foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) "
|
|
||||||
r"REFERENCES `([^`]*)` \(`([^`]*)`\)")
|
|
||||||
|
|
||||||
FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('extra',))
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|
||||||
data_types_reverse = {
|
|
||||||
FieldType.BLOB: 'TextField',
|
|
||||||
FieldType.DECIMAL: 'DecimalField',
|
|
||||||
FieldType.NEWDECIMAL: 'DecimalField',
|
|
||||||
FieldType.DATE: 'DateField',
|
|
||||||
FieldType.DATETIME: 'DateTimeField',
|
|
||||||
FieldType.DOUBLE: 'FloatField',
|
|
||||||
FieldType.FLOAT: 'FloatField',
|
|
||||||
FieldType.INT24: 'IntegerField',
|
|
||||||
FieldType.LONG: 'IntegerField',
|
|
||||||
FieldType.LONGLONG: 'BigIntegerField',
|
|
||||||
FieldType.SHORT: 'SmallIntegerField',
|
|
||||||
FieldType.STRING: 'CharField',
|
|
||||||
FieldType.TIME: 'TimeField',
|
|
||||||
FieldType.TIMESTAMP: 'DateTimeField',
|
|
||||||
FieldType.TINY: 'IntegerField',
|
|
||||||
FieldType.TINY_BLOB: 'TextField',
|
|
||||||
FieldType.MEDIUM_BLOB: 'TextField',
|
|
||||||
FieldType.LONG_BLOB: 'TextField',
|
|
||||||
FieldType.VAR_STRING: 'CharField',
|
|
||||||
}
|
|
||||||
|
|
||||||
def get_field_type(self, data_type, description):
|
|
||||||
field_type = super(DatabaseIntrospection, self).get_field_type(
|
|
||||||
data_type, description)
|
|
||||||
if (field_type == 'IntegerField'
|
|
||||||
and 'auto_increment' in description.extra):
|
|
||||||
return 'AutoField'
|
|
||||||
return field_type
|
|
||||||
|
|
||||||
def get_table_list(self, cursor):
|
|
||||||
"""Returns a list of table names in the current database."""
|
|
||||||
cursor.execute("SHOW FULL TABLES")
|
|
||||||
return [
|
|
||||||
TableInfo(row[0], {'BASE TABLE': 't', 'VIEW': 'v'}.get(row[1]))
|
|
||||||
for row in cursor.fetchall()
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_table_description(self, cursor, table_name):
|
|
||||||
"""
|
|
||||||
Returns a description of the table, with the DB-API
|
|
||||||
cursor.description interface."
|
|
||||||
"""
|
|
||||||
# - information_schema database gives more accurate results for
|
|
||||||
# some figures:
|
|
||||||
# - varchar length returned by cursor.description is an internal
|
|
||||||
# length, not visible length (#5725)
|
|
||||||
# - precision and scale (for decimal fields) (#5014)
|
|
||||||
# - auto_increment is not available in cursor.description
|
|
||||||
|
|
||||||
InfoLine = namedtuple('InfoLine', 'col_name data_type max_len '
|
|
||||||
'num_prec num_scale extra column_default')
|
|
||||||
cursor.execute("""
|
|
||||||
SELECT column_name, data_type, character_maximum_length,
|
|
||||||
numeric_precision, numeric_scale, extra, column_default
|
|
||||||
FROM information_schema.columns
|
|
||||||
WHERE table_name = %s AND table_schema = DATABASE()""",
|
|
||||||
[table_name])
|
|
||||||
field_info = dict(
|
|
||||||
(line[0], InfoLine(*line)) for line in cursor.fetchall()
|
|
||||||
)
|
|
||||||
|
|
||||||
cursor.execute("SELECT * FROM %s LIMIT 1"
|
|
||||||
% self.connection.ops.quote_name(table_name))
|
|
||||||
to_int = lambda i: int(i) if i is not None else i
|
|
||||||
fields = []
|
|
||||||
for line in cursor.description:
|
|
||||||
col_name = force_text(line[0])
|
|
||||||
fields.append(
|
|
||||||
FieldInfo(*(
|
|
||||||
(col_name,) +
|
|
||||||
line[1:3] +
|
|
||||||
(
|
|
||||||
to_int(field_info[col_name].max_len) or line[3],
|
|
||||||
to_int(field_info[col_name].num_prec) or line[4],
|
|
||||||
to_int(field_info[col_name].num_scale) or line[5],
|
|
||||||
line[6],
|
|
||||||
field_info[col_name].column_default,
|
|
||||||
field_info[col_name].extra,
|
|
||||||
)
|
|
||||||
))
|
|
||||||
)
|
|
||||||
return fields
|
|
||||||
|
|
||||||
def _name_to_index(self, cursor, table_name):
|
|
||||||
"""
|
|
||||||
Returns a dictionary of {field_name: field_index} for the given table.
|
|
||||||
Indexes are 0-based.
|
|
||||||
"""
|
|
||||||
return dict((d[0], i) for i, d in enumerate(
|
|
||||||
self.get_table_description(cursor, table_name)))
|
|
||||||
|
|
||||||
def get_relations(self, cursor, table_name):
|
|
||||||
"""
|
|
||||||
Returns a dictionary of {field_index: (field_index_other_table,
|
|
||||||
other_table)}
|
|
||||||
representing all relationships to the given table. Indexes are 0-based.
|
|
||||||
"""
|
|
||||||
constraints = self.get_key_columns(cursor, table_name)
|
|
||||||
relations = {}
|
|
||||||
for my_fieldname, other_table, other_field in constraints:
|
|
||||||
relations[my_fieldname] = (other_field, other_table)
|
|
||||||
return relations
|
|
||||||
|
|
||||||
def get_key_columns(self, cursor, table_name):
|
|
||||||
"""
|
|
||||||
Returns a list of (column_name, referenced_table_name,
|
|
||||||
referenced_column_name) for all key columns in given table.
|
|
||||||
"""
|
|
||||||
key_columns = []
|
|
||||||
cursor.execute(
|
|
||||||
"SELECT column_name, referenced_table_name, referenced_column_name "
|
|
||||||
"FROM information_schema.key_column_usage "
|
|
||||||
"WHERE table_name = %s "
|
|
||||||
"AND table_schema = DATABASE() "
|
|
||||||
"AND referenced_table_name IS NOT NULL "
|
|
||||||
"AND referenced_column_name IS NOT NULL", [table_name])
|
|
||||||
key_columns.extend(cursor.fetchall())
|
|
||||||
return key_columns
|
|
||||||
|
|
||||||
def get_indexes(self, cursor, table_name):
|
|
||||||
cursor.execute("SHOW INDEX FROM {0}"
|
|
||||||
"".format(self.connection.ops.quote_name(table_name)))
|
|
||||||
# Do a two-pass search for indexes: on first pass check which indexes
|
|
||||||
# are multicolumn, on second pass check which single-column indexes
|
|
||||||
# are present.
|
|
||||||
rows = list(cursor.fetchall())
|
|
||||||
multicol_indexes = set()
|
|
||||||
for row in rows:
|
|
||||||
if row[3] > 1:
|
|
||||||
multicol_indexes.add(row[2])
|
|
||||||
indexes = {}
|
|
||||||
for row in rows:
|
|
||||||
if row[2] in multicol_indexes:
|
|
||||||
continue
|
|
||||||
if row[4] not in indexes:
|
|
||||||
indexes[row[4]] = {'primary_key': False, 'unique': False}
|
|
||||||
# It's possible to have the unique and PK constraints in
|
|
||||||
# separate indexes.
|
|
||||||
if row[2] == 'PRIMARY':
|
|
||||||
indexes[row[4]]['primary_key'] = True
|
|
||||||
if not row[1]:
|
|
||||||
indexes[row[4]]['unique'] = True
|
|
||||||
return indexes
|
|
||||||
|
|
||||||
def get_primary_key_column(self, cursor, table_name):
|
|
||||||
"""
|
|
||||||
Returns the name of the primary key column for the given table
|
|
||||||
"""
|
|
||||||
for column in self.get_indexes(cursor, table_name).items():
|
|
||||||
if column[1]['primary_key']:
|
|
||||||
return column[0]
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_storage_engine(self, cursor, table_name):
|
|
||||||
"""
|
|
||||||
Retrieves the storage engine for a given table. Returns the default
|
|
||||||
storage engine if the table doesn't exist.
|
|
||||||
"""
|
|
||||||
cursor.execute(
|
|
||||||
"SELECT engine "
|
|
||||||
"FROM information_schema.tables "
|
|
||||||
"WHERE table_name = %s", [table_name])
|
|
||||||
result = cursor.fetchone()
|
|
||||||
if not result:
|
|
||||||
return self.connection.features.mysql_storage_engine
|
|
||||||
return result[0]
|
|
||||||
|
|
||||||
def get_constraints(self, cursor, table_name):
|
|
||||||
"""
|
|
||||||
Retrieves any constraints or keys (unique, pk, fk, check, index) across
|
|
||||||
one or more columns.
|
|
||||||
"""
|
|
||||||
constraints = {}
|
|
||||||
# Get the actual constraint names and columns
|
|
||||||
name_query = (
|
|
||||||
"SELECT kc.`constraint_name`, kc.`column_name`, "
|
|
||||||
"kc.`referenced_table_name`, kc.`referenced_column_name` "
|
|
||||||
"FROM information_schema.key_column_usage AS kc "
|
|
||||||
"WHERE "
|
|
||||||
"kc.table_schema = %s AND "
|
|
||||||
"kc.table_name = %s"
|
|
||||||
)
|
|
||||||
cursor.execute(name_query, [self.connection.settings_dict['NAME'],
|
|
||||||
table_name])
|
|
||||||
for constraint, column, ref_table, ref_column in cursor.fetchall():
|
|
||||||
if constraint not in constraints:
|
|
||||||
constraints[constraint] = {
|
|
||||||
'columns': OrderedSet(),
|
|
||||||
'primary_key': False,
|
|
||||||
'unique': False,
|
|
||||||
'index': False,
|
|
||||||
'check': False,
|
|
||||||
'foreign_key': \
|
|
||||||
(ref_table, ref_column) if ref_column else None
|
|
||||||
}
|
|
||||||
constraints[constraint]['columns'].add(column)
|
|
||||||
# Now get the constraint types
|
|
||||||
type_query = """
|
|
||||||
SELECT c.constraint_name, c.constraint_type
|
|
||||||
FROM information_schema.table_constraints AS c
|
|
||||||
WHERE
|
|
||||||
c.table_schema = %s AND
|
|
||||||
c.table_name = %s
|
|
||||||
"""
|
|
||||||
cursor.execute(type_query, [self.connection.settings_dict['NAME'],
|
|
||||||
table_name])
|
|
||||||
for constraint, kind in cursor.fetchall():
|
|
||||||
if kind.lower() == "primary key":
|
|
||||||
constraints[constraint]['primary_key'] = True
|
|
||||||
constraints[constraint]['unique'] = True
|
|
||||||
elif kind.lower() == "unique":
|
|
||||||
constraints[constraint]['unique'] = True
|
|
||||||
# Now add in the indexes
|
|
||||||
cursor.execute("SHOW INDEX FROM %s" % self.connection.ops.quote_name(
|
|
||||||
table_name))
|
|
||||||
for table, non_unique, index, colseq, column in [x[:5] for x in
|
|
||||||
cursor.fetchall()]:
|
|
||||||
if index not in constraints:
|
|
||||||
constraints[index] = {
|
|
||||||
'columns': OrderedSet(),
|
|
||||||
'primary_key': False,
|
|
||||||
'unique': False,
|
|
||||||
'index': True,
|
|
||||||
'check': False,
|
|
||||||
'foreign_key': None,
|
|
||||||
}
|
|
||||||
constraints[index]['index'] = True
|
|
||||||
constraints[index]['columns'].add(column)
|
|
||||||
# Convert the sorted sets to lists
|
|
||||||
for constraint in constraints.values():
|
|
||||||
constraint['columns'] = list(constraint['columns'])
|
|
||||||
return constraints
|
|
@ -1,240 +0,0 @@
|
|||||||
# MySQL Connector/Python - MySQL driver written in Python.
|
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
import django
|
|
||||||
from django.conf import settings
|
|
||||||
from django.db.backends.base.operations import BaseDatabaseOperations
|
|
||||||
from django.utils import six, timezone
|
|
||||||
from django.utils.encoding import force_text
|
|
||||||
|
|
||||||
try:
|
|
||||||
from _mysql_connector import datetime_to_mysql, time_to_mysql
|
|
||||||
except ImportError:
|
|
||||||
HAVE_CEXT = False
|
|
||||||
else:
|
|
||||||
HAVE_CEXT = True
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseOperations(BaseDatabaseOperations):
|
|
||||||
compiler_module = "mysql.connector.django.compiler"
|
|
||||||
|
|
||||||
# MySQL stores positive fields as UNSIGNED ints.
|
|
||||||
integer_field_ranges = dict(BaseDatabaseOperations.integer_field_ranges,
|
|
||||||
PositiveSmallIntegerField=(0, 4294967295),
|
|
||||||
PositiveIntegerField=(
|
|
||||||
0, 18446744073709551615),)
|
|
||||||
|
|
||||||
def date_extract_sql(self, lookup_type, field_name):
|
|
||||||
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
|
||||||
if lookup_type == 'week_day':
|
|
||||||
# DAYOFWEEK() returns an integer, 1-7, Sunday=1.
|
|
||||||
# Note: WEEKDAY() returns 0-6, Monday=0.
|
|
||||||
return "DAYOFWEEK({0})".format(field_name)
|
|
||||||
else:
|
|
||||||
return "EXTRACT({0} FROM {1})".format(
|
|
||||||
lookup_type.upper(), field_name)
|
|
||||||
|
|
||||||
def date_trunc_sql(self, lookup_type, field_name):
|
|
||||||
"""Returns SQL simulating DATE_TRUNC
|
|
||||||
|
|
||||||
This function uses MySQL functions DATE_FORMAT and CAST to
|
|
||||||
simulate DATE_TRUNC.
|
|
||||||
|
|
||||||
The field_name is returned when lookup_type is not supported.
|
|
||||||
"""
|
|
||||||
fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
|
|
||||||
format = ('%Y-', '%m', '-%d', ' %H:', '%i', ':%S')
|
|
||||||
format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
|
|
||||||
try:
|
|
||||||
i = fields.index(lookup_type) + 1
|
|
||||||
except ValueError:
|
|
||||||
# Wrong lookup type, just return the value from MySQL as-is
|
|
||||||
sql = field_name
|
|
||||||
else:
|
|
||||||
format_str = ''.join([f for f in format[:i]] +
|
|
||||||
[f for f in format_def[i:]])
|
|
||||||
sql = "CAST(DATE_FORMAT({0}, '{1}') AS DATETIME)".format(
|
|
||||||
field_name, format_str)
|
|
||||||
return sql
|
|
||||||
|
|
||||||
def datetime_extract_sql(self, lookup_type, field_name, tzname):
|
|
||||||
if settings.USE_TZ:
|
|
||||||
field_name = "CONVERT_TZ({0}, 'UTC', %s)".format(field_name)
|
|
||||||
params = [tzname]
|
|
||||||
else:
|
|
||||||
params = []
|
|
||||||
|
|
||||||
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
|
||||||
if lookup_type == 'week_day':
|
|
||||||
# DAYOFWEEK() returns an integer, 1-7, Sunday=1.
|
|
||||||
# Note: WEEKDAY() returns 0-6, Monday=0.
|
|
||||||
sql = "DAYOFWEEK({0})".format(field_name)
|
|
||||||
else:
|
|
||||||
sql = "EXTRACT({0} FROM {1})".format(lookup_type.upper(),
|
|
||||||
field_name)
|
|
||||||
return sql, params
|
|
||||||
|
|
||||||
def datetime_trunc_sql(self, lookup_type, field_name, tzname):
|
|
||||||
if settings.USE_TZ:
|
|
||||||
field_name = "CONVERT_TZ({0}, 'UTC', %s)".format(field_name)
|
|
||||||
params = [tzname]
|
|
||||||
else:
|
|
||||||
params = []
|
|
||||||
fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
|
|
||||||
format_ = ('%Y-', '%m', '-%d', ' %H:', '%i', ':%S')
|
|
||||||
format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
|
|
||||||
try:
|
|
||||||
i = fields.index(lookup_type) + 1
|
|
||||||
except ValueError:
|
|
||||||
sql = field_name
|
|
||||||
else:
|
|
||||||
format_str = ''.join([f for f in format_[:i]] +
|
|
||||||
[f for f in format_def[i:]])
|
|
||||||
sql = "CAST(DATE_FORMAT({0}, '{1}') AS DATETIME)".format(
|
|
||||||
field_name, format_str)
|
|
||||||
return sql, params
|
|
||||||
|
|
||||||
def date_interval_sql(self, timedelta):
|
|
||||||
"""Returns SQL for calculating date/time intervals
|
|
||||||
"""
|
|
||||||
return "INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND" % (
|
|
||||||
timedelta.days, timedelta.seconds, timedelta.microseconds), []
|
|
||||||
|
|
||||||
def format_for_duration_arithmetic(self, sql):
|
|
||||||
if self.connection.features.supports_microsecond_precision:
|
|
||||||
return 'INTERVAL %s MICROSECOND' % sql
|
|
||||||
else:
|
|
||||||
return 'INTERVAL FLOOR(%s / 1000000) SECOND' % sql
|
|
||||||
|
|
||||||
def drop_foreignkey_sql(self):
|
|
||||||
return "DROP FOREIGN KEY"
|
|
||||||
|
|
||||||
def force_no_ordering(self):
|
|
||||||
"""
|
|
||||||
"ORDER BY NULL" prevents MySQL from implicitly ordering by grouped
|
|
||||||
columns. If no ordering would otherwise be applied, we don't want any
|
|
||||||
implicit sorting going on.
|
|
||||||
"""
|
|
||||||
return [(None, ("NULL", [], False))]
|
|
||||||
|
|
||||||
def fulltext_search_sql(self, field_name):
|
|
||||||
return 'MATCH ({0}) AGAINST (%s IN BOOLEAN MODE)'.format(field_name)
|
|
||||||
|
|
||||||
def last_executed_query(self, cursor, sql, params):
|
|
||||||
return force_text(cursor.statement, errors='replace')
|
|
||||||
|
|
||||||
def no_limit_value(self):
|
|
||||||
# 2**64 - 1, as recommended by the MySQL documentation
|
|
||||||
return 18446744073709551615
|
|
||||||
|
|
||||||
def quote_name(self, name):
|
|
||||||
if name.startswith("`") and name.endswith("`"):
|
|
||||||
return name # Quoting once is enough.
|
|
||||||
return "`{0}`".format(name)
|
|
||||||
|
|
||||||
def random_function_sql(self):
|
|
||||||
return 'RAND()'
|
|
||||||
|
|
||||||
def sql_flush(self, style, tables, sequences, allow_cascade=False):
|
|
||||||
if tables:
|
|
||||||
sql = ['SET FOREIGN_KEY_CHECKS = 0;']
|
|
||||||
for table in tables:
|
|
||||||
sql.append('{keyword} {table};'.format(
|
|
||||||
keyword=style.SQL_KEYWORD('TRUNCATE'),
|
|
||||||
table=style.SQL_FIELD(self.quote_name(table))))
|
|
||||||
sql.append('SET FOREIGN_KEY_CHECKS = 1;')
|
|
||||||
sql.extend(self.sequence_reset_by_name_sql(style, sequences))
|
|
||||||
return sql
|
|
||||||
else:
|
|
||||||
return []
|
|
||||||
|
|
||||||
def validate_autopk_value(self, value):
|
|
||||||
# MySQLism: zero in AUTO_INCREMENT field does not work. Refs #17653.
|
|
||||||
if value == 0:
|
|
||||||
raise ValueError('The database backend does not accept 0 as a '
|
|
||||||
'value for AutoField.')
|
|
||||||
return value
|
|
||||||
|
|
||||||
def adapt_datetimefield_value(self, value):
|
|
||||||
return self.value_to_db_datetime(value)
|
|
||||||
|
|
||||||
def value_to_db_datetime(self, value):
|
|
||||||
if value is None:
|
|
||||||
return None
|
|
||||||
# MySQL doesn't support tz-aware times
|
|
||||||
if timezone.is_aware(value):
|
|
||||||
if settings.USE_TZ:
|
|
||||||
value = value.astimezone(timezone.utc).replace(tzinfo=None)
|
|
||||||
else:
|
|
||||||
raise ValueError(
|
|
||||||
"MySQL backend does not support timezone-aware times."
|
|
||||||
)
|
|
||||||
if not self.connection.features.supports_microsecond_precision:
|
|
||||||
value = value.replace(microsecond=0)
|
|
||||||
if not self.connection.use_pure:
|
|
||||||
return datetime_to_mysql(value)
|
|
||||||
return self.connection.converter.to_mysql(value)
|
|
||||||
|
|
||||||
def adapt_timefield_value(self, value):
|
|
||||||
return self.value_to_db_time(value)
|
|
||||||
|
|
||||||
def value_to_db_time(self, value):
|
|
||||||
if value is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# MySQL doesn't support tz-aware times
|
|
||||||
if timezone.is_aware(value):
|
|
||||||
raise ValueError("MySQL backend does not support timezone-aware "
|
|
||||||
"times.")
|
|
||||||
|
|
||||||
if not self.connection.use_pure:
|
|
||||||
return time_to_mysql(value)
|
|
||||||
return self.connection.converter.to_mysql(value)
|
|
||||||
|
|
||||||
def max_name_length(self):
|
|
||||||
return 64
|
|
||||||
|
|
||||||
def bulk_insert_sql(self, fields, placeholder_rows):
|
|
||||||
placeholder_rows_sql = (", ".join(row) for row in placeholder_rows)
|
|
||||||
values_sql = ", ".join("({0})".format(sql) for sql in placeholder_rows_sql)
|
|
||||||
return "VALUES " + values_sql
|
|
||||||
|
|
||||||
def combine_expression(self, connector, sub_expressions):
|
|
||||||
"""
|
|
||||||
MySQL requires special cases for ^ operators in query expressions
|
|
||||||
"""
|
|
||||||
if connector == '^':
|
|
||||||
return 'POW(%s)' % ','.join(sub_expressions)
|
|
||||||
return super(DatabaseOperations, self).combine_expression(
|
|
||||||
connector, sub_expressions)
|
|
||||||
|
|
||||||
def get_db_converters(self, expression):
|
|
||||||
converters = super(DatabaseOperations, self).get_db_converters(
|
|
||||||
expression)
|
|
||||||
internal_type = expression.output_field.get_internal_type()
|
|
||||||
if internal_type in ['BooleanField', 'NullBooleanField']:
|
|
||||||
converters.append(self.convert_booleanfield_value)
|
|
||||||
if internal_type == 'UUIDField':
|
|
||||||
converters.append(self.convert_uuidfield_value)
|
|
||||||
if internal_type == 'TextField':
|
|
||||||
converters.append(self.convert_textfield_value)
|
|
||||||
return converters
|
|
||||||
|
|
||||||
def convert_booleanfield_value(self, value,
|
|
||||||
expression, connection, context):
|
|
||||||
if value in (0, 1):
|
|
||||||
value = bool(value)
|
|
||||||
return value
|
|
||||||
|
|
||||||
def convert_uuidfield_value(self, value, expression, connection, context):
|
|
||||||
if value is not None:
|
|
||||||
value = uuid.UUID(value)
|
|
||||||
return value
|
|
||||||
|
|
||||||
def convert_textfield_value(self, value, expression, connection, context):
|
|
||||||
if value is not None:
|
|
||||||
value = force_text(value)
|
|
||||||
return value
|
|
@ -1,79 +0,0 @@
|
|||||||
# MySQL Connector/Python - MySQL driver written in Python.
|
|
||||||
|
|
||||||
import django
|
|
||||||
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
|
||||||
from django.db.models import NOT_PROVIDED
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|
||||||
|
|
||||||
sql_rename_table = "RENAME TABLE %(old_table)s TO %(new_table)s"
|
|
||||||
|
|
||||||
sql_alter_column_null = "MODIFY %(column)s %(type)s NULL"
|
|
||||||
sql_alter_column_not_null = "MODIFY %(column)s %(type)s NOT NULL"
|
|
||||||
sql_alter_column_type = "MODIFY %(column)s %(type)s"
|
|
||||||
sql_rename_column = "ALTER TABLE %(table)s CHANGE %(old_column)s " \
|
|
||||||
"%(new_column)s %(type)s"
|
|
||||||
|
|
||||||
sql_delete_unique = "ALTER TABLE %(table)s DROP INDEX %(name)s"
|
|
||||||
|
|
||||||
sql_create_fk = "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s FOREIGN " \
|
|
||||||
"KEY (%(column)s) REFERENCES %(to_table)s (%(to_column)s)"
|
|
||||||
sql_delete_fk = "ALTER TABLE %(table)s DROP FOREIGN KEY %(name)s"
|
|
||||||
|
|
||||||
sql_delete_index = "DROP INDEX %(name)s ON %(table)s"
|
|
||||||
|
|
||||||
alter_string_set_null = 'MODIFY %(column)s %(type)s NULL;'
|
|
||||||
alter_string_drop_null = 'MODIFY %(column)s %(type)s NOT NULL;'
|
|
||||||
|
|
||||||
sql_create_pk = "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s " \
|
|
||||||
"PRIMARY KEY (%(columns)s)"
|
|
||||||
sql_delete_pk = "ALTER TABLE %(table)s DROP PRIMARY KEY"
|
|
||||||
|
|
||||||
def quote_value(self, value):
|
|
||||||
# Inner import to allow module to fail to load gracefully
|
|
||||||
from mysql.connector.conversion import MySQLConverter
|
|
||||||
return MySQLConverter.quote(MySQLConverter.escape(value))
|
|
||||||
|
|
||||||
def skip_default(self, field):
|
|
||||||
"""
|
|
||||||
MySQL doesn't accept default values for longtext and longblob
|
|
||||||
and implicitly treats these columns as nullable.
|
|
||||||
"""
|
|
||||||
return field.db_type(self.connection) in ('longtext', 'longblob')
|
|
||||||
|
|
||||||
def add_field(self, model, field):
|
|
||||||
super(DatabaseSchemaEditor, self).add_field(model, field)
|
|
||||||
|
|
||||||
# Simulate the effect of a one-off default.
|
|
||||||
if (self.skip_default(field)
|
|
||||||
and field.default not in (None, NOT_PROVIDED)):
|
|
||||||
effective_default = self.effective_default(field)
|
|
||||||
self.execute('UPDATE %(table)s SET %(column)s = %%s' % {
|
|
||||||
'table': self.quote_name(model._meta.db_table),
|
|
||||||
'column': self.quote_name(field.column),
|
|
||||||
}, [effective_default])
|
|
||||||
|
|
||||||
def _model_indexes_sql(self, model):
|
|
||||||
storage = self.connection.introspection.get_storage_engine(
|
|
||||||
self.connection.cursor(), model._meta.db_table
|
|
||||||
)
|
|
||||||
if storage == "InnoDB":
|
|
||||||
for field in model._meta.local_fields:
|
|
||||||
if (field.db_index and not field.unique
|
|
||||||
and field.get_internal_type() == "ForeignKey"):
|
|
||||||
# Temporary setting db_index to False (in memory) to
|
|
||||||
# disable index creation for FKs (index automatically
|
|
||||||
# created by MySQL)
|
|
||||||
field.db_index = False
|
|
||||||
return super(DatabaseSchemaEditor, self)._model_indexes_sql(model)
|
|
||||||
|
|
||||||
def _alter_column_type_sql(self, table, old_field, new_field, new_type):
|
|
||||||
# Keep null property of old field, if it has changed, it will be
|
|
||||||
# handled separately
|
|
||||||
if old_field.null:
|
|
||||||
new_type += " NULL"
|
|
||||||
else:
|
|
||||||
new_type += " NOT NULL"
|
|
||||||
return super(DatabaseSchemaEditor, self)._alter_column_type_sql(
|
|
||||||
table, old_field, new_field, new_type)
|
|
@ -1,40 +0,0 @@
|
|||||||
# MySQL Connector/Python - MySQL driver written in Python.
|
|
||||||
|
|
||||||
import django
|
|
||||||
|
|
||||||
from django.db.backends.base.validation import BaseDatabaseValidation
|
|
||||||
from django.core import checks
|
|
||||||
from django.db import connection
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseValidation(BaseDatabaseValidation):
|
|
||||||
def check_field(self, field, **kwargs):
|
|
||||||
"""
|
|
||||||
MySQL has the following field length restriction:
|
|
||||||
No character (varchar) fields can have a length exceeding 255
|
|
||||||
characters if they have a unique index on them.
|
|
||||||
"""
|
|
||||||
errors = super(DatabaseValidation, self).check_field(field,
|
|
||||||
**kwargs)
|
|
||||||
|
|
||||||
# Ignore any related fields.
|
|
||||||
if getattr(field, 'rel', None) is None:
|
|
||||||
field_type = field.db_type(connection)
|
|
||||||
|
|
||||||
if field_type is None:
|
|
||||||
return errors
|
|
||||||
|
|
||||||
if (field_type.startswith('varchar') # Look for CharFields...
|
|
||||||
and field.unique # ... that are unique
|
|
||||||
and (field.max_length is None or
|
|
||||||
int(field.max_length) > 255)):
|
|
||||||
errors.append(
|
|
||||||
checks.Error(
|
|
||||||
('MySQL does not allow unique CharFields to have a '
|
|
||||||
'max_length > 255.'),
|
|
||||||
hint=None,
|
|
||||||
obj=field,
|
|
||||||
id='mysql.E001',
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return errors
|
|
File diff suppressed because it is too large
Load Diff
@ -1,307 +0,0 @@
|
|||||||
# Copyright (c) 2009, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Python exceptions
|
|
||||||
"""
|
|
||||||
|
|
||||||
from . import utils
|
|
||||||
from .locales import get_client_error
|
|
||||||
from .catch23 import PY2
|
|
||||||
|
|
||||||
# _CUSTOM_ERROR_EXCEPTIONS holds custom exceptions and is ued by the
|
|
||||||
# function custom_error_exception. _ERROR_EXCEPTIONS (at bottom of module)
|
|
||||||
# is similar, but hardcoded exceptions.
|
|
||||||
_CUSTOM_ERROR_EXCEPTIONS = {}
|
|
||||||
|
|
||||||
|
|
||||||
def custom_error_exception(error=None, exception=None):
|
|
||||||
"""Define custom exceptions for MySQL server errors
|
|
||||||
|
|
||||||
This function defines custom exceptions for MySQL server errors and
|
|
||||||
returns the current set customizations.
|
|
||||||
|
|
||||||
If error is a MySQL Server error number, then you have to pass also the
|
|
||||||
exception class.
|
|
||||||
|
|
||||||
The error argument can also be a dictionary in which case the key is
|
|
||||||
the server error number, and value the exception to be raised.
|
|
||||||
|
|
||||||
If none of the arguments are given, then custom_error_exception() will
|
|
||||||
simply return the current set customizations.
|
|
||||||
|
|
||||||
To reset the customizations, simply supply an empty dictionary.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
import mysql.connector
|
|
||||||
from mysql.connector import errorcode
|
|
||||||
|
|
||||||
# Server error 1028 should raise a DatabaseError
|
|
||||||
mysql.connector.custom_error_exception(
|
|
||||||
1028, mysql.connector.DatabaseError)
|
|
||||||
|
|
||||||
# Or using a dictionary:
|
|
||||||
mysql.connector.custom_error_exception({
|
|
||||||
1028: mysql.connector.DatabaseError,
|
|
||||||
1029: mysql.connector.OperationalError,
|
|
||||||
})
|
|
||||||
|
|
||||||
# Reset
|
|
||||||
mysql.connector.custom_error_exception({})
|
|
||||||
|
|
||||||
Returns a dictionary.
|
|
||||||
"""
|
|
||||||
global _CUSTOM_ERROR_EXCEPTIONS # pylint: disable=W0603
|
|
||||||
|
|
||||||
if isinstance(error, dict) and not error:
|
|
||||||
_CUSTOM_ERROR_EXCEPTIONS = {}
|
|
||||||
return _CUSTOM_ERROR_EXCEPTIONS
|
|
||||||
|
|
||||||
if not error and not exception:
|
|
||||||
return _CUSTOM_ERROR_EXCEPTIONS
|
|
||||||
|
|
||||||
if not isinstance(error, (int, dict)):
|
|
||||||
raise ValueError(
|
|
||||||
"The error argument should be either an integer or dictionary")
|
|
||||||
|
|
||||||
if isinstance(error, int):
|
|
||||||
error = {error: exception}
|
|
||||||
|
|
||||||
for errno, _exception in error.items():
|
|
||||||
if not isinstance(errno, int):
|
|
||||||
raise ValueError("error number should be an integer")
|
|
||||||
try:
|
|
||||||
if not issubclass(_exception, Exception):
|
|
||||||
raise TypeError
|
|
||||||
except TypeError:
|
|
||||||
raise ValueError("exception should be subclass of Exception")
|
|
||||||
_CUSTOM_ERROR_EXCEPTIONS[errno] = _exception
|
|
||||||
|
|
||||||
return _CUSTOM_ERROR_EXCEPTIONS
|
|
||||||
|
|
||||||
def get_mysql_exception(errno, msg=None, sqlstate=None):
|
|
||||||
"""Get the exception matching the MySQL error
|
|
||||||
|
|
||||||
This function will return an exception based on the SQLState. The given
|
|
||||||
message will be passed on in the returned exception.
|
|
||||||
|
|
||||||
The exception returned can be customized using the
|
|
||||||
mysql.connector.custom_error_exception() function.
|
|
||||||
|
|
||||||
Returns an Exception
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return _CUSTOM_ERROR_EXCEPTIONS[errno](
|
|
||||||
msg=msg, errno=errno, sqlstate=sqlstate)
|
|
||||||
except KeyError:
|
|
||||||
# Error was not mapped to particular exception
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
return _ERROR_EXCEPTIONS[errno](
|
|
||||||
msg=msg, errno=errno, sqlstate=sqlstate)
|
|
||||||
except KeyError:
|
|
||||||
# Error was not mapped to particular exception
|
|
||||||
pass
|
|
||||||
|
|
||||||
if not sqlstate:
|
|
||||||
return DatabaseError(msg=msg, errno=errno)
|
|
||||||
|
|
||||||
try:
|
|
||||||
return _SQLSTATE_CLASS_EXCEPTION[sqlstate[0:2]](
|
|
||||||
msg=msg, errno=errno, sqlstate=sqlstate)
|
|
||||||
except KeyError:
|
|
||||||
# Return default InterfaceError
|
|
||||||
return DatabaseError(msg=msg, errno=errno, sqlstate=sqlstate)
|
|
||||||
|
|
||||||
def get_exception(packet):
|
|
||||||
"""Returns an exception object based on the MySQL error
|
|
||||||
|
|
||||||
Returns an exception object based on the MySQL error in the given
|
|
||||||
packet.
|
|
||||||
|
|
||||||
Returns an Error-Object.
|
|
||||||
"""
|
|
||||||
errno = errmsg = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
if packet[4] != 255:
|
|
||||||
raise ValueError("Packet is not an error packet")
|
|
||||||
except IndexError as err:
|
|
||||||
return InterfaceError("Failed getting Error information (%r)" % err)
|
|
||||||
|
|
||||||
sqlstate = None
|
|
||||||
try:
|
|
||||||
packet = packet[5:]
|
|
||||||
(packet, errno) = utils.read_int(packet, 2)
|
|
||||||
if packet[0] != 35:
|
|
||||||
# Error without SQLState
|
|
||||||
if isinstance(packet, (bytes, bytearray)):
|
|
||||||
errmsg = packet.decode('utf8')
|
|
||||||
else:
|
|
||||||
errmsg = packet
|
|
||||||
else:
|
|
||||||
(packet, sqlstate) = utils.read_bytes(packet[1:], 5)
|
|
||||||
sqlstate = sqlstate.decode('utf8')
|
|
||||||
errmsg = packet.decode('utf8')
|
|
||||||
except Exception as err: # pylint: disable=W0703
|
|
||||||
return InterfaceError("Failed getting Error information (%r)" % err)
|
|
||||||
else:
|
|
||||||
return get_mysql_exception(errno, errmsg, sqlstate)
|
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception):
|
|
||||||
"""Exception that is base class for all other error exceptions"""
|
|
||||||
def __init__(self, msg=None, errno=None, values=None, sqlstate=None):
|
|
||||||
super(Error, self).__init__()
|
|
||||||
self.msg = msg
|
|
||||||
self._full_msg = self.msg
|
|
||||||
self.errno = errno or -1
|
|
||||||
self.sqlstate = sqlstate
|
|
||||||
|
|
||||||
if not self.msg and (2000 <= self.errno < 3000):
|
|
||||||
self.msg = get_client_error(self.errno)
|
|
||||||
if values is not None:
|
|
||||||
try:
|
|
||||||
self.msg = self.msg % values
|
|
||||||
except TypeError as err:
|
|
||||||
self.msg = "{0} (Warning: {1})".format(self.msg, str(err))
|
|
||||||
elif not self.msg:
|
|
||||||
self._full_msg = self.msg = 'Unknown error'
|
|
||||||
|
|
||||||
if self.msg and self.errno != -1:
|
|
||||||
fields = {
|
|
||||||
'errno': self.errno,
|
|
||||||
'msg': self.msg.encode('utf8') if PY2 else self.msg
|
|
||||||
}
|
|
||||||
if self.sqlstate:
|
|
||||||
fmt = '{errno} ({state}): {msg}'
|
|
||||||
fields['state'] = self.sqlstate
|
|
||||||
else:
|
|
||||||
fmt = '{errno}: {msg}'
|
|
||||||
self._full_msg = fmt.format(**fields)
|
|
||||||
|
|
||||||
self.args = (self.errno, self._full_msg, self.sqlstate)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._full_msg
|
|
||||||
|
|
||||||
|
|
||||||
class Warning(Exception): # pylint: disable=W0622
|
|
||||||
"""Exception for important warnings"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InterfaceError(Error):
|
|
||||||
"""Exception for errors related to the interface"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseError(Error):
|
|
||||||
"""Exception for errors related to the database"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InternalError(DatabaseError):
|
|
||||||
"""Exception for errors internal database errors"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class OperationalError(DatabaseError):
|
|
||||||
"""Exception for errors related to the database's operation"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ProgrammingError(DatabaseError):
|
|
||||||
"""Exception for errors programming errors"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class IntegrityError(DatabaseError):
|
|
||||||
"""Exception for errors regarding relational integrity"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DataError(DatabaseError):
|
|
||||||
"""Exception for errors reporting problems with processed data"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class NotSupportedError(DatabaseError):
|
|
||||||
"""Exception for errors when an unsupported database feature was used"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class PoolError(Error):
|
|
||||||
"""Exception for errors relating to connection pooling"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
_SQLSTATE_CLASS_EXCEPTION = {
|
|
||||||
'02': DataError, # no data
|
|
||||||
'07': DatabaseError, # dynamic SQL error
|
|
||||||
'08': OperationalError, # connection exception
|
|
||||||
'0A': NotSupportedError, # feature not supported
|
|
||||||
'21': DataError, # cardinality violation
|
|
||||||
'22': DataError, # data exception
|
|
||||||
'23': IntegrityError, # integrity constraint violation
|
|
||||||
'24': ProgrammingError, # invalid cursor state
|
|
||||||
'25': ProgrammingError, # invalid transaction state
|
|
||||||
'26': ProgrammingError, # invalid SQL statement name
|
|
||||||
'27': ProgrammingError, # triggered data change violation
|
|
||||||
'28': ProgrammingError, # invalid authorization specification
|
|
||||||
'2A': ProgrammingError, # direct SQL syntax error or access rule violation
|
|
||||||
'2B': DatabaseError, # dependent privilege descriptors still exist
|
|
||||||
'2C': ProgrammingError, # invalid character set name
|
|
||||||
'2D': DatabaseError, # invalid transaction termination
|
|
||||||
'2E': DatabaseError, # invalid connection name
|
|
||||||
'33': DatabaseError, # invalid SQL descriptor name
|
|
||||||
'34': ProgrammingError, # invalid cursor name
|
|
||||||
'35': ProgrammingError, # invalid condition number
|
|
||||||
'37': ProgrammingError, # dynamic SQL syntax error or access rule violation
|
|
||||||
'3C': ProgrammingError, # ambiguous cursor name
|
|
||||||
'3D': ProgrammingError, # invalid catalog name
|
|
||||||
'3F': ProgrammingError, # invalid schema name
|
|
||||||
'40': InternalError, # transaction rollback
|
|
||||||
'42': ProgrammingError, # syntax error or access rule violation
|
|
||||||
'44': InternalError, # with check option violation
|
|
||||||
'HZ': OperationalError, # remote database access
|
|
||||||
'XA': IntegrityError,
|
|
||||||
'0K': OperationalError,
|
|
||||||
'HY': DatabaseError, # default when no SQLState provided by MySQL server
|
|
||||||
}
|
|
||||||
|
|
||||||
_ERROR_EXCEPTIONS = {
|
|
||||||
1243: ProgrammingError,
|
|
||||||
1210: ProgrammingError,
|
|
||||||
2002: InterfaceError,
|
|
||||||
2013: OperationalError,
|
|
||||||
2049: NotSupportedError,
|
|
||||||
2055: OperationalError,
|
|
||||||
2061: InterfaceError,
|
|
||||||
2026: InterfaceError,
|
|
||||||
}
|
|
@ -1,75 +0,0 @@
|
|||||||
# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Translations
|
|
||||||
"""
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
'get_client_error'
|
|
||||||
]
|
|
||||||
|
|
||||||
from .. import errorcode
|
|
||||||
|
|
||||||
def get_client_error(error, language='eng'):
|
|
||||||
"""Lookup client error
|
|
||||||
|
|
||||||
This function will lookup the client error message based on the given
|
|
||||||
error and return the error message. If the error was not found,
|
|
||||||
None will be returned.
|
|
||||||
|
|
||||||
Error can be either an integer or a string. For example:
|
|
||||||
error: 2000
|
|
||||||
error: CR_UNKNOWN_ERROR
|
|
||||||
|
|
||||||
The language attribute can be used to retrieve a localized message, when
|
|
||||||
available.
|
|
||||||
|
|
||||||
Returns a string or None.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
tmp = __import__('mysql.connector.locales.{0}'.format(language),
|
|
||||||
globals(), locals(), ['client_error'])
|
|
||||||
except ImportError:
|
|
||||||
raise ImportError("No localization support for language '{0}'".format(
|
|
||||||
language))
|
|
||||||
client_error = tmp.client_error
|
|
||||||
|
|
||||||
if isinstance(error, int):
|
|
||||||
errno = error
|
|
||||||
for key, value in errorcode.__dict__.items():
|
|
||||||
if value == errno:
|
|
||||||
error = key
|
|
||||||
break
|
|
||||||
|
|
||||||
if isinstance(error, (str)):
|
|
||||||
try:
|
|
||||||
return getattr(client_error, error)
|
|
||||||
except AttributeError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
raise ValueError("error argument needs to be either an integer or string")
|
|
@ -1,30 +0,0 @@
|
|||||||
# Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""English Content
|
|
||||||
"""
|
|
@ -1,102 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
# This file was auto-generated.
|
|
||||||
_GENERATED_ON = '2018-03-16'
|
|
||||||
_MYSQL_VERSION = (8, 0, 11)
|
|
||||||
|
|
||||||
# Start MySQL Error messages
|
|
||||||
CR_UNKNOWN_ERROR = u"Unknown MySQL error"
|
|
||||||
CR_SOCKET_CREATE_ERROR = u"Can't create UNIX socket (%s)"
|
|
||||||
CR_CONNECTION_ERROR = u"Can't connect to local MySQL server through socket '%-.100s' (%s)"
|
|
||||||
CR_CONN_HOST_ERROR = u"Can't connect to MySQL server on '%-.100s' (%s)"
|
|
||||||
CR_IPSOCK_ERROR = u"Can't create TCP/IP socket (%s)"
|
|
||||||
CR_UNKNOWN_HOST = u"Unknown MySQL server host '%-.100s' (%s)"
|
|
||||||
CR_SERVER_GONE_ERROR = u"MySQL server has gone away"
|
|
||||||
CR_VERSION_ERROR = u"Protocol mismatch; server version = %s, client version = %s"
|
|
||||||
CR_OUT_OF_MEMORY = u"MySQL client ran out of memory"
|
|
||||||
CR_WRONG_HOST_INFO = u"Wrong host info"
|
|
||||||
CR_LOCALHOST_CONNECTION = u"Localhost via UNIX socket"
|
|
||||||
CR_TCP_CONNECTION = u"%-.100s via TCP/IP"
|
|
||||||
CR_SERVER_HANDSHAKE_ERR = u"Error in server handshake"
|
|
||||||
CR_SERVER_LOST = u"Lost connection to MySQL server during query"
|
|
||||||
CR_COMMANDS_OUT_OF_SYNC = u"Commands out of sync; you can't run this command now"
|
|
||||||
CR_NAMEDPIPE_CONNECTION = u"Named pipe: %-.32s"
|
|
||||||
CR_NAMEDPIPEWAIT_ERROR = u"Can't wait for named pipe to host: %-.64s pipe: %-.32s (%s)"
|
|
||||||
CR_NAMEDPIPEOPEN_ERROR = u"Can't open named pipe to host: %-.64s pipe: %-.32s (%s)"
|
|
||||||
CR_NAMEDPIPESETSTATE_ERROR = u"Can't set state of named pipe to host: %-.64s pipe: %-.32s (%s)"
|
|
||||||
CR_CANT_READ_CHARSET = u"Can't initialize character set %-.32s (path: %-.100s)"
|
|
||||||
CR_NET_PACKET_TOO_LARGE = u"Got packet bigger than 'max_allowed_packet' bytes"
|
|
||||||
CR_EMBEDDED_CONNECTION = u"Embedded server"
|
|
||||||
CR_PROBE_SLAVE_STATUS = u"Error on SHOW SLAVE STATUS:"
|
|
||||||
CR_PROBE_SLAVE_HOSTS = u"Error on SHOW SLAVE HOSTS:"
|
|
||||||
CR_PROBE_SLAVE_CONNECT = u"Error connecting to slave:"
|
|
||||||
CR_PROBE_MASTER_CONNECT = u"Error connecting to master:"
|
|
||||||
CR_SSL_CONNECTION_ERROR = u"SSL connection error: %-.100s"
|
|
||||||
CR_MALFORMED_PACKET = u"Malformed packet"
|
|
||||||
CR_WRONG_LICENSE = u"This client library is licensed only for use with MySQL servers having '%s' license"
|
|
||||||
CR_NULL_POINTER = u"Invalid use of null pointer"
|
|
||||||
CR_NO_PREPARE_STMT = u"Statement not prepared"
|
|
||||||
CR_PARAMS_NOT_BOUND = u"No data supplied for parameters in prepared statement"
|
|
||||||
CR_DATA_TRUNCATED = u"Data truncated"
|
|
||||||
CR_NO_PARAMETERS_EXISTS = u"No parameters exist in the statement"
|
|
||||||
CR_INVALID_PARAMETER_NO = u"Invalid parameter number"
|
|
||||||
CR_INVALID_BUFFER_USE = u"Can't send long data for non-string/non-binary data types (parameter: %s)"
|
|
||||||
CR_UNSUPPORTED_PARAM_TYPE = u"Using unsupported buffer type: %s (parameter: %s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECTION = u"Shared memory: %-.100s"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR = u"Can't open shared memory; client could not create request event (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR = u"Can't open shared memory; no answer event received from server (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR = u"Can't open shared memory; server could not allocate file mapping (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_MAP_ERROR = u"Can't open shared memory; server could not get pointer to file mapping (%s)"
|
|
||||||
CR_SHARED_MEMORY_FILE_MAP_ERROR = u"Can't open shared memory; client could not allocate file mapping (%s)"
|
|
||||||
CR_SHARED_MEMORY_MAP_ERROR = u"Can't open shared memory; client could not get pointer to file mapping (%s)"
|
|
||||||
CR_SHARED_MEMORY_EVENT_ERROR = u"Can't open shared memory; client could not create %s event (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR = u"Can't open shared memory; no answer from server (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_SET_ERROR = u"Can't open shared memory; cannot send request event to server (%s)"
|
|
||||||
CR_CONN_UNKNOW_PROTOCOL = u"Wrong or unknown protocol"
|
|
||||||
CR_INVALID_CONN_HANDLE = u"Invalid connection handle"
|
|
||||||
CR_UNUSED_1 = u"Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)"
|
|
||||||
CR_FETCH_CANCELED = u"Row retrieval was canceled by mysql_stmt_close() call"
|
|
||||||
CR_NO_DATA = u"Attempt to read column without prior row fetch"
|
|
||||||
CR_NO_STMT_METADATA = u"Prepared statement contains no metadata"
|
|
||||||
CR_NO_RESULT_SET = u"Attempt to read a row while there is no result set associated with the statement"
|
|
||||||
CR_NOT_IMPLEMENTED = u"This feature is not implemented yet"
|
|
||||||
CR_SERVER_LOST_EXTENDED = u"Lost connection to MySQL server at '%s', system error: %s"
|
|
||||||
CR_STMT_CLOSED = u"Statement closed indirectly because of a preceding %s() call"
|
|
||||||
CR_NEW_STMT_METADATA = u"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again"
|
|
||||||
CR_ALREADY_CONNECTED = u"This handle is already connected. Use a separate handle for each connection."
|
|
||||||
CR_AUTH_PLUGIN_CANNOT_LOAD = u"Authentication plugin '%s' cannot be loaded: %s"
|
|
||||||
CR_DUPLICATE_CONNECTION_ATTR = u"There is an attribute with the same name already"
|
|
||||||
CR_AUTH_PLUGIN_ERR = u"Authentication plugin '%s' reported error: %s"
|
|
||||||
CR_INSECURE_API_ERR = u"Insecure API function call: '%s' Use instead: '%s'"
|
|
||||||
CR_FILE_NAME_TOO_LONG = u"File name is too long"
|
|
||||||
CR_SSL_FIPS_MODE_ERR = u"Set FIPS mode ON/STRICT failed"
|
|
||||||
# End MySQL Error messages
|
|
||||||
|
|
@ -1,611 +0,0 @@
|
|||||||
# Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Module implementing low-level socket communication with MySQL servers.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from collections import deque
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import struct
|
|
||||||
import sys
|
|
||||||
import zlib
|
|
||||||
|
|
||||||
try:
|
|
||||||
import ssl
|
|
||||||
TLS_VERSIONS = {
|
|
||||||
"TLSv1": ssl.PROTOCOL_TLSv1,
|
|
||||||
"TLSv1.1": ssl.PROTOCOL_TLSv1_1,
|
|
||||||
"TLSv1.2": ssl.PROTOCOL_TLSv1_2}
|
|
||||||
# TLSv1.3 included in PROTOCOL_TLS, but PROTOCOL_TLS is not included on 3.4
|
|
||||||
if hasattr(ssl, "PROTOCOL_TLS"):
|
|
||||||
TLS_VERSIONS["TLSv1.3"] = ssl.PROTOCOL_TLS # pylint: disable=E1101
|
|
||||||
else:
|
|
||||||
TLS_VERSIONS["TLSv1.3"] = ssl.PROTOCOL_SSLv23 # Alias of PROTOCOL_TLS
|
|
||||||
if hasattr(ssl, "HAS_TLSv1_3") and ssl.HAS_TLSv1_3:
|
|
||||||
TLS_V1_3_SUPPORTED = True
|
|
||||||
else:
|
|
||||||
TLS_V1_3_SUPPORTED = False
|
|
||||||
except:
|
|
||||||
# If import fails, we don't have SSL support.
|
|
||||||
TLS_V1_3_SUPPORTED = False
|
|
||||||
pass
|
|
||||||
|
|
||||||
from . import constants, errors
|
|
||||||
from .errors import InterfaceError
|
|
||||||
from .catch23 import PY2, init_bytearray, struct_unpack
|
|
||||||
|
|
||||||
|
|
||||||
def _strioerror(err):
|
|
||||||
"""Reformat the IOError error message
|
|
||||||
|
|
||||||
This function reformats the IOError error message.
|
|
||||||
"""
|
|
||||||
if not err.errno:
|
|
||||||
return str(err)
|
|
||||||
return '{errno} {strerr}'.format(errno=err.errno, strerr=err.strerror)
|
|
||||||
|
|
||||||
|
|
||||||
def _prepare_packets(buf, pktnr):
|
|
||||||
"""Prepare a packet for sending to the MySQL server"""
|
|
||||||
pkts = []
|
|
||||||
pllen = len(buf)
|
|
||||||
maxpktlen = constants.MAX_PACKET_LENGTH
|
|
||||||
while pllen > maxpktlen:
|
|
||||||
pkts.append(b'\xff\xff\xff' + struct.pack('<B', pktnr)
|
|
||||||
+ buf[:maxpktlen])
|
|
||||||
buf = buf[maxpktlen:]
|
|
||||||
pllen = len(buf)
|
|
||||||
pktnr = pktnr + 1
|
|
||||||
pkts.append(struct.pack('<I', pllen)[0:3]
|
|
||||||
+ struct.pack('<B', pktnr) + buf)
|
|
||||||
return pkts
|
|
||||||
|
|
||||||
|
|
||||||
class BaseMySQLSocket(object):
|
|
||||||
"""Base class for MySQL socket communication
|
|
||||||
|
|
||||||
This class should not be used directly but overloaded, changing the
|
|
||||||
at least the open_connection()-method. Examples of subclasses are
|
|
||||||
mysql.connector.network.MySQLTCPSocket
|
|
||||||
mysql.connector.network.MySQLUnixSocket
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.sock = None # holds the socket connection
|
|
||||||
self._connection_timeout = None
|
|
||||||
self._packet_number = -1
|
|
||||||
self._compressed_packet_number = -1
|
|
||||||
self._packet_queue = deque()
|
|
||||||
self.recvsize = 8192
|
|
||||||
|
|
||||||
@property
|
|
||||||
def next_packet_number(self):
|
|
||||||
"""Increments the packet number"""
|
|
||||||
self._packet_number = self._packet_number + 1
|
|
||||||
if self._packet_number > 255:
|
|
||||||
self._packet_number = 0
|
|
||||||
return self._packet_number
|
|
||||||
|
|
||||||
@property
|
|
||||||
def next_compressed_packet_number(self):
|
|
||||||
"""Increments the compressed packet number"""
|
|
||||||
self._compressed_packet_number = self._compressed_packet_number + 1
|
|
||||||
if self._compressed_packet_number > 255:
|
|
||||||
self._compressed_packet_number = 0
|
|
||||||
return self._compressed_packet_number
|
|
||||||
|
|
||||||
def open_connection(self):
|
|
||||||
"""Open the socket"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def get_address(self):
|
|
||||||
"""Get the location of the socket"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def shutdown(self):
|
|
||||||
"""Shut down the socket before closing it"""
|
|
||||||
try:
|
|
||||||
self.sock.shutdown(socket.SHUT_RDWR)
|
|
||||||
self.sock.close()
|
|
||||||
del self._packet_queue
|
|
||||||
except (socket.error, AttributeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def close_connection(self):
|
|
||||||
"""Close the socket"""
|
|
||||||
try:
|
|
||||||
self.sock.close()
|
|
||||||
del self._packet_queue
|
|
||||||
except (socket.error, AttributeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
self.shutdown()
|
|
||||||
|
|
||||||
def send_plain(self, buf, packet_number=None,
|
|
||||||
compressed_packet_number=None):
|
|
||||||
"""Send packets to the MySQL server"""
|
|
||||||
if packet_number is None:
|
|
||||||
self.next_packet_number # pylint: disable=W0104
|
|
||||||
else:
|
|
||||||
self._packet_number = packet_number
|
|
||||||
packets = _prepare_packets(buf, self._packet_number)
|
|
||||||
for packet in packets:
|
|
||||||
try:
|
|
||||||
if PY2:
|
|
||||||
self.sock.sendall(buffer(packet)) # pylint: disable=E0602
|
|
||||||
else:
|
|
||||||
self.sock.sendall(packet)
|
|
||||||
except IOError as err:
|
|
||||||
raise errors.OperationalError(
|
|
||||||
errno=2055, values=(self.get_address(), _strioerror(err)))
|
|
||||||
except AttributeError:
|
|
||||||
raise errors.OperationalError(errno=2006)
|
|
||||||
|
|
||||||
send = send_plain
|
|
||||||
|
|
||||||
def send_compressed(self, buf, packet_number=None,
|
|
||||||
compressed_packet_number=None):
|
|
||||||
"""Send compressed packets to the MySQL server"""
|
|
||||||
if packet_number is None:
|
|
||||||
self.next_packet_number # pylint: disable=W0104
|
|
||||||
else:
|
|
||||||
self._packet_number = packet_number
|
|
||||||
if compressed_packet_number is None:
|
|
||||||
self.next_compressed_packet_number # pylint: disable=W0104
|
|
||||||
else:
|
|
||||||
self._compressed_packet_number = compressed_packet_number
|
|
||||||
|
|
||||||
pktnr = self._packet_number
|
|
||||||
pllen = len(buf)
|
|
||||||
zpkts = []
|
|
||||||
maxpktlen = constants.MAX_PACKET_LENGTH
|
|
||||||
if pllen > maxpktlen:
|
|
||||||
pkts = _prepare_packets(buf, pktnr)
|
|
||||||
if PY2:
|
|
||||||
tmpbuf = bytearray()
|
|
||||||
for pkt in pkts:
|
|
||||||
tmpbuf += pkt
|
|
||||||
tmpbuf = buffer(tmpbuf) # pylint: disable=E0602
|
|
||||||
else:
|
|
||||||
tmpbuf = b''.join(pkts)
|
|
||||||
del pkts
|
|
||||||
zbuf = zlib.compress(tmpbuf[:16384])
|
|
||||||
header = (struct.pack('<I', len(zbuf))[0:3]
|
|
||||||
+ struct.pack('<B', self._compressed_packet_number)
|
|
||||||
+ b'\x00\x40\x00')
|
|
||||||
if PY2:
|
|
||||||
header = buffer(header) # pylint: disable=E0602
|
|
||||||
zpkts.append(header + zbuf)
|
|
||||||
tmpbuf = tmpbuf[16384:]
|
|
||||||
pllen = len(tmpbuf)
|
|
||||||
self.next_compressed_packet_number # pylint: disable=W0104
|
|
||||||
while pllen > maxpktlen:
|
|
||||||
zbuf = zlib.compress(tmpbuf[:maxpktlen])
|
|
||||||
header = (struct.pack('<I', len(zbuf))[0:3]
|
|
||||||
+ struct.pack('<B', self._compressed_packet_number)
|
|
||||||
+ b'\xff\xff\xff')
|
|
||||||
if PY2:
|
|
||||||
header = buffer(header) # pylint: disable=E0602
|
|
||||||
zpkts.append(header + zbuf)
|
|
||||||
tmpbuf = tmpbuf[maxpktlen:]
|
|
||||||
pllen = len(tmpbuf)
|
|
||||||
self.next_compressed_packet_number # pylint: disable=W0104
|
|
||||||
if tmpbuf:
|
|
||||||
zbuf = zlib.compress(tmpbuf)
|
|
||||||
header = (struct.pack('<I', len(zbuf))[0:3]
|
|
||||||
+ struct.pack('<B', self._compressed_packet_number)
|
|
||||||
+ struct.pack('<I', pllen)[0:3])
|
|
||||||
if PY2:
|
|
||||||
header = buffer(header) # pylint: disable=E0602
|
|
||||||
zpkts.append(header + zbuf)
|
|
||||||
del tmpbuf
|
|
||||||
else:
|
|
||||||
pkt = (struct.pack('<I', pllen)[0:3] +
|
|
||||||
struct.pack('<B', pktnr) + buf)
|
|
||||||
if PY2:
|
|
||||||
pkt = buffer(pkt) # pylint: disable=E0602
|
|
||||||
pllen = len(pkt)
|
|
||||||
if pllen > 50:
|
|
||||||
zbuf = zlib.compress(pkt)
|
|
||||||
zpkts.append(struct.pack('<I', len(zbuf))[0:3]
|
|
||||||
+ struct.pack('<B', self._compressed_packet_number)
|
|
||||||
+ struct.pack('<I', pllen)[0:3]
|
|
||||||
+ zbuf)
|
|
||||||
else:
|
|
||||||
header = (struct.pack('<I', pllen)[0:3]
|
|
||||||
+ struct.pack('<B', self._compressed_packet_number)
|
|
||||||
+ struct.pack('<I', 0)[0:3])
|
|
||||||
if PY2:
|
|
||||||
header = buffer(header) # pylint: disable=E0602
|
|
||||||
zpkts.append(header + pkt)
|
|
||||||
|
|
||||||
for zip_packet in zpkts:
|
|
||||||
try:
|
|
||||||
self.sock.sendall(zip_packet)
|
|
||||||
except IOError as err:
|
|
||||||
raise errors.OperationalError(
|
|
||||||
errno=2055, values=(self.get_address(), _strioerror(err)))
|
|
||||||
except AttributeError:
|
|
||||||
raise errors.OperationalError(errno=2006)
|
|
||||||
|
|
||||||
def recv_plain(self):
|
|
||||||
"""Receive packets from the MySQL server"""
|
|
||||||
try:
|
|
||||||
# Read the header of the MySQL packet, 4 bytes
|
|
||||||
packet = bytearray(b'')
|
|
||||||
packet_len = 0
|
|
||||||
while packet_len < 4:
|
|
||||||
chunk = self.sock.recv(4 - packet_len)
|
|
||||||
if not chunk:
|
|
||||||
raise errors.InterfaceError(errno=2013)
|
|
||||||
packet += chunk
|
|
||||||
packet_len = len(packet)
|
|
||||||
|
|
||||||
# Save the packet number and payload length
|
|
||||||
self._packet_number = packet[3]
|
|
||||||
if PY2:
|
|
||||||
payload_len = struct.unpack_from(
|
|
||||||
"<I",
|
|
||||||
buffer(packet[0:3] + b'\x00'))[0] # pylint: disable=E0602
|
|
||||||
else:
|
|
||||||
payload_len = struct.unpack("<I", packet[0:3] + b'\x00')[0]
|
|
||||||
|
|
||||||
# Read the payload
|
|
||||||
rest = payload_len
|
|
||||||
packet.extend(bytearray(payload_len))
|
|
||||||
packet_view = memoryview(packet) # pylint: disable=E0602
|
|
||||||
packet_view = packet_view[4:]
|
|
||||||
while rest:
|
|
||||||
read = self.sock.recv_into(packet_view, rest)
|
|
||||||
if read == 0 and rest > 0:
|
|
||||||
raise errors.InterfaceError(errno=2013)
|
|
||||||
packet_view = packet_view[read:]
|
|
||||||
rest -= read
|
|
||||||
return packet
|
|
||||||
except IOError as err:
|
|
||||||
raise errors.OperationalError(
|
|
||||||
errno=2055, values=(self.get_address(), _strioerror(err)))
|
|
||||||
|
|
||||||
def recv_py26_plain(self):
|
|
||||||
"""Receive packets from the MySQL server"""
|
|
||||||
try:
|
|
||||||
# Read the header of the MySQL packet, 4 bytes
|
|
||||||
header = bytearray(b'')
|
|
||||||
header_len = 0
|
|
||||||
while header_len < 4:
|
|
||||||
chunk = self.sock.recv(4 - header_len)
|
|
||||||
if not chunk:
|
|
||||||
raise errors.InterfaceError(errno=2013)
|
|
||||||
header += chunk
|
|
||||||
header_len = len(header)
|
|
||||||
|
|
||||||
# Save the packet number and payload length
|
|
||||||
self._packet_number = header[3]
|
|
||||||
payload_len = struct_unpack("<I", header[0:3] + b'\x00')[0]
|
|
||||||
|
|
||||||
# Read the payload
|
|
||||||
rest = payload_len
|
|
||||||
payload = init_bytearray(b'')
|
|
||||||
while rest > 0:
|
|
||||||
chunk = self.sock.recv(rest)
|
|
||||||
if not chunk:
|
|
||||||
raise errors.InterfaceError(errno=2013)
|
|
||||||
payload += chunk
|
|
||||||
rest = payload_len - len(payload)
|
|
||||||
return header + payload
|
|
||||||
except IOError as err:
|
|
||||||
raise errors.OperationalError(
|
|
||||||
errno=2055, values=(self.get_address(), _strioerror(err)))
|
|
||||||
|
|
||||||
if sys.version_info[0:2] == (2, 6):
|
|
||||||
recv = recv_py26_plain
|
|
||||||
recv_plain = recv_py26_plain
|
|
||||||
else:
|
|
||||||
recv = recv_plain
|
|
||||||
|
|
||||||
def _split_zipped_payload(self, packet_bunch):
|
|
||||||
"""Split compressed payload"""
|
|
||||||
while packet_bunch:
|
|
||||||
if PY2:
|
|
||||||
payload_length = struct.unpack_from(
|
|
||||||
"<I",
|
|
||||||
packet_bunch[0:3] + b'\x00')[0] # pylint: disable=E0602
|
|
||||||
else:
|
|
||||||
payload_length = struct.unpack("<I", packet_bunch[0:3] + b'\x00')[0]
|
|
||||||
|
|
||||||
self._packet_queue.append(packet_bunch[0:payload_length + 4])
|
|
||||||
packet_bunch = packet_bunch[payload_length + 4:]
|
|
||||||
|
|
||||||
def recv_compressed(self):
|
|
||||||
"""Receive compressed packets from the MySQL server"""
|
|
||||||
try:
|
|
||||||
pkt = self._packet_queue.popleft()
|
|
||||||
self._packet_number = pkt[3]
|
|
||||||
return pkt
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
header = bytearray(b'')
|
|
||||||
packets = []
|
|
||||||
try:
|
|
||||||
abyte = self.sock.recv(1)
|
|
||||||
while abyte and len(header) < 7:
|
|
||||||
header += abyte
|
|
||||||
abyte = self.sock.recv(1)
|
|
||||||
while header:
|
|
||||||
if len(header) < 7:
|
|
||||||
raise errors.InterfaceError(errno=2013)
|
|
||||||
|
|
||||||
# Get length of compressed packet
|
|
||||||
zip_payload_length = struct_unpack("<I",
|
|
||||||
header[0:3] + b'\x00')[0]
|
|
||||||
self._compressed_packet_number = header[3]
|
|
||||||
|
|
||||||
# Get payload length before compression
|
|
||||||
payload_length = struct_unpack("<I", header[4:7] + b'\x00')[0]
|
|
||||||
|
|
||||||
zip_payload = init_bytearray(abyte)
|
|
||||||
while len(zip_payload) < zip_payload_length:
|
|
||||||
chunk = self.sock.recv(zip_payload_length
|
|
||||||
- len(zip_payload))
|
|
||||||
if not chunk:
|
|
||||||
raise errors.InterfaceError(errno=2013)
|
|
||||||
zip_payload = zip_payload + chunk
|
|
||||||
|
|
||||||
# Payload was not compressed
|
|
||||||
if payload_length == 0:
|
|
||||||
self._split_zipped_payload(zip_payload)
|
|
||||||
pkt = self._packet_queue.popleft()
|
|
||||||
self._packet_number = pkt[3]
|
|
||||||
return pkt
|
|
||||||
|
|
||||||
packets.append((payload_length, zip_payload))
|
|
||||||
|
|
||||||
if zip_payload_length <= 16384:
|
|
||||||
# We received the full compressed packet
|
|
||||||
break
|
|
||||||
|
|
||||||
# Get next compressed packet
|
|
||||||
header = init_bytearray(b'')
|
|
||||||
abyte = self.sock.recv(1)
|
|
||||||
while abyte and len(header) < 7:
|
|
||||||
header += abyte
|
|
||||||
abyte = self.sock.recv(1)
|
|
||||||
|
|
||||||
except IOError as err:
|
|
||||||
raise errors.OperationalError(
|
|
||||||
errno=2055, values=(self.get_address(), _strioerror(err)))
|
|
||||||
|
|
||||||
# Compressed packet can contain more than 1 MySQL packets
|
|
||||||
# We decompress and make one so we can split it up
|
|
||||||
tmp = init_bytearray(b'')
|
|
||||||
for payload_length, payload in packets:
|
|
||||||
# payload_length can not be 0; this was previously handled
|
|
||||||
if PY2:
|
|
||||||
tmp += zlib.decompress(buffer(payload)) # pylint: disable=E0602
|
|
||||||
else:
|
|
||||||
tmp += zlib.decompress(payload)
|
|
||||||
self._split_zipped_payload(tmp)
|
|
||||||
del tmp
|
|
||||||
|
|
||||||
try:
|
|
||||||
pkt = self._packet_queue.popleft()
|
|
||||||
self._packet_number = pkt[3]
|
|
||||||
return pkt
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_connection_timeout(self, timeout):
|
|
||||||
"""Set the connection timeout"""
|
|
||||||
self._connection_timeout = timeout
|
|
||||||
|
|
||||||
# pylint: disable=C0103,E1101
|
|
||||||
def switch_to_ssl(self, ca, cert, key, verify_cert=False,
|
|
||||||
verify_identity=False, cipher_suites=None,
|
|
||||||
tls_versions=None):
|
|
||||||
"""Switch the socket to use SSL"""
|
|
||||||
if not self.sock:
|
|
||||||
raise errors.InterfaceError(errno=2048)
|
|
||||||
|
|
||||||
try:
|
|
||||||
if verify_cert:
|
|
||||||
cert_reqs = ssl.CERT_REQUIRED
|
|
||||||
elif verify_identity:
|
|
||||||
cert_reqs = ssl.CERT_OPTIONAL
|
|
||||||
else:
|
|
||||||
cert_reqs = ssl.CERT_NONE
|
|
||||||
|
|
||||||
if tls_versions is None or not tls_versions:
|
|
||||||
context = ssl.create_default_context()
|
|
||||||
if not verify_identity:
|
|
||||||
context.check_hostname = False
|
|
||||||
context.options
|
|
||||||
else:
|
|
||||||
tls_versions.sort(reverse=True)
|
|
||||||
|
|
||||||
tls_version = tls_versions[0]
|
|
||||||
if not TLS_V1_3_SUPPORTED and \
|
|
||||||
tls_version == "TLSv1.3" and len(tls_versions) > 1:
|
|
||||||
tls_version = tls_versions[1]
|
|
||||||
ssl_protocol = TLS_VERSIONS[tls_version]
|
|
||||||
context = ssl.SSLContext(ssl_protocol)
|
|
||||||
|
|
||||||
if tls_version == "TLSv1.3":
|
|
||||||
if "TLSv1.2" not in tls_versions:
|
|
||||||
context.options |= ssl.OP_NO_TLSv1_2
|
|
||||||
if "TLSv1.1" not in tls_versions:
|
|
||||||
context.options |= ssl.OP_NO_TLSv1_1
|
|
||||||
if "TLSv1" not in tls_versions:
|
|
||||||
context.options |= ssl.OP_NO_TLSv1
|
|
||||||
|
|
||||||
context.check_hostname = False
|
|
||||||
context.verify_mode = cert_reqs
|
|
||||||
context.load_default_certs()
|
|
||||||
|
|
||||||
if ca:
|
|
||||||
try:
|
|
||||||
context.load_verify_locations(ca)
|
|
||||||
except (IOError, ssl.SSLError) as err:
|
|
||||||
self.sock.close()
|
|
||||||
raise InterfaceError(
|
|
||||||
"Invalid CA Certificate: {}".format(err))
|
|
||||||
if cert:
|
|
||||||
try:
|
|
||||||
context.load_cert_chain(cert, key)
|
|
||||||
except (IOError, ssl.SSLError) as err:
|
|
||||||
self.sock.close()
|
|
||||||
raise InterfaceError(
|
|
||||||
"Invalid Certificate/Key: {}".format(err))
|
|
||||||
if cipher_suites:
|
|
||||||
context.set_ciphers(cipher_suites)
|
|
||||||
|
|
||||||
if hasattr(self, "server_host"):
|
|
||||||
self.sock = context.wrap_socket(
|
|
||||||
self.sock, server_hostname=self.server_host)
|
|
||||||
else:
|
|
||||||
self.sock = context.wrap_socket(self.sock)
|
|
||||||
|
|
||||||
if verify_identity:
|
|
||||||
context.check_hostname = True
|
|
||||||
hostnames = [self.server_host]
|
|
||||||
if os.name == 'nt' and self.server_host == 'localhost':
|
|
||||||
hostnames = ['localhost', '127.0.0.1']
|
|
||||||
aliases = socket.gethostbyaddr(self.server_host)
|
|
||||||
hostnames.extend([aliases[0]] + aliases[1])
|
|
||||||
match_found = False
|
|
||||||
errs = []
|
|
||||||
for hostname in hostnames:
|
|
||||||
try:
|
|
||||||
ssl.match_hostname(self.sock.getpeercert(), hostname)
|
|
||||||
except ssl.CertificateError as err:
|
|
||||||
errs.append(str(err))
|
|
||||||
else:
|
|
||||||
match_found = True
|
|
||||||
break
|
|
||||||
if not match_found:
|
|
||||||
self.sock.close()
|
|
||||||
raise InterfaceError("Unable to verify server identity: {}"
|
|
||||||
"".format(", ".join(errs)))
|
|
||||||
except NameError:
|
|
||||||
raise errors.NotSupportedError(
|
|
||||||
"Python installation has no SSL support")
|
|
||||||
except (ssl.SSLError, IOError) as err:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
errno=2055, values=(self.get_address(), _strioerror(err)))
|
|
||||||
except ssl.CertificateError as err:
|
|
||||||
raise errors.InterfaceError(str(err))
|
|
||||||
except NotImplementedError as err:
|
|
||||||
raise errors.InterfaceError(str(err))
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: enable=C0103,E1101
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLUnixSocket(BaseMySQLSocket):
|
|
||||||
"""MySQL socket class using UNIX sockets
|
|
||||||
|
|
||||||
Opens a connection through the UNIX socket of the MySQL Server.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, unix_socket='/tmp/mysql.sock'):
|
|
||||||
super(MySQLUnixSocket, self).__init__()
|
|
||||||
self.unix_socket = unix_socket
|
|
||||||
|
|
||||||
def get_address(self):
|
|
||||||
return self.unix_socket
|
|
||||||
|
|
||||||
def open_connection(self):
|
|
||||||
try:
|
|
||||||
self.sock = socket.socket(socket.AF_UNIX, # pylint: disable=E1101
|
|
||||||
socket.SOCK_STREAM)
|
|
||||||
self.sock.settimeout(self._connection_timeout)
|
|
||||||
self.sock.connect(self.unix_socket)
|
|
||||||
except IOError as err:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
errno=2002, values=(self.get_address(), _strioerror(err)))
|
|
||||||
except Exception as err:
|
|
||||||
raise errors.InterfaceError(str(err))
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLTCPSocket(BaseMySQLSocket):
|
|
||||||
"""MySQL socket class using TCP/IP
|
|
||||||
|
|
||||||
Opens a TCP/IP connection to the MySQL Server.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, host='127.0.0.1', port=3306, force_ipv6=False):
|
|
||||||
super(MySQLTCPSocket, self).__init__()
|
|
||||||
self.server_host = host
|
|
||||||
self.server_port = port
|
|
||||||
self.force_ipv6 = force_ipv6
|
|
||||||
self._family = 0
|
|
||||||
|
|
||||||
def get_address(self):
|
|
||||||
return "{0}:{1}".format(self.server_host, self.server_port)
|
|
||||||
|
|
||||||
def open_connection(self):
|
|
||||||
"""Open the TCP/IP connection to the MySQL server
|
|
||||||
"""
|
|
||||||
# Get address information
|
|
||||||
addrinfo = [None] * 5
|
|
||||||
try:
|
|
||||||
addrinfos = socket.getaddrinfo(self.server_host,
|
|
||||||
self.server_port,
|
|
||||||
0, socket.SOCK_STREAM,
|
|
||||||
socket.SOL_TCP)
|
|
||||||
# If multiple results we favor IPv4, unless IPv6 was forced.
|
|
||||||
for info in addrinfos:
|
|
||||||
if self.force_ipv6 and info[0] == socket.AF_INET6:
|
|
||||||
addrinfo = info
|
|
||||||
break
|
|
||||||
elif info[0] == socket.AF_INET:
|
|
||||||
addrinfo = info
|
|
||||||
break
|
|
||||||
if self.force_ipv6 and addrinfo[0] is None:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
"No IPv6 address found for {0}".format(self.server_host))
|
|
||||||
if addrinfo[0] is None:
|
|
||||||
addrinfo = addrinfos[0]
|
|
||||||
except IOError as err:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
errno=2003, values=(self.get_address(), _strioerror(err)))
|
|
||||||
else:
|
|
||||||
(self._family, socktype, proto, _, sockaddr) = addrinfo
|
|
||||||
|
|
||||||
# Instanciate the socket and connect
|
|
||||||
try:
|
|
||||||
self.sock = socket.socket(self._family, socktype, proto)
|
|
||||||
self.sock.settimeout(self._connection_timeout)
|
|
||||||
self.sock.connect(sockaddr)
|
|
||||||
except IOError as err:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
errno=2003, values=(self.get_address(), _strioerror(err)))
|
|
||||||
except Exception as err:
|
|
||||||
raise errors.OperationalError(str(err))
|
|
@ -1,345 +0,0 @@
|
|||||||
# Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Implements parser to parse MySQL option files.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import codecs
|
|
||||||
import io
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
|
|
||||||
from .catch23 import PY2
|
|
||||||
from .constants import DEFAULT_CONFIGURATION, CNX_POOL_ARGS
|
|
||||||
|
|
||||||
# pylint: disable=F0401
|
|
||||||
if PY2:
|
|
||||||
from ConfigParser import SafeConfigParser, MissingSectionHeaderError
|
|
||||||
else:
|
|
||||||
from configparser import (ConfigParser as SafeConfigParser,
|
|
||||||
MissingSectionHeaderError)
|
|
||||||
# pylint: enable=F0401
|
|
||||||
|
|
||||||
DEFAULT_EXTENSIONS = {
|
|
||||||
'nt': ('ini', 'cnf'),
|
|
||||||
'posix': ('cnf',)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def read_option_files(**config):
|
|
||||||
"""
|
|
||||||
Read option files for connection parameters.
|
|
||||||
|
|
||||||
Checks if connection arguments contain option file arguments, and then
|
|
||||||
reads option files accordingly.
|
|
||||||
"""
|
|
||||||
if 'option_files' in config:
|
|
||||||
try:
|
|
||||||
if isinstance(config['option_groups'], str):
|
|
||||||
config['option_groups'] = [config['option_groups']]
|
|
||||||
groups = config['option_groups']
|
|
||||||
del config['option_groups']
|
|
||||||
except KeyError:
|
|
||||||
groups = ['client', 'connector_python']
|
|
||||||
|
|
||||||
if isinstance(config['option_files'], str):
|
|
||||||
config['option_files'] = [config['option_files']]
|
|
||||||
option_parser = MySQLOptionsParser(list(config['option_files']),
|
|
||||||
keep_dashes=False)
|
|
||||||
del config['option_files']
|
|
||||||
|
|
||||||
config_from_file = option_parser.get_groups_as_dict_with_priority(
|
|
||||||
*groups)
|
|
||||||
config_options = {}
|
|
||||||
for group in groups:
|
|
||||||
try:
|
|
||||||
for option, value in config_from_file[group].items():
|
|
||||||
try:
|
|
||||||
if option == 'socket':
|
|
||||||
option = 'unix_socket'
|
|
||||||
|
|
||||||
if (option not in CNX_POOL_ARGS and
|
|
||||||
option != 'failover'):
|
|
||||||
# pylint: disable=W0104
|
|
||||||
DEFAULT_CONFIGURATION[option]
|
|
||||||
# pylint: enable=W0104
|
|
||||||
|
|
||||||
if (option not in config_options or
|
|
||||||
config_options[option][1] <= value[1]):
|
|
||||||
config_options[option] = value
|
|
||||||
except KeyError:
|
|
||||||
if group == 'connector_python':
|
|
||||||
raise AttributeError("Unsupported argument "
|
|
||||||
"'{0}'".format(option))
|
|
||||||
except KeyError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
not_evaluate = ('password', 'passwd')
|
|
||||||
for option, value in config_options.items():
|
|
||||||
if option not in config:
|
|
||||||
try:
|
|
||||||
if option in not_evaluate:
|
|
||||||
config[option] = value[0]
|
|
||||||
else:
|
|
||||||
config[option] = eval(value[0]) # pylint: disable=W0123
|
|
||||||
except (NameError, SyntaxError):
|
|
||||||
config[option] = value[0]
|
|
||||||
|
|
||||||
return config
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLOptionsParser(SafeConfigParser): # pylint: disable=R0901
|
|
||||||
"""This class implements methods to parse MySQL option files"""
|
|
||||||
|
|
||||||
def __init__(self, files=None, keep_dashes=True): # pylint: disable=W0231
|
|
||||||
"""Initialize
|
|
||||||
|
|
||||||
If defaults is True, default option files are read first
|
|
||||||
|
|
||||||
Raises ValueError if defaults is set to True but defaults files
|
|
||||||
cannot be found.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Regular expression to allow options with no value(For Python v2.6)
|
|
||||||
self.OPTCRE = re.compile( # pylint: disable=C0103
|
|
||||||
r'(?P<option>[^:=\s][^:=]*)'
|
|
||||||
r'\s*(?:'
|
|
||||||
r'(?P<vi>[:=])\s*'
|
|
||||||
r'(?P<value>.*))?$'
|
|
||||||
)
|
|
||||||
|
|
||||||
self._options_dict = {}
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
SafeConfigParser.__init__(self)
|
|
||||||
else:
|
|
||||||
SafeConfigParser.__init__(self, strict=False)
|
|
||||||
|
|
||||||
self.default_extension = DEFAULT_EXTENSIONS[os.name]
|
|
||||||
self.keep_dashes = keep_dashes
|
|
||||||
|
|
||||||
if not files:
|
|
||||||
raise ValueError('files argument should be given')
|
|
||||||
if isinstance(files, str):
|
|
||||||
self.files = [files]
|
|
||||||
else:
|
|
||||||
self.files = files
|
|
||||||
|
|
||||||
self._parse_options(list(self.files))
|
|
||||||
self._sections = self.get_groups_as_dict()
|
|
||||||
|
|
||||||
def optionxform(self, optionstr):
|
|
||||||
"""Converts option strings
|
|
||||||
|
|
||||||
Converts option strings to lower case and replaces dashes(-) with
|
|
||||||
underscores(_) if keep_dashes variable is set.
|
|
||||||
"""
|
|
||||||
if not self.keep_dashes:
|
|
||||||
optionstr = optionstr.replace('-', '_')
|
|
||||||
return optionstr.lower()
|
|
||||||
|
|
||||||
def _parse_options(self, files):
|
|
||||||
"""Parse options from files given as arguments.
|
|
||||||
This method checks for !include or !inculdedir directives and if there
|
|
||||||
is any, those files included by these directives are also parsed
|
|
||||||
for options.
|
|
||||||
|
|
||||||
Raises ValueError if any of the included or file given in arguments
|
|
||||||
is not readable.
|
|
||||||
"""
|
|
||||||
index = 0
|
|
||||||
err_msg = "Option file '{0}' being included again in file '{1}'"
|
|
||||||
|
|
||||||
for file_ in files:
|
|
||||||
try:
|
|
||||||
if file_ in files[index+1:]:
|
|
||||||
raise ValueError("Same option file '{0}' occurring more "
|
|
||||||
"than once in the list".format(file_))
|
|
||||||
with open(file_, 'r') as op_file:
|
|
||||||
for line in op_file.readlines():
|
|
||||||
if line.startswith('!includedir'):
|
|
||||||
_, dir_path = line.split(None, 1)
|
|
||||||
dir_path = dir_path.strip()
|
|
||||||
for entry in os.listdir(dir_path):
|
|
||||||
entry = os.path.join(dir_path, entry)
|
|
||||||
if entry in files:
|
|
||||||
raise ValueError(err_msg.format(
|
|
||||||
entry, file_))
|
|
||||||
if (os.path.isfile(entry) and
|
|
||||||
entry.endswith(self.default_extension)):
|
|
||||||
files.insert(index+1, entry)
|
|
||||||
|
|
||||||
elif line.startswith('!include'):
|
|
||||||
_, filename = line.split(None, 1)
|
|
||||||
filename = filename.strip()
|
|
||||||
if filename in files:
|
|
||||||
raise ValueError(err_msg.format(
|
|
||||||
filename, file_))
|
|
||||||
files.insert(index+1, filename)
|
|
||||||
|
|
||||||
index += 1
|
|
||||||
|
|
||||||
except (IOError, OSError) as exc:
|
|
||||||
raise ValueError("Failed reading file '{0}': {1}".format(
|
|
||||||
file_, str(exc)))
|
|
||||||
|
|
||||||
read_files = self.read(files)
|
|
||||||
not_read_files = set(files) - set(read_files)
|
|
||||||
if not_read_files:
|
|
||||||
raise ValueError("File(s) {0} could not be read.".format(
|
|
||||||
', '.join(not_read_files)))
|
|
||||||
|
|
||||||
def read(self, filenames): # pylint: disable=W0221
|
|
||||||
"""Read and parse a filename or a list of filenames.
|
|
||||||
|
|
||||||
Overridden from ConfigParser and modified so as to allow options
|
|
||||||
which are not inside any section header
|
|
||||||
|
|
||||||
Return list of successfully read files.
|
|
||||||
"""
|
|
||||||
if isinstance(filenames, str):
|
|
||||||
filenames = [filenames]
|
|
||||||
read_ok = []
|
|
||||||
for priority, filename in enumerate(filenames):
|
|
||||||
try:
|
|
||||||
out_file = io.StringIO()
|
|
||||||
for line in codecs.open(filename, encoding='utf-8'):
|
|
||||||
line = line.strip()
|
|
||||||
match_obj = self.OPTCRE.match(line)
|
|
||||||
if not self.SECTCRE.match(line) and match_obj:
|
|
||||||
optname, delimiter, optval = match_obj.group('option',
|
|
||||||
'vi',
|
|
||||||
'value')
|
|
||||||
if optname and not optval and not delimiter:
|
|
||||||
out_file.write(line + "=\n")
|
|
||||||
else:
|
|
||||||
out_file.write(line + '\n')
|
|
||||||
else:
|
|
||||||
out_file.write(line + '\n')
|
|
||||||
out_file.seek(0)
|
|
||||||
except IOError:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
self._read(out_file, filename)
|
|
||||||
for group in self._sections.keys():
|
|
||||||
try:
|
|
||||||
self._options_dict[group]
|
|
||||||
except KeyError:
|
|
||||||
self._options_dict[group] = {}
|
|
||||||
for option, value in self._sections[group].items():
|
|
||||||
self._options_dict[group][option] = (value, priority)
|
|
||||||
|
|
||||||
self._sections = self._dict()
|
|
||||||
|
|
||||||
except MissingSectionHeaderError:
|
|
||||||
self._read(out_file, filename)
|
|
||||||
out_file.close()
|
|
||||||
read_ok.append(filename)
|
|
||||||
return read_ok
|
|
||||||
|
|
||||||
def get_groups(self, *args):
|
|
||||||
"""Returns options as a dictionary.
|
|
||||||
|
|
||||||
Returns options from all the groups specified as arguments, returns
|
|
||||||
the options from all groups if no argument provided. Options are
|
|
||||||
overridden when they are found in the next group.
|
|
||||||
|
|
||||||
Returns a dictionary
|
|
||||||
"""
|
|
||||||
if not args:
|
|
||||||
args = self._options_dict.keys()
|
|
||||||
|
|
||||||
options = {}
|
|
||||||
priority = {}
|
|
||||||
for group in args:
|
|
||||||
try:
|
|
||||||
for option, value in [(key, value,) for key, value in
|
|
||||||
self._options_dict[group].items() if
|
|
||||||
key != "__name__" and
|
|
||||||
not key.startswith("!")]:
|
|
||||||
if option not in options or priority[option] <= value[1]:
|
|
||||||
priority[option] = value[1]
|
|
||||||
options[option] = value[0]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
def get_groups_as_dict_with_priority(self, *args): # pylint: disable=C0103
|
|
||||||
"""Returns options as dictionary of dictionaries.
|
|
||||||
|
|
||||||
Returns options from all the groups specified as arguments. For each
|
|
||||||
group the option are contained in a dictionary. The order in which
|
|
||||||
the groups are specified is unimportant. Also options are not
|
|
||||||
overridden in between the groups.
|
|
||||||
|
|
||||||
The value is a tuple with two elements, first being the actual value
|
|
||||||
and second is the priority of the value which is higher for a value
|
|
||||||
read from a higher priority file.
|
|
||||||
|
|
||||||
Returns an dictionary of dictionaries
|
|
||||||
"""
|
|
||||||
if not args:
|
|
||||||
args = self._options_dict.keys()
|
|
||||||
|
|
||||||
options = dict()
|
|
||||||
for group in args:
|
|
||||||
try:
|
|
||||||
options[group] = dict((key, value,) for key, value in
|
|
||||||
self._options_dict[group].items() if
|
|
||||||
key != "__name__" and
|
|
||||||
not key.startswith("!"))
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return options
|
|
||||||
|
|
||||||
def get_groups_as_dict(self, *args):
|
|
||||||
"""Returns options as dictionary of dictionaries.
|
|
||||||
|
|
||||||
Returns options from all the groups specified as arguments. For each
|
|
||||||
group the option are contained in a dictionary. The order in which
|
|
||||||
the groups are specified is unimportant. Also options are not
|
|
||||||
overridden in between the groups.
|
|
||||||
|
|
||||||
Returns an dictionary of dictionaries
|
|
||||||
"""
|
|
||||||
if not args:
|
|
||||||
args = self._options_dict.keys()
|
|
||||||
|
|
||||||
options = dict()
|
|
||||||
for group in args:
|
|
||||||
try:
|
|
||||||
options[group] = dict((key, value[0],) for key, value in
|
|
||||||
self._options_dict[group].items() if
|
|
||||||
key != "__name__" and
|
|
||||||
not key.startswith("!"))
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return options
|
|
@ -1,361 +0,0 @@
|
|||||||
# Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Implementing pooling of connections to MySQL servers.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
from uuid import uuid4
|
|
||||||
# pylint: disable=F0401
|
|
||||||
try:
|
|
||||||
import queue
|
|
||||||
except ImportError:
|
|
||||||
# Python v2
|
|
||||||
import Queue as queue
|
|
||||||
# pylint: enable=F0401
|
|
||||||
import threading
|
|
||||||
|
|
||||||
from . import errors
|
|
||||||
from .connection import MySQLConnection
|
|
||||||
|
|
||||||
CONNECTION_POOL_LOCK = threading.RLock()
|
|
||||||
CNX_POOL_MAXSIZE = 32
|
|
||||||
CNX_POOL_MAXNAMESIZE = 64
|
|
||||||
CNX_POOL_NAMEREGEX = re.compile(r'[^a-zA-Z0-9._:\-*$#]')
|
|
||||||
|
|
||||||
|
|
||||||
def generate_pool_name(**kwargs):
|
|
||||||
"""Generate a pool name
|
|
||||||
|
|
||||||
This function takes keyword arguments, usually the connection
|
|
||||||
arguments for MySQLConnection, and tries to generate a name for
|
|
||||||
a pool.
|
|
||||||
|
|
||||||
Raises PoolError when no name can be generated.
|
|
||||||
|
|
||||||
Returns a string.
|
|
||||||
"""
|
|
||||||
parts = []
|
|
||||||
for key in ('host', 'port', 'user', 'database'):
|
|
||||||
try:
|
|
||||||
parts.append(str(kwargs[key]))
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if not parts:
|
|
||||||
raise errors.PoolError(
|
|
||||||
"Failed generating pool name; specify pool_name")
|
|
||||||
|
|
||||||
return '_'.join(parts)
|
|
||||||
|
|
||||||
|
|
||||||
class PooledMySQLConnection(object):
|
|
||||||
"""Class holding a MySQL Connection in a pool
|
|
||||||
|
|
||||||
PooledMySQLConnection is used by MySQLConnectionPool to return an
|
|
||||||
instance holding a MySQL connection. It works like a MySQLConnection
|
|
||||||
except for methods like close() and config().
|
|
||||||
|
|
||||||
The close()-method will add the connection back to the pool rather
|
|
||||||
than disconnecting from the MySQL server.
|
|
||||||
|
|
||||||
Configuring the connection have to be done through the MySQLConnectionPool
|
|
||||||
method set_config(). Using config() on pooled connection will raise a
|
|
||||||
PoolError.
|
|
||||||
"""
|
|
||||||
def __init__(self, pool, cnx):
|
|
||||||
"""Initialize
|
|
||||||
|
|
||||||
The pool argument must be an instance of MySQLConnectionPoll. cnx
|
|
||||||
if an instance of MySQLConnection.
|
|
||||||
"""
|
|
||||||
if not isinstance(pool, MySQLConnectionPool):
|
|
||||||
raise AttributeError(
|
|
||||||
"pool should be a MySQLConnectionPool")
|
|
||||||
if not isinstance(cnx, MySQLConnection):
|
|
||||||
raise AttributeError(
|
|
||||||
"cnx should be a MySQLConnection")
|
|
||||||
self._cnx_pool = pool
|
|
||||||
self._cnx = cnx
|
|
||||||
|
|
||||||
def __getattr__(self, attr):
|
|
||||||
"""Calls attributes of the MySQLConnection instance"""
|
|
||||||
return getattr(self._cnx, attr)
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
"""Do not close, but add connection back to pool
|
|
||||||
|
|
||||||
The close() method does not close the connection with the
|
|
||||||
MySQL server. The connection is added back to the pool so it
|
|
||||||
can be reused.
|
|
||||||
|
|
||||||
When the pool is configured to reset the session, the session
|
|
||||||
state will be cleared by re-authenticating the user.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
cnx = self._cnx
|
|
||||||
if self._cnx_pool.reset_session:
|
|
||||||
cnx.reset_session()
|
|
||||||
finally:
|
|
||||||
self._cnx_pool.add_connection(cnx)
|
|
||||||
self._cnx = None
|
|
||||||
|
|
||||||
def config(self, **kwargs):
|
|
||||||
"""Configuration is done through the pool"""
|
|
||||||
raise errors.PoolError(
|
|
||||||
"Configuration for pooled connections should "
|
|
||||||
"be done through the pool itself."
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def pool_name(self):
|
|
||||||
"""Return the name of the connection pool"""
|
|
||||||
return self._cnx_pool.pool_name
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLConnectionPool(object):
|
|
||||||
"""Class defining a pool of MySQL connections"""
|
|
||||||
def __init__(self, pool_size=5, pool_name=None, pool_reset_session=True,
|
|
||||||
**kwargs):
|
|
||||||
"""Initialize
|
|
||||||
|
|
||||||
Initialize a MySQL connection pool with a maximum number of
|
|
||||||
connections set to pool_size. The rest of the keywords
|
|
||||||
arguments, kwargs, are configuration arguments for MySQLConnection
|
|
||||||
instances.
|
|
||||||
"""
|
|
||||||
self._pool_size = None
|
|
||||||
self._pool_name = None
|
|
||||||
self._reset_session = pool_reset_session
|
|
||||||
self._set_pool_size(pool_size)
|
|
||||||
self._set_pool_name(pool_name or generate_pool_name(**kwargs))
|
|
||||||
self._cnx_config = {}
|
|
||||||
self._cnx_queue = queue.Queue(self._pool_size)
|
|
||||||
self._config_version = uuid4()
|
|
||||||
|
|
||||||
if kwargs:
|
|
||||||
self.set_config(**kwargs)
|
|
||||||
cnt = 0
|
|
||||||
while cnt < self._pool_size:
|
|
||||||
self.add_connection()
|
|
||||||
cnt += 1
|
|
||||||
|
|
||||||
@property
|
|
||||||
def pool_name(self):
|
|
||||||
"""Return the name of the connection pool"""
|
|
||||||
return self._pool_name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def pool_size(self):
|
|
||||||
"""Return number of connections managed by the pool"""
|
|
||||||
return self._pool_size
|
|
||||||
|
|
||||||
@property
|
|
||||||
def reset_session(self):
|
|
||||||
"""Return whether to reset session"""
|
|
||||||
return self._reset_session
|
|
||||||
|
|
||||||
def set_config(self, **kwargs):
|
|
||||||
"""Set the connection configuration for MySQLConnection instances
|
|
||||||
|
|
||||||
This method sets the configuration used for creating MySQLConnection
|
|
||||||
instances. See MySQLConnection for valid connection arguments.
|
|
||||||
|
|
||||||
Raises PoolError when a connection argument is not valid, missing
|
|
||||||
or not supported by MySQLConnection.
|
|
||||||
"""
|
|
||||||
if not kwargs:
|
|
||||||
return
|
|
||||||
|
|
||||||
with CONNECTION_POOL_LOCK:
|
|
||||||
try:
|
|
||||||
test_cnx = MySQLConnection()
|
|
||||||
if "use_pure" in kwargs:
|
|
||||||
del kwargs["use_pure"]
|
|
||||||
test_cnx.config(**kwargs)
|
|
||||||
self._cnx_config = kwargs
|
|
||||||
self._config_version = uuid4()
|
|
||||||
except AttributeError as err:
|
|
||||||
raise errors.PoolError(
|
|
||||||
"Connection configuration not valid: {0}".format(err))
|
|
||||||
|
|
||||||
def _set_pool_size(self, pool_size):
|
|
||||||
"""Set the size of the pool
|
|
||||||
|
|
||||||
This method sets the size of the pool but it will not resize the pool.
|
|
||||||
|
|
||||||
Raises an AttributeError when the pool_size is not valid. Invalid size
|
|
||||||
is 0, negative or higher than pooling.CNX_POOL_MAXSIZE.
|
|
||||||
"""
|
|
||||||
if pool_size <= 0 or pool_size > CNX_POOL_MAXSIZE:
|
|
||||||
raise AttributeError(
|
|
||||||
"Pool size should be higher than 0 and "
|
|
||||||
"lower or equal to {0}".format(CNX_POOL_MAXSIZE))
|
|
||||||
self._pool_size = pool_size
|
|
||||||
|
|
||||||
def _set_pool_name(self, pool_name):
|
|
||||||
r"""Set the name of the pool
|
|
||||||
|
|
||||||
This method checks the validity and sets the name of the pool.
|
|
||||||
|
|
||||||
Raises an AttributeError when pool_name contains illegal characters
|
|
||||||
([^a-zA-Z0-9._\-*$#]) or is longer than pooling.CNX_POOL_MAXNAMESIZE.
|
|
||||||
"""
|
|
||||||
if CNX_POOL_NAMEREGEX.search(pool_name):
|
|
||||||
raise AttributeError(
|
|
||||||
"Pool name '{0}' contains illegal characters".format(pool_name))
|
|
||||||
if len(pool_name) > CNX_POOL_MAXNAMESIZE:
|
|
||||||
raise AttributeError(
|
|
||||||
"Pool name '{0}' is too long".format(pool_name))
|
|
||||||
self._pool_name = pool_name
|
|
||||||
|
|
||||||
def _queue_connection(self, cnx):
|
|
||||||
"""Put connection back in the queue
|
|
||||||
|
|
||||||
This method is putting a connection back in the queue. It will not
|
|
||||||
acquire a lock as the methods using _queue_connection() will have it
|
|
||||||
set.
|
|
||||||
|
|
||||||
Raises PoolError on errors.
|
|
||||||
"""
|
|
||||||
if not isinstance(cnx, MySQLConnection):
|
|
||||||
raise errors.PoolError(
|
|
||||||
"Connection instance not subclass of MySQLConnection.")
|
|
||||||
|
|
||||||
try:
|
|
||||||
self._cnx_queue.put(cnx, block=False)
|
|
||||||
except queue.Full:
|
|
||||||
raise errors.PoolError("Failed adding connection; queue is full")
|
|
||||||
|
|
||||||
def add_connection(self, cnx=None):
|
|
||||||
"""Add a connection to the pool
|
|
||||||
|
|
||||||
This method instantiates a MySQLConnection using the configuration
|
|
||||||
passed when initializing the MySQLConnectionPool instance or using
|
|
||||||
the set_config() method.
|
|
||||||
If cnx is a MySQLConnection instance, it will be added to the
|
|
||||||
queue.
|
|
||||||
|
|
||||||
Raises PoolError when no configuration is set, when no more
|
|
||||||
connection can be added (maximum reached) or when the connection
|
|
||||||
can not be instantiated.
|
|
||||||
"""
|
|
||||||
with CONNECTION_POOL_LOCK:
|
|
||||||
if not self._cnx_config:
|
|
||||||
raise errors.PoolError(
|
|
||||||
"Connection configuration not available")
|
|
||||||
|
|
||||||
if self._cnx_queue.full():
|
|
||||||
raise errors.PoolError(
|
|
||||||
"Failed adding connection; queue is full")
|
|
||||||
|
|
||||||
if not cnx:
|
|
||||||
cnx = MySQLConnection(**self._cnx_config)
|
|
||||||
try:
|
|
||||||
if (self._reset_session and self._cnx_config['compress']
|
|
||||||
and cnx.get_server_version() < (5, 7, 3)):
|
|
||||||
raise errors.NotSupportedError("Pool reset session is "
|
|
||||||
"not supported with "
|
|
||||||
"compression for MySQL "
|
|
||||||
"server version 5.7.2 "
|
|
||||||
"or earlier.")
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# pylint: disable=W0201,W0212
|
|
||||||
cnx._pool_config_version = self._config_version
|
|
||||||
# pylint: enable=W0201,W0212
|
|
||||||
else:
|
|
||||||
if not isinstance(cnx, MySQLConnection):
|
|
||||||
raise errors.PoolError(
|
|
||||||
"Connection instance not subclass of MySQLConnection.")
|
|
||||||
|
|
||||||
self._queue_connection(cnx)
|
|
||||||
|
|
||||||
def get_connection(self):
|
|
||||||
"""Get a connection from the pool
|
|
||||||
|
|
||||||
This method returns an PooledMySQLConnection instance which
|
|
||||||
has a reference to the pool that created it, and the next available
|
|
||||||
MySQL connection.
|
|
||||||
|
|
||||||
When the MySQL connection is not connect, a reconnect is attempted.
|
|
||||||
|
|
||||||
Raises PoolError on errors.
|
|
||||||
|
|
||||||
Returns a PooledMySQLConnection instance.
|
|
||||||
"""
|
|
||||||
with CONNECTION_POOL_LOCK:
|
|
||||||
try:
|
|
||||||
cnx = self._cnx_queue.get(block=False)
|
|
||||||
except queue.Empty:
|
|
||||||
raise errors.PoolError(
|
|
||||||
"Failed getting connection; pool exhausted")
|
|
||||||
|
|
||||||
# pylint: disable=W0201,W0212
|
|
||||||
if not cnx.is_connected() \
|
|
||||||
or self._config_version != cnx._pool_config_version:
|
|
||||||
cnx.config(**self._cnx_config)
|
|
||||||
try:
|
|
||||||
cnx.reconnect()
|
|
||||||
except errors.InterfaceError:
|
|
||||||
# Failed to reconnect, give connection back to pool
|
|
||||||
self._queue_connection(cnx)
|
|
||||||
raise
|
|
||||||
cnx._pool_config_version = self._config_version
|
|
||||||
# pylint: enable=W0201,W0212
|
|
||||||
|
|
||||||
return PooledMySQLConnection(self, cnx)
|
|
||||||
|
|
||||||
def _remove_connections(self):
|
|
||||||
"""Close all connections
|
|
||||||
|
|
||||||
This method closes all connections. It returns the number
|
|
||||||
of connections it closed.
|
|
||||||
|
|
||||||
Used mostly for tests.
|
|
||||||
|
|
||||||
Returns int.
|
|
||||||
"""
|
|
||||||
with CONNECTION_POOL_LOCK:
|
|
||||||
cnt = 0
|
|
||||||
cnxq = self._cnx_queue
|
|
||||||
while cnxq.qsize():
|
|
||||||
try:
|
|
||||||
cnx = cnxq.get(block=False)
|
|
||||||
cnx.disconnect()
|
|
||||||
cnt += 1
|
|
||||||
except queue.Empty:
|
|
||||||
return cnt
|
|
||||||
except errors.PoolError:
|
|
||||||
raise
|
|
||||||
except errors.Error:
|
|
||||||
# Any other error when closing means connection is closed
|
|
||||||
pass
|
|
||||||
|
|
||||||
return cnt
|
|
@ -1,762 +0,0 @@
|
|||||||
# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Implements the MySQL Client/Server protocol
|
|
||||||
"""
|
|
||||||
|
|
||||||
import struct
|
|
||||||
import datetime
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
from .constants import (
|
|
||||||
FieldFlag, ServerCmd, FieldType, ClientFlag)
|
|
||||||
from . import errors, utils
|
|
||||||
from .authentication import get_auth_plugin
|
|
||||||
from .catch23 import PY2, struct_unpack
|
|
||||||
from .errors import DatabaseError, get_exception
|
|
||||||
|
|
||||||
PROTOCOL_VERSION = 10
|
|
||||||
|
|
||||||
|
|
||||||
class MySQLProtocol(object):
|
|
||||||
"""Implements MySQL client/server protocol
|
|
||||||
|
|
||||||
Create and parses MySQL packets.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def _connect_with_db(self, client_flags, database):
|
|
||||||
"""Prepare database string for handshake response"""
|
|
||||||
if client_flags & ClientFlag.CONNECT_WITH_DB and database:
|
|
||||||
return database.encode('utf8') + b'\x00'
|
|
||||||
return b'\x00'
|
|
||||||
|
|
||||||
def _auth_response(self, client_flags, username, password, database,
|
|
||||||
auth_plugin, auth_data, ssl_enabled):
|
|
||||||
"""Prepare the authentication response"""
|
|
||||||
if not password:
|
|
||||||
return b'\x00'
|
|
||||||
|
|
||||||
try:
|
|
||||||
auth = get_auth_plugin(auth_plugin)(
|
|
||||||
auth_data,
|
|
||||||
username=username, password=password, database=database,
|
|
||||||
ssl_enabled=ssl_enabled)
|
|
||||||
plugin_auth_response = auth.auth_response()
|
|
||||||
except (TypeError, errors.InterfaceError) as exc:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
"Failed authentication: {0}".format(str(exc)))
|
|
||||||
|
|
||||||
if client_flags & ClientFlag.SECURE_CONNECTION:
|
|
||||||
resplen = len(plugin_auth_response)
|
|
||||||
auth_response = struct.pack('<B', resplen) + plugin_auth_response
|
|
||||||
else:
|
|
||||||
auth_response = plugin_auth_response + b'\x00'
|
|
||||||
return auth_response
|
|
||||||
|
|
||||||
def make_auth(self, handshake, username=None, password=None, database=None,
|
|
||||||
charset=45, client_flags=0,
|
|
||||||
max_allowed_packet=1073741824, ssl_enabled=False,
|
|
||||||
auth_plugin=None, conn_attrs=None):
|
|
||||||
"""Make a MySQL Authentication packet"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
auth_data = handshake['auth_data']
|
|
||||||
auth_plugin = auth_plugin or handshake['auth_plugin']
|
|
||||||
except (TypeError, KeyError) as exc:
|
|
||||||
raise errors.ProgrammingError(
|
|
||||||
"Handshake misses authentication info ({0})".format(exc))
|
|
||||||
|
|
||||||
if not username:
|
|
||||||
username = b''
|
|
||||||
try:
|
|
||||||
username_bytes = username.encode('utf8') # pylint: disable=E1103
|
|
||||||
except AttributeError:
|
|
||||||
# Username is already bytes
|
|
||||||
username_bytes = username
|
|
||||||
packet = struct.pack('<IIH{filler}{usrlen}sx'.format(
|
|
||||||
filler='x' * 22, usrlen=len(username_bytes)),
|
|
||||||
client_flags, max_allowed_packet, charset,
|
|
||||||
username_bytes)
|
|
||||||
|
|
||||||
packet += self._auth_response(client_flags, username, password,
|
|
||||||
database,
|
|
||||||
auth_plugin,
|
|
||||||
auth_data, ssl_enabled)
|
|
||||||
|
|
||||||
packet += self._connect_with_db(client_flags, database)
|
|
||||||
|
|
||||||
if client_flags & ClientFlag.PLUGIN_AUTH:
|
|
||||||
packet += auth_plugin.encode('utf8') + b'\x00'
|
|
||||||
|
|
||||||
if (client_flags & ClientFlag.CONNECT_ARGS) and conn_attrs is not None:
|
|
||||||
packet += self.make_conn_attrs(conn_attrs)
|
|
||||||
|
|
||||||
return packet
|
|
||||||
|
|
||||||
def make_conn_attrs(self, conn_attrs):
|
|
||||||
"""Encode the connection attributes"""
|
|
||||||
for attr_name in conn_attrs:
|
|
||||||
if conn_attrs[attr_name] is None:
|
|
||||||
conn_attrs[attr_name] = ""
|
|
||||||
conn_attrs_len = (
|
|
||||||
sum([len(x) + len(conn_attrs[x]) for x in conn_attrs]) +
|
|
||||||
len(conn_attrs.keys()) + len(conn_attrs.values()))
|
|
||||||
|
|
||||||
conn_attrs_packet = struct.pack('<B', conn_attrs_len)
|
|
||||||
for attr_name in conn_attrs:
|
|
||||||
conn_attrs_packet += struct.pack('<B', len(attr_name))
|
|
||||||
conn_attrs_packet += attr_name.encode('utf8')
|
|
||||||
conn_attrs_packet += struct.pack('<B', len(conn_attrs[attr_name]))
|
|
||||||
conn_attrs_packet += conn_attrs[attr_name].encode('utf8')
|
|
||||||
return conn_attrs_packet
|
|
||||||
|
|
||||||
def make_auth_ssl(self, charset=45, client_flags=0,
|
|
||||||
max_allowed_packet=1073741824):
|
|
||||||
"""Make a SSL authentication packet"""
|
|
||||||
return utils.int4store(client_flags) + \
|
|
||||||
utils.int4store(max_allowed_packet) + \
|
|
||||||
utils.int2store(charset) + \
|
|
||||||
b'\x00' * 22
|
|
||||||
|
|
||||||
def make_command(self, command, argument=None):
|
|
||||||
"""Make a MySQL packet containing a command"""
|
|
||||||
data = utils.int1store(command)
|
|
||||||
if argument is not None:
|
|
||||||
data += argument
|
|
||||||
return data
|
|
||||||
|
|
||||||
def make_stmt_fetch(self, statement_id, rows=1):
|
|
||||||
"""Make a MySQL packet with Fetch Statement command"""
|
|
||||||
return utils.int4store(statement_id) + utils.int4store(rows)
|
|
||||||
|
|
||||||
def make_change_user(self, handshake, username=None, password=None,
|
|
||||||
database=None, charset=45, client_flags=0,
|
|
||||||
ssl_enabled=False, auth_plugin=None):
|
|
||||||
"""Make a MySQL packet with the Change User command"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
auth_data = handshake['auth_data']
|
|
||||||
auth_plugin = auth_plugin or handshake['auth_plugin']
|
|
||||||
except (TypeError, KeyError) as exc:
|
|
||||||
raise errors.ProgrammingError(
|
|
||||||
"Handshake misses authentication info ({0})".format(exc))
|
|
||||||
|
|
||||||
if not username:
|
|
||||||
username = b''
|
|
||||||
try:
|
|
||||||
username_bytes = username.encode('utf8') # pylint: disable=E1103
|
|
||||||
except AttributeError:
|
|
||||||
# Username is already bytes
|
|
||||||
username_bytes = username
|
|
||||||
packet = struct.pack('<B{usrlen}sx'.format(usrlen=len(username_bytes)),
|
|
||||||
ServerCmd.CHANGE_USER, username_bytes)
|
|
||||||
|
|
||||||
packet += self._auth_response(client_flags, username, password,
|
|
||||||
database,
|
|
||||||
auth_plugin,
|
|
||||||
auth_data, ssl_enabled)
|
|
||||||
|
|
||||||
packet += self._connect_with_db(client_flags, database)
|
|
||||||
|
|
||||||
packet += struct.pack('<H', charset)
|
|
||||||
|
|
||||||
if client_flags & ClientFlag.PLUGIN_AUTH:
|
|
||||||
packet += auth_plugin.encode('utf8') + b'\x00'
|
|
||||||
|
|
||||||
return packet
|
|
||||||
|
|
||||||
def parse_handshake(self, packet):
|
|
||||||
"""Parse a MySQL Handshake-packet"""
|
|
||||||
res = {}
|
|
||||||
res['protocol'] = struct_unpack('<xxxxB', packet[0:5])[0]
|
|
||||||
if res["protocol"] != PROTOCOL_VERSION:
|
|
||||||
raise DatabaseError("Protocol mismatch; server version = {}, "
|
|
||||||
"client version = {}".format(res["protocol"],
|
|
||||||
PROTOCOL_VERSION))
|
|
||||||
(packet, res['server_version_original']) = utils.read_string(
|
|
||||||
packet[5:], end=b'\x00')
|
|
||||||
|
|
||||||
(res['server_threadid'],
|
|
||||||
auth_data1,
|
|
||||||
capabilities1,
|
|
||||||
res['charset'],
|
|
||||||
res['server_status'],
|
|
||||||
capabilities2,
|
|
||||||
auth_data_length
|
|
||||||
) = struct_unpack('<I8sx2sBH2sBxxxxxxxxxx', packet[0:31])
|
|
||||||
res['server_version_original'] = res['server_version_original'].decode()
|
|
||||||
|
|
||||||
packet = packet[31:]
|
|
||||||
|
|
||||||
capabilities = utils.intread(capabilities1 + capabilities2)
|
|
||||||
auth_data2 = b''
|
|
||||||
if capabilities & ClientFlag.SECURE_CONNECTION:
|
|
||||||
size = min(13, auth_data_length - 8) if auth_data_length else 13
|
|
||||||
auth_data2 = packet[0:size]
|
|
||||||
packet = packet[size:]
|
|
||||||
if auth_data2[-1] == 0:
|
|
||||||
auth_data2 = auth_data2[:-1]
|
|
||||||
|
|
||||||
if capabilities & ClientFlag.PLUGIN_AUTH:
|
|
||||||
if (b'\x00' not in packet
|
|
||||||
and res['server_version_original'].startswith("5.5.8")):
|
|
||||||
# MySQL server 5.5.8 has a bug where end byte is not send
|
|
||||||
(packet, res['auth_plugin']) = (b'', packet)
|
|
||||||
else:
|
|
||||||
(packet, res['auth_plugin']) = utils.read_string(
|
|
||||||
packet, end=b'\x00')
|
|
||||||
res['auth_plugin'] = res['auth_plugin'].decode('utf-8')
|
|
||||||
else:
|
|
||||||
res['auth_plugin'] = 'mysql_native_password'
|
|
||||||
|
|
||||||
res['auth_data'] = auth_data1 + auth_data2
|
|
||||||
res['capabilities'] = capabilities
|
|
||||||
return res
|
|
||||||
|
|
||||||
def parse_ok(self, packet):
|
|
||||||
"""Parse a MySQL OK-packet"""
|
|
||||||
if not packet[4] == 0:
|
|
||||||
raise errors.InterfaceError("Failed parsing OK packet (invalid).")
|
|
||||||
|
|
||||||
ok_packet = {}
|
|
||||||
try:
|
|
||||||
ok_packet['field_count'] = struct_unpack('<xxxxB', packet[0:5])[0]
|
|
||||||
(packet, ok_packet['affected_rows']) = utils.read_lc_int(packet[5:])
|
|
||||||
(packet, ok_packet['insert_id']) = utils.read_lc_int(packet)
|
|
||||||
(ok_packet['status_flag'],
|
|
||||||
ok_packet['warning_count']) = struct_unpack('<HH', packet[0:4])
|
|
||||||
packet = packet[4:]
|
|
||||||
if packet:
|
|
||||||
(packet, ok_packet['info_msg']) = utils.read_lc_string(packet)
|
|
||||||
ok_packet['info_msg'] = ok_packet['info_msg'].decode('utf-8')
|
|
||||||
except ValueError:
|
|
||||||
raise errors.InterfaceError("Failed parsing OK packet.")
|
|
||||||
return ok_packet
|
|
||||||
|
|
||||||
def parse_column_count(self, packet):
|
|
||||||
"""Parse a MySQL packet with the number of columns in result set"""
|
|
||||||
try:
|
|
||||||
count = utils.read_lc_int(packet[4:])[1]
|
|
||||||
return count
|
|
||||||
except (struct.error, ValueError):
|
|
||||||
raise errors.InterfaceError("Failed parsing column count")
|
|
||||||
|
|
||||||
def parse_column(self, packet, charset='utf-8'):
|
|
||||||
"""Parse a MySQL column-packet"""
|
|
||||||
(packet, _) = utils.read_lc_string(packet[4:]) # catalog
|
|
||||||
(packet, _) = utils.read_lc_string(packet) # db
|
|
||||||
(packet, _) = utils.read_lc_string(packet) # table
|
|
||||||
(packet, _) = utils.read_lc_string(packet) # org_table
|
|
||||||
(packet, name) = utils.read_lc_string(packet) # name
|
|
||||||
(packet, _) = utils.read_lc_string(packet) # org_name
|
|
||||||
|
|
||||||
try:
|
|
||||||
(_, _, field_type,
|
|
||||||
flags, _) = struct_unpack('<xHIBHBxx', packet)
|
|
||||||
except struct.error:
|
|
||||||
raise errors.InterfaceError("Failed parsing column information")
|
|
||||||
|
|
||||||
return (
|
|
||||||
name.decode(charset),
|
|
||||||
field_type,
|
|
||||||
None, # display_size
|
|
||||||
None, # internal_size
|
|
||||||
None, # precision
|
|
||||||
None, # scale
|
|
||||||
~flags & FieldFlag.NOT_NULL, # null_ok
|
|
||||||
flags, # MySQL specific
|
|
||||||
)
|
|
||||||
|
|
||||||
def parse_eof(self, packet):
|
|
||||||
"""Parse a MySQL EOF-packet"""
|
|
||||||
if packet[4] == 0:
|
|
||||||
# EOF packet deprecation
|
|
||||||
return self.parse_ok(packet)
|
|
||||||
|
|
||||||
err_msg = "Failed parsing EOF packet."
|
|
||||||
res = {}
|
|
||||||
try:
|
|
||||||
unpacked = struct_unpack('<xxxBBHH', packet)
|
|
||||||
except struct.error:
|
|
||||||
raise errors.InterfaceError(err_msg)
|
|
||||||
|
|
||||||
if not (unpacked[1] == 254 and len(packet) <= 9):
|
|
||||||
raise errors.InterfaceError(err_msg)
|
|
||||||
|
|
||||||
res['warning_count'] = unpacked[2]
|
|
||||||
res['status_flag'] = unpacked[3]
|
|
||||||
return res
|
|
||||||
|
|
||||||
def parse_statistics(self, packet, with_header=True):
|
|
||||||
"""Parse the statistics packet"""
|
|
||||||
errmsg = "Failed getting COM_STATISTICS information"
|
|
||||||
res = {}
|
|
||||||
# Information is separated by 2 spaces
|
|
||||||
if with_header:
|
|
||||||
pairs = packet[4:].split(b'\x20\x20')
|
|
||||||
else:
|
|
||||||
pairs = packet.split(b'\x20\x20')
|
|
||||||
for pair in pairs:
|
|
||||||
try:
|
|
||||||
(lbl, val) = [v.strip() for v in pair.split(b':', 2)]
|
|
||||||
except:
|
|
||||||
raise errors.InterfaceError(errmsg)
|
|
||||||
|
|
||||||
# It's either an integer or a decimal
|
|
||||||
lbl = lbl.decode('utf-8')
|
|
||||||
try:
|
|
||||||
res[lbl] = int(val)
|
|
||||||
except:
|
|
||||||
try:
|
|
||||||
res[lbl] = Decimal(val.decode('utf-8'))
|
|
||||||
except:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
"{0} ({1}:{2}).".format(errmsg, lbl, val))
|
|
||||||
return res
|
|
||||||
|
|
||||||
def read_text_result(self, sock, version, count=1):
|
|
||||||
"""Read MySQL text result
|
|
||||||
|
|
||||||
Reads all or given number of rows from the socket.
|
|
||||||
|
|
||||||
Returns a tuple with 2 elements: a list with all rows and
|
|
||||||
the EOF packet.
|
|
||||||
"""
|
|
||||||
rows = []
|
|
||||||
eof = None
|
|
||||||
rowdata = None
|
|
||||||
i = 0
|
|
||||||
while True:
|
|
||||||
if eof or i == count:
|
|
||||||
break
|
|
||||||
packet = sock.recv()
|
|
||||||
if packet.startswith(b'\xff\xff\xff'):
|
|
||||||
datas = [packet[4:]]
|
|
||||||
packet = sock.recv()
|
|
||||||
while packet.startswith(b'\xff\xff\xff'):
|
|
||||||
datas.append(packet[4:])
|
|
||||||
packet = sock.recv()
|
|
||||||
datas.append(packet[4:])
|
|
||||||
rowdata = utils.read_lc_string_list(bytearray(b'').join(datas))
|
|
||||||
elif packet[4] == 254 and packet[0] < 7:
|
|
||||||
eof = self.parse_eof(packet)
|
|
||||||
rowdata = None
|
|
||||||
else:
|
|
||||||
eof = None
|
|
||||||
rowdata = utils.read_lc_string_list(packet[4:])
|
|
||||||
if eof is None and rowdata is not None:
|
|
||||||
rows.append(rowdata)
|
|
||||||
elif eof is None and rowdata is None:
|
|
||||||
raise get_exception(packet)
|
|
||||||
i += 1
|
|
||||||
return rows, eof
|
|
||||||
|
|
||||||
def _parse_binary_integer(self, packet, field):
|
|
||||||
"""Parse an integer from a binary packet"""
|
|
||||||
if field[1] == FieldType.TINY:
|
|
||||||
format_ = '<b'
|
|
||||||
length = 1
|
|
||||||
elif field[1] == FieldType.SHORT:
|
|
||||||
format_ = '<h'
|
|
||||||
length = 2
|
|
||||||
elif field[1] in (FieldType.INT24, FieldType.LONG):
|
|
||||||
format_ = '<i'
|
|
||||||
length = 4
|
|
||||||
elif field[1] == FieldType.LONGLONG:
|
|
||||||
format_ = '<q'
|
|
||||||
length = 8
|
|
||||||
|
|
||||||
if field[7] & FieldFlag.UNSIGNED:
|
|
||||||
format_ = format_.upper()
|
|
||||||
|
|
||||||
return (packet[length:], struct_unpack(format_, packet[0:length])[0])
|
|
||||||
|
|
||||||
def _parse_binary_float(self, packet, field):
|
|
||||||
"""Parse a float/double from a binary packet"""
|
|
||||||
if field[1] == FieldType.DOUBLE:
|
|
||||||
length = 8
|
|
||||||
format_ = '<d'
|
|
||||||
else:
|
|
||||||
length = 4
|
|
||||||
format_ = '<f'
|
|
||||||
|
|
||||||
return (packet[length:], struct_unpack(format_, packet[0:length])[0])
|
|
||||||
|
|
||||||
def _parse_binary_timestamp(self, packet, field):
|
|
||||||
"""Parse a timestamp from a binary packet"""
|
|
||||||
length = packet[0]
|
|
||||||
value = None
|
|
||||||
if length == 4:
|
|
||||||
value = datetime.date(
|
|
||||||
year=struct_unpack('<H', packet[1:3])[0],
|
|
||||||
month=packet[3],
|
|
||||||
day=packet[4])
|
|
||||||
elif length >= 7:
|
|
||||||
mcs = 0
|
|
||||||
if length == 11:
|
|
||||||
mcs = struct_unpack('<I', packet[8:length + 1])[0]
|
|
||||||
value = datetime.datetime(
|
|
||||||
year=struct_unpack('<H', packet[1:3])[0],
|
|
||||||
month=packet[3],
|
|
||||||
day=packet[4],
|
|
||||||
hour=packet[5],
|
|
||||||
minute=packet[6],
|
|
||||||
second=packet[7],
|
|
||||||
microsecond=mcs)
|
|
||||||
|
|
||||||
return (packet[length + 1:], value)
|
|
||||||
|
|
||||||
def _parse_binary_time(self, packet, field):
|
|
||||||
"""Parse a time value from a binary packet"""
|
|
||||||
length = packet[0]
|
|
||||||
data = packet[1:length + 1]
|
|
||||||
mcs = 0
|
|
||||||
if length > 8:
|
|
||||||
mcs = struct_unpack('<I', data[8:])[0]
|
|
||||||
days = struct_unpack('<I', data[1:5])[0]
|
|
||||||
if data[0] == 1:
|
|
||||||
days *= -1
|
|
||||||
tmp = datetime.timedelta(days=days,
|
|
||||||
seconds=data[7],
|
|
||||||
microseconds=mcs,
|
|
||||||
minutes=data[6],
|
|
||||||
hours=data[5])
|
|
||||||
|
|
||||||
return (packet[length + 1:], tmp)
|
|
||||||
|
|
||||||
def _parse_binary_values(self, fields, packet, charset='utf-8'):
|
|
||||||
"""Parse values from a binary result packet"""
|
|
||||||
null_bitmap_length = (len(fields) + 7 + 2) // 8
|
|
||||||
null_bitmap = [int(i) for i in packet[0:null_bitmap_length]]
|
|
||||||
packet = packet[null_bitmap_length:]
|
|
||||||
|
|
||||||
values = []
|
|
||||||
for pos, field in enumerate(fields):
|
|
||||||
if null_bitmap[int((pos+2)/8)] & (1 << (pos + 2) % 8):
|
|
||||||
values.append(None)
|
|
||||||
continue
|
|
||||||
elif field[1] in (FieldType.TINY, FieldType.SHORT,
|
|
||||||
FieldType.INT24,
|
|
||||||
FieldType.LONG, FieldType.LONGLONG):
|
|
||||||
(packet, value) = self._parse_binary_integer(packet, field)
|
|
||||||
values.append(value)
|
|
||||||
elif field[1] in (FieldType.DOUBLE, FieldType.FLOAT):
|
|
||||||
(packet, value) = self._parse_binary_float(packet, field)
|
|
||||||
values.append(value)
|
|
||||||
elif field[1] in (FieldType.DATETIME, FieldType.DATE,
|
|
||||||
FieldType.TIMESTAMP):
|
|
||||||
(packet, value) = self._parse_binary_timestamp(packet, field)
|
|
||||||
values.append(value)
|
|
||||||
elif field[1] == FieldType.TIME:
|
|
||||||
(packet, value) = self._parse_binary_time(packet, field)
|
|
||||||
values.append(value)
|
|
||||||
else:
|
|
||||||
(packet, value) = utils.read_lc_string(packet)
|
|
||||||
values.append(value.decode(charset))
|
|
||||||
|
|
||||||
return tuple(values)
|
|
||||||
|
|
||||||
def read_binary_result(self, sock, columns, count=1, charset='utf-8'):
|
|
||||||
"""Read MySQL binary protocol result
|
|
||||||
|
|
||||||
Reads all or given number of binary resultset rows from the socket.
|
|
||||||
"""
|
|
||||||
rows = []
|
|
||||||
eof = None
|
|
||||||
values = None
|
|
||||||
i = 0
|
|
||||||
while True:
|
|
||||||
if eof is not None:
|
|
||||||
break
|
|
||||||
if i == count:
|
|
||||||
break
|
|
||||||
packet = sock.recv()
|
|
||||||
if packet[4] == 254:
|
|
||||||
eof = self.parse_eof(packet)
|
|
||||||
values = None
|
|
||||||
elif packet[4] == 0:
|
|
||||||
eof = None
|
|
||||||
values = self._parse_binary_values(columns, packet[5:], charset)
|
|
||||||
if eof is None and values is not None:
|
|
||||||
rows.append(values)
|
|
||||||
elif eof is None and values is None:
|
|
||||||
raise get_exception(packet)
|
|
||||||
i += 1
|
|
||||||
return (rows, eof)
|
|
||||||
|
|
||||||
def parse_binary_prepare_ok(self, packet):
|
|
||||||
"""Parse a MySQL Binary Protocol OK packet"""
|
|
||||||
if not packet[4] == 0:
|
|
||||||
raise errors.InterfaceError("Failed parsing Binary OK packet")
|
|
||||||
|
|
||||||
ok_pkt = {}
|
|
||||||
try:
|
|
||||||
(packet, ok_pkt['statement_id']) = utils.read_int(packet[5:], 4)
|
|
||||||
(packet, ok_pkt['num_columns']) = utils.read_int(packet, 2)
|
|
||||||
(packet, ok_pkt['num_params']) = utils.read_int(packet, 2)
|
|
||||||
packet = packet[1:] # Filler 1 * \x00
|
|
||||||
(packet, ok_pkt['warning_count']) = utils.read_int(packet, 2)
|
|
||||||
except ValueError:
|
|
||||||
raise errors.InterfaceError("Failed parsing Binary OK packet")
|
|
||||||
|
|
||||||
return ok_pkt
|
|
||||||
|
|
||||||
def _prepare_binary_integer(self, value):
|
|
||||||
"""Prepare an integer for the MySQL binary protocol"""
|
|
||||||
field_type = None
|
|
||||||
flags = 0
|
|
||||||
if value < 0:
|
|
||||||
if value >= -128:
|
|
||||||
format_ = '<b'
|
|
||||||
field_type = FieldType.TINY
|
|
||||||
elif value >= -32768:
|
|
||||||
format_ = '<h'
|
|
||||||
field_type = FieldType.SHORT
|
|
||||||
elif value >= -2147483648:
|
|
||||||
format_ = '<i'
|
|
||||||
field_type = FieldType.LONG
|
|
||||||
else:
|
|
||||||
format_ = '<q'
|
|
||||||
field_type = FieldType.LONGLONG
|
|
||||||
else:
|
|
||||||
flags = 128
|
|
||||||
if value <= 255:
|
|
||||||
format_ = '<B'
|
|
||||||
field_type = FieldType.TINY
|
|
||||||
elif value <= 65535:
|
|
||||||
format_ = '<H'
|
|
||||||
field_type = FieldType.SHORT
|
|
||||||
elif value <= 4294967295:
|
|
||||||
format_ = '<I'
|
|
||||||
field_type = FieldType.LONG
|
|
||||||
else:
|
|
||||||
field_type = FieldType.LONGLONG
|
|
||||||
format_ = '<Q'
|
|
||||||
return (struct.pack(format_, value), field_type, flags)
|
|
||||||
|
|
||||||
def _prepare_binary_timestamp(self, value):
|
|
||||||
"""Prepare a timestamp object for the MySQL binary protocol
|
|
||||||
|
|
||||||
This method prepares a timestamp of type datetime.datetime or
|
|
||||||
datetime.date for sending over the MySQL binary protocol.
|
|
||||||
A tuple is returned with the prepared value and field type
|
|
||||||
as elements.
|
|
||||||
|
|
||||||
Raises ValueError when the argument value is of invalid type.
|
|
||||||
|
|
||||||
Returns a tuple.
|
|
||||||
"""
|
|
||||||
if isinstance(value, datetime.datetime):
|
|
||||||
field_type = FieldType.DATETIME
|
|
||||||
elif isinstance(value, datetime.date):
|
|
||||||
field_type = FieldType.DATE
|
|
||||||
else:
|
|
||||||
raise ValueError(
|
|
||||||
"Argument must a datetime.datetime or datetime.date")
|
|
||||||
|
|
||||||
packed = (utils.int2store(value.year) +
|
|
||||||
utils.int1store(value.month) +
|
|
||||||
utils.int1store(value.day))
|
|
||||||
|
|
||||||
if isinstance(value, datetime.datetime):
|
|
||||||
packed = (packed + utils.int1store(value.hour) +
|
|
||||||
utils.int1store(value.minute) +
|
|
||||||
utils.int1store(value.second))
|
|
||||||
if value.microsecond > 0:
|
|
||||||
packed += utils.int4store(value.microsecond)
|
|
||||||
|
|
||||||
packed = utils.int1store(len(packed)) + packed
|
|
||||||
return (packed, field_type)
|
|
||||||
|
|
||||||
def _prepare_binary_time(self, value):
|
|
||||||
"""Prepare a time object for the MySQL binary protocol
|
|
||||||
|
|
||||||
This method prepares a time object of type datetime.timedelta or
|
|
||||||
datetime.time for sending over the MySQL binary protocol.
|
|
||||||
A tuple is returned with the prepared value and field type
|
|
||||||
as elements.
|
|
||||||
|
|
||||||
Raises ValueError when the argument value is of invalid type.
|
|
||||||
|
|
||||||
Returns a tuple.
|
|
||||||
"""
|
|
||||||
if not isinstance(value, (datetime.timedelta, datetime.time)):
|
|
||||||
raise ValueError(
|
|
||||||
"Argument must a datetime.timedelta or datetime.time")
|
|
||||||
|
|
||||||
field_type = FieldType.TIME
|
|
||||||
negative = 0
|
|
||||||
mcs = None
|
|
||||||
packed = b''
|
|
||||||
|
|
||||||
if isinstance(value, datetime.timedelta):
|
|
||||||
if value.days < 0:
|
|
||||||
negative = 1
|
|
||||||
(hours, remainder) = divmod(value.seconds, 3600)
|
|
||||||
(mins, secs) = divmod(remainder, 60)
|
|
||||||
packed += (utils.int4store(abs(value.days)) +
|
|
||||||
utils.int1store(hours) +
|
|
||||||
utils.int1store(mins) +
|
|
||||||
utils.int1store(secs))
|
|
||||||
mcs = value.microseconds
|
|
||||||
else:
|
|
||||||
packed += (utils.int4store(0) +
|
|
||||||
utils.int1store(value.hour) +
|
|
||||||
utils.int1store(value.minute) +
|
|
||||||
utils.int1store(value.second))
|
|
||||||
mcs = value.microsecond
|
|
||||||
if mcs:
|
|
||||||
packed += utils.int4store(mcs)
|
|
||||||
|
|
||||||
packed = utils.int1store(negative) + packed
|
|
||||||
packed = utils.int1store(len(packed)) + packed
|
|
||||||
|
|
||||||
return (packed, field_type)
|
|
||||||
|
|
||||||
def _prepare_stmt_send_long_data(self, statement, param, data):
|
|
||||||
"""Prepare long data for prepared statements
|
|
||||||
|
|
||||||
Returns a string.
|
|
||||||
"""
|
|
||||||
packet = (
|
|
||||||
utils.int4store(statement) +
|
|
||||||
utils.int2store(param) +
|
|
||||||
data)
|
|
||||||
return packet
|
|
||||||
|
|
||||||
def make_stmt_execute(self, statement_id, data=(), parameters=(),
|
|
||||||
flags=0, long_data_used=None, charset='utf8'):
|
|
||||||
"""Make a MySQL packet with the Statement Execute command"""
|
|
||||||
iteration_count = 1
|
|
||||||
null_bitmap = [0] * ((len(data) + 7) // 8)
|
|
||||||
values = []
|
|
||||||
types = []
|
|
||||||
packed = b''
|
|
||||||
if charset == 'utf8mb4':
|
|
||||||
charset = 'utf8'
|
|
||||||
if long_data_used is None:
|
|
||||||
long_data_used = {}
|
|
||||||
if parameters and data:
|
|
||||||
if len(data) != len(parameters):
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
"Failed executing prepared statement: data values does not"
|
|
||||||
" match number of parameters")
|
|
||||||
for pos, _ in enumerate(parameters):
|
|
||||||
value = data[pos]
|
|
||||||
flags = 0
|
|
||||||
if value is None:
|
|
||||||
null_bitmap[(pos // 8)] |= 1 << (pos % 8)
|
|
||||||
types.append(utils.int1store(FieldType.NULL) +
|
|
||||||
utils.int1store(flags))
|
|
||||||
continue
|
|
||||||
elif pos in long_data_used:
|
|
||||||
if long_data_used[pos][0]:
|
|
||||||
# We suppose binary data
|
|
||||||
field_type = FieldType.BLOB
|
|
||||||
else:
|
|
||||||
# We suppose text data
|
|
||||||
field_type = FieldType.STRING
|
|
||||||
elif isinstance(value, int):
|
|
||||||
(packed, field_type,
|
|
||||||
flags) = self._prepare_binary_integer(value)
|
|
||||||
values.append(packed)
|
|
||||||
elif isinstance(value, str):
|
|
||||||
if PY2:
|
|
||||||
values.append(utils.lc_int(len(value)) +
|
|
||||||
value)
|
|
||||||
else:
|
|
||||||
value = value.encode(charset)
|
|
||||||
values.append(
|
|
||||||
utils.lc_int(len(value)) + value)
|
|
||||||
field_type = FieldType.VARCHAR
|
|
||||||
elif isinstance(value, bytes):
|
|
||||||
values.append(utils.lc_int(len(value)) + value)
|
|
||||||
field_type = FieldType.BLOB
|
|
||||||
elif PY2 and \
|
|
||||||
isinstance(value, unicode): # pylint: disable=E0602
|
|
||||||
value = value.encode(charset)
|
|
||||||
values.append(utils.lc_int(len(value)) + value)
|
|
||||||
field_type = FieldType.VARCHAR
|
|
||||||
elif isinstance(value, Decimal):
|
|
||||||
values.append(
|
|
||||||
utils.lc_int(len(str(value).encode(
|
|
||||||
charset))) + str(value).encode(charset))
|
|
||||||
field_type = FieldType.DECIMAL
|
|
||||||
elif isinstance(value, float):
|
|
||||||
values.append(struct.pack('<d', value))
|
|
||||||
field_type = FieldType.DOUBLE
|
|
||||||
elif isinstance(value, (datetime.datetime, datetime.date)):
|
|
||||||
(packed, field_type) = self._prepare_binary_timestamp(
|
|
||||||
value)
|
|
||||||
values.append(packed)
|
|
||||||
elif isinstance(value, (datetime.timedelta, datetime.time)):
|
|
||||||
(packed, field_type) = self._prepare_binary_time(value)
|
|
||||||
values.append(packed)
|
|
||||||
else:
|
|
||||||
raise errors.ProgrammingError(
|
|
||||||
"MySQL binary protocol can not handle "
|
|
||||||
"'{classname}' objects".format(
|
|
||||||
classname=value.__class__.__name__))
|
|
||||||
types.append(utils.int1store(field_type) +
|
|
||||||
utils.int1store(flags))
|
|
||||||
|
|
||||||
packet = (
|
|
||||||
utils.int4store(statement_id) +
|
|
||||||
utils.int1store(flags) +
|
|
||||||
utils.int4store(iteration_count) +
|
|
||||||
b''.join([struct.pack('B', bit) for bit in null_bitmap]) +
|
|
||||||
utils.int1store(1)
|
|
||||||
)
|
|
||||||
|
|
||||||
for a_type in types:
|
|
||||||
packet += a_type
|
|
||||||
|
|
||||||
for a_value in values:
|
|
||||||
packet += a_value
|
|
||||||
|
|
||||||
return packet
|
|
||||||
|
|
||||||
def parse_auth_switch_request(self, packet):
|
|
||||||
"""Parse a MySQL AuthSwitchRequest-packet"""
|
|
||||||
if not packet[4] == 254:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
"Failed parsing AuthSwitchRequest packet")
|
|
||||||
|
|
||||||
(packet, plugin_name) = utils.read_string(packet[5:], end=b'\x00')
|
|
||||||
if packet and packet[-1] == 0:
|
|
||||||
packet = packet[:-1]
|
|
||||||
|
|
||||||
return plugin_name.decode('utf8'), packet
|
|
||||||
|
|
||||||
def parse_auth_more_data(self, packet):
|
|
||||||
"""Parse a MySQL AuthMoreData-packet"""
|
|
||||||
if not packet[4] == 1:
|
|
||||||
raise errors.InterfaceError(
|
|
||||||
"Failed parsing AuthMoreData packet")
|
|
||||||
|
|
||||||
return packet[5:]
|
|
@ -1,443 +0,0 @@
|
|||||||
# Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Utilities
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import subprocess
|
|
||||||
import struct
|
|
||||||
import sys
|
|
||||||
|
|
||||||
from .catch23 import struct_unpack, PY2
|
|
||||||
|
|
||||||
|
|
||||||
__MYSQL_DEBUG__ = False
|
|
||||||
|
|
||||||
|
|
||||||
def intread(buf):
|
|
||||||
"""Unpacks the given buffer to an integer"""
|
|
||||||
try:
|
|
||||||
if isinstance(buf, int):
|
|
||||||
return buf
|
|
||||||
length = len(buf)
|
|
||||||
if length == 1:
|
|
||||||
return buf[0]
|
|
||||||
elif length <= 4:
|
|
||||||
tmp = buf + b'\x00'*(4-length)
|
|
||||||
return struct_unpack('<I', tmp)[0]
|
|
||||||
tmp = buf + b'\x00'*(8-length)
|
|
||||||
return struct_unpack('<Q', tmp)[0]
|
|
||||||
except:
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def int1store(i):
|
|
||||||
"""
|
|
||||||
Takes an unsigned byte (1 byte) and packs it as a bytes-object.
|
|
||||||
|
|
||||||
Returns string.
|
|
||||||
"""
|
|
||||||
if i < 0 or i > 255:
|
|
||||||
raise ValueError('int1store requires 0 <= i <= 255')
|
|
||||||
else:
|
|
||||||
return bytearray(struct.pack('<B', i))
|
|
||||||
|
|
||||||
|
|
||||||
def int2store(i):
|
|
||||||
"""
|
|
||||||
Takes an unsigned short (2 bytes) and packs it as a bytes-object.
|
|
||||||
|
|
||||||
Returns string.
|
|
||||||
"""
|
|
||||||
if i < 0 or i > 65535:
|
|
||||||
raise ValueError('int2store requires 0 <= i <= 65535')
|
|
||||||
else:
|
|
||||||
return bytearray(struct.pack('<H', i))
|
|
||||||
|
|
||||||
|
|
||||||
def int3store(i):
|
|
||||||
"""
|
|
||||||
Takes an unsigned integer (3 bytes) and packs it as a bytes-object.
|
|
||||||
|
|
||||||
Returns string.
|
|
||||||
"""
|
|
||||||
if i < 0 or i > 16777215:
|
|
||||||
raise ValueError('int3store requires 0 <= i <= 16777215')
|
|
||||||
else:
|
|
||||||
return bytearray(struct.pack('<I', i)[0:3])
|
|
||||||
|
|
||||||
|
|
||||||
def int4store(i):
|
|
||||||
"""
|
|
||||||
Takes an unsigned integer (4 bytes) and packs it as a bytes-object.
|
|
||||||
|
|
||||||
Returns string.
|
|
||||||
"""
|
|
||||||
if i < 0 or i > 4294967295:
|
|
||||||
raise ValueError('int4store requires 0 <= i <= 4294967295')
|
|
||||||
else:
|
|
||||||
return bytearray(struct.pack('<I', i))
|
|
||||||
|
|
||||||
|
|
||||||
def int8store(i):
|
|
||||||
"""
|
|
||||||
Takes an unsigned integer (8 bytes) and packs it as string.
|
|
||||||
|
|
||||||
Returns string.
|
|
||||||
"""
|
|
||||||
if i < 0 or i > 18446744073709551616:
|
|
||||||
raise ValueError('int8store requires 0 <= i <= 2^64')
|
|
||||||
else:
|
|
||||||
return bytearray(struct.pack('<Q', i))
|
|
||||||
|
|
||||||
|
|
||||||
def intstore(i):
|
|
||||||
"""
|
|
||||||
Takes an unsigned integers and packs it as a bytes-object.
|
|
||||||
|
|
||||||
This function uses int1store, int2store, int3store,
|
|
||||||
int4store or int8store depending on the integer value.
|
|
||||||
|
|
||||||
returns string.
|
|
||||||
"""
|
|
||||||
if i < 0 or i > 18446744073709551616:
|
|
||||||
raise ValueError('intstore requires 0 <= i <= 2^64')
|
|
||||||
|
|
||||||
if i <= 255:
|
|
||||||
formed_string = int1store
|
|
||||||
elif i <= 65535:
|
|
||||||
formed_string = int2store
|
|
||||||
elif i <= 16777215:
|
|
||||||
formed_string = int3store
|
|
||||||
elif i <= 4294967295:
|
|
||||||
formed_string = int4store
|
|
||||||
else:
|
|
||||||
formed_string = int8store
|
|
||||||
|
|
||||||
return formed_string(i)
|
|
||||||
|
|
||||||
|
|
||||||
def lc_int(i):
|
|
||||||
"""
|
|
||||||
Takes an unsigned integer and packs it as bytes,
|
|
||||||
with the information of how much bytes the encoded int takes.
|
|
||||||
"""
|
|
||||||
if i < 0 or i > 18446744073709551616:
|
|
||||||
raise ValueError('Requires 0 <= i <= 2^64')
|
|
||||||
|
|
||||||
if i < 251:
|
|
||||||
return bytearray(struct.pack('<B', i))
|
|
||||||
elif i <= 65535:
|
|
||||||
return b'\xfc' + bytearray(struct.pack('<H', i))
|
|
||||||
elif i <= 16777215:
|
|
||||||
return b'\xfd' + bytearray(struct.pack('<I', i)[0:3])
|
|
||||||
|
|
||||||
return b'\xfe' + bytearray(struct.pack('<Q', i))
|
|
||||||
|
|
||||||
|
|
||||||
def read_bytes(buf, size):
|
|
||||||
"""
|
|
||||||
Reads bytes from a buffer.
|
|
||||||
|
|
||||||
Returns a tuple with buffer less the read bytes, and the bytes.
|
|
||||||
"""
|
|
||||||
res = buf[0:size]
|
|
||||||
return (buf[size:], res)
|
|
||||||
|
|
||||||
|
|
||||||
def read_lc_string(buf):
|
|
||||||
"""
|
|
||||||
Takes a buffer and reads a length coded string from the start.
|
|
||||||
|
|
||||||
This is how Length coded strings work
|
|
||||||
|
|
||||||
If the string is 250 bytes long or smaller, then it looks like this:
|
|
||||||
|
|
||||||
<-- 1b -->
|
|
||||||
+----------+-------------------------
|
|
||||||
| length | a string goes here
|
|
||||||
+----------+-------------------------
|
|
||||||
|
|
||||||
If the string is bigger than 250, then it looks like this:
|
|
||||||
|
|
||||||
<- 1b -><- 2/3/8 ->
|
|
||||||
+------+-----------+-------------------------
|
|
||||||
| type | length | a string goes here
|
|
||||||
+------+-----------+-------------------------
|
|
||||||
|
|
||||||
if type == \xfc:
|
|
||||||
length is code in next 2 bytes
|
|
||||||
elif type == \xfd:
|
|
||||||
length is code in next 3 bytes
|
|
||||||
elif type == \xfe:
|
|
||||||
length is code in next 8 bytes
|
|
||||||
|
|
||||||
NULL has a special value. If the buffer starts with \xfb then
|
|
||||||
it's a NULL and we return None as value.
|
|
||||||
|
|
||||||
Returns a tuple (trucated buffer, bytes).
|
|
||||||
"""
|
|
||||||
if buf[0] == 251: # \xfb
|
|
||||||
# NULL value
|
|
||||||
return (buf[1:], None)
|
|
||||||
|
|
||||||
length = lsize = 0
|
|
||||||
fst = buf[0]
|
|
||||||
|
|
||||||
if fst <= 250: # \xFA
|
|
||||||
length = fst
|
|
||||||
return (buf[1 + length:], buf[1:length + 1])
|
|
||||||
elif fst == 252:
|
|
||||||
lsize = 2
|
|
||||||
elif fst == 253:
|
|
||||||
lsize = 3
|
|
||||||
if fst == 254:
|
|
||||||
lsize = 8
|
|
||||||
|
|
||||||
length = intread(buf[1:lsize + 1])
|
|
||||||
return (buf[lsize + length + 1:], buf[lsize + 1:length + lsize + 1])
|
|
||||||
|
|
||||||
|
|
||||||
def read_lc_string_list(buf):
|
|
||||||
"""Reads all length encoded strings from the given buffer
|
|
||||||
|
|
||||||
Returns a list of bytes
|
|
||||||
"""
|
|
||||||
byteslst = []
|
|
||||||
|
|
||||||
sizes = {252: 2, 253: 3, 254: 8}
|
|
||||||
|
|
||||||
buf_len = len(buf)
|
|
||||||
pos = 0
|
|
||||||
|
|
||||||
while pos < buf_len:
|
|
||||||
first = buf[pos]
|
|
||||||
if first == 255:
|
|
||||||
# Special case when MySQL error 1317 is returned by MySQL.
|
|
||||||
# We simply return None.
|
|
||||||
return None
|
|
||||||
if first == 251:
|
|
||||||
# NULL value
|
|
||||||
byteslst.append(None)
|
|
||||||
pos += 1
|
|
||||||
else:
|
|
||||||
if first <= 250:
|
|
||||||
length = first
|
|
||||||
byteslst.append(buf[(pos + 1):length + (pos + 1)])
|
|
||||||
pos += 1 + length
|
|
||||||
else:
|
|
||||||
lsize = 0
|
|
||||||
try:
|
|
||||||
lsize = sizes[first]
|
|
||||||
except KeyError:
|
|
||||||
return None
|
|
||||||
length = intread(buf[(pos + 1):lsize + (pos + 1)])
|
|
||||||
byteslst.append(
|
|
||||||
buf[pos + 1 + lsize:length + lsize + (pos + 1)])
|
|
||||||
pos += 1 + lsize + length
|
|
||||||
|
|
||||||
return tuple(byteslst)
|
|
||||||
|
|
||||||
|
|
||||||
def read_string(buf, end=None, size=None):
|
|
||||||
"""
|
|
||||||
Reads a string up until a character or for a given size.
|
|
||||||
|
|
||||||
Returns a tuple (trucated buffer, string).
|
|
||||||
"""
|
|
||||||
if end is None and size is None:
|
|
||||||
raise ValueError('read_string() needs either end or size')
|
|
||||||
|
|
||||||
if end is not None:
|
|
||||||
try:
|
|
||||||
idx = buf.index(end)
|
|
||||||
except ValueError:
|
|
||||||
raise ValueError("end byte not present in buffer")
|
|
||||||
return (buf[idx + 1:], buf[0:idx])
|
|
||||||
elif size is not None:
|
|
||||||
return read_bytes(buf, size)
|
|
||||||
|
|
||||||
raise ValueError('read_string() needs either end or size (weird)')
|
|
||||||
|
|
||||||
|
|
||||||
def read_int(buf, size):
|
|
||||||
"""Read an integer from buffer
|
|
||||||
|
|
||||||
Returns a tuple (truncated buffer, int)
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
res = intread(buf[0:size])
|
|
||||||
except:
|
|
||||||
raise
|
|
||||||
|
|
||||||
return (buf[size:], res)
|
|
||||||
|
|
||||||
|
|
||||||
def read_lc_int(buf):
|
|
||||||
"""
|
|
||||||
Takes a buffer and reads an length code string from the start.
|
|
||||||
|
|
||||||
Returns a tuple with buffer less the integer and the integer read.
|
|
||||||
"""
|
|
||||||
if not buf:
|
|
||||||
raise ValueError("Empty buffer.")
|
|
||||||
|
|
||||||
lcbyte = buf[0]
|
|
||||||
if lcbyte == 251:
|
|
||||||
return (buf[1:], None)
|
|
||||||
elif lcbyte < 251:
|
|
||||||
return (buf[1:], int(lcbyte))
|
|
||||||
elif lcbyte == 252:
|
|
||||||
return (buf[3:], struct_unpack('<xH', buf[0:3])[0])
|
|
||||||
elif lcbyte == 253:
|
|
||||||
return (buf[4:], struct_unpack('<I', buf[1:4] + b'\x00')[0])
|
|
||||||
elif lcbyte == 254:
|
|
||||||
return (buf[9:], struct_unpack('<xQ', buf[0:9])[0])
|
|
||||||
else:
|
|
||||||
raise ValueError("Failed reading length encoded integer")
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# For debugging
|
|
||||||
#
|
|
||||||
def _digest_buffer(buf):
|
|
||||||
"""Debug function for showing buffers"""
|
|
||||||
if not isinstance(buf, str):
|
|
||||||
return ''.join(["\\x%02x" % c for c in buf])
|
|
||||||
return ''.join(["\\x%02x" % ord(c) for c in buf])
|
|
||||||
|
|
||||||
|
|
||||||
def print_buffer(abuffer, prefix=None, limit=30):
|
|
||||||
"""Debug function printing output of _digest_buffer()"""
|
|
||||||
if prefix:
|
|
||||||
if limit and limit > 0:
|
|
||||||
digest = _digest_buffer(abuffer[0:limit])
|
|
||||||
else:
|
|
||||||
digest = _digest_buffer(abuffer)
|
|
||||||
print(prefix + ': ' + digest)
|
|
||||||
else:
|
|
||||||
print(_digest_buffer(abuffer))
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_os_release():
|
|
||||||
"""Parse the contents of /etc/os-release file.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A dictionary containing release information.
|
|
||||||
"""
|
|
||||||
distro = {}
|
|
||||||
os_release_file = os.path.join("/etc", "os-release")
|
|
||||||
if not os.path.exists(os_release_file):
|
|
||||||
return distro
|
|
||||||
with open(os_release_file) as file_obj:
|
|
||||||
for line in file_obj:
|
|
||||||
key_value = line.split("=")
|
|
||||||
if len(key_value) != 2:
|
|
||||||
continue
|
|
||||||
key = key_value[0].lower()
|
|
||||||
value = key_value[1].rstrip("\n").strip('"')
|
|
||||||
distro[key] = value
|
|
||||||
return distro
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_lsb_release():
|
|
||||||
"""Parse the contents of /etc/lsb-release file.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A dictionary containing release information.
|
|
||||||
"""
|
|
||||||
distro = {}
|
|
||||||
lsb_release_file = os.path.join("/etc", "lsb-release")
|
|
||||||
if os.path.exists(lsb_release_file):
|
|
||||||
with open(lsb_release_file) as file_obj:
|
|
||||||
for line in file_obj:
|
|
||||||
key_value = line.split("=")
|
|
||||||
if len(key_value) != 2:
|
|
||||||
continue
|
|
||||||
key = key_value[0].lower()
|
|
||||||
value = key_value[1].rstrip("\n").strip('"')
|
|
||||||
distro[key] = value
|
|
||||||
return distro
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_lsb_release_command():
|
|
||||||
"""Parse the output of the lsb_release command.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A dictionary containing release information.
|
|
||||||
"""
|
|
||||||
distro = {}
|
|
||||||
with open(os.devnull, "w") as devnull:
|
|
||||||
try:
|
|
||||||
stdout = subprocess.check_output(
|
|
||||||
("lsb_release", "-a"), stderr=devnull)
|
|
||||||
except OSError:
|
|
||||||
return None
|
|
||||||
lines = stdout.decode(sys.getfilesystemencoding()).splitlines()
|
|
||||||
for line in lines:
|
|
||||||
key_value = line.split(":")
|
|
||||||
if len(key_value) != 2:
|
|
||||||
continue
|
|
||||||
key = key_value[0].replace(" ", "_").lower()
|
|
||||||
value = key_value[1].strip("\t")
|
|
||||||
distro[key] = value.encode("utf-8") if PY2 else value
|
|
||||||
return distro
|
|
||||||
|
|
||||||
|
|
||||||
def linux_distribution():
|
|
||||||
"""Tries to determine the name of the Linux OS distribution name.
|
|
||||||
|
|
||||||
First tries to get information from ``/etc/os-release`` file.
|
|
||||||
If fails, tries to get the information of ``/etc/lsb-release`` file.
|
|
||||||
And finally the information of ``lsb-release`` command.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A tuple with (`name`, `version`, `codename`)
|
|
||||||
"""
|
|
||||||
distro = _parse_lsb_release()
|
|
||||||
if distro:
|
|
||||||
return (distro.get("distrib_id", ""),
|
|
||||||
distro.get("distrib_release", ""),
|
|
||||||
distro.get("distrib_codename", ""))
|
|
||||||
|
|
||||||
if not PY2:
|
|
||||||
distro = _parse_lsb_release_command()
|
|
||||||
if distro:
|
|
||||||
return (distro.get("distributor_id", ""),
|
|
||||||
distro.get("release", ""),
|
|
||||||
distro.get("codename", ""))
|
|
||||||
|
|
||||||
distro = _parse_os_release()
|
|
||||||
if distro:
|
|
||||||
return (distro.get("name", ""),
|
|
||||||
distro.get("version_id", ""),
|
|
||||||
distro.get("version_codename", ""))
|
|
||||||
|
|
||||||
return ("", "", "")
|
|
@ -1,44 +0,0 @@
|
|||||||
# Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""MySQL Connector/Python version information
|
|
||||||
|
|
||||||
The file version.py gets installed and is available after installation
|
|
||||||
as mysql.connector.version.
|
|
||||||
"""
|
|
||||||
|
|
||||||
VERSION = (8, 0, 20, '', 1)
|
|
||||||
|
|
||||||
if VERSION[3] and VERSION[4]:
|
|
||||||
VERSION_TEXT = '{0}.{1}.{2}{3}{4}'.format(*VERSION)
|
|
||||||
else:
|
|
||||||
VERSION_TEXT = '{0}.{1}.{2}'.format(*VERSION[0:3])
|
|
||||||
|
|
||||||
VERSION_EXTRA = ''
|
|
||||||
LICENSE = 'GPLv2 with FOSS License Exception'
|
|
||||||
EDITION = '' # Added in package names, after the version
|
|
@ -1,5 +0,0 @@
|
|||||||
|
|
||||||
MySQL driver written in Python which does not depend on MySQL C client
|
|
||||||
libraries and implements the DB API v2.0 specification (PEP-249).
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
pip
|
|
@ -1,39 +0,0 @@
|
|||||||
Metadata-Version: 2.0
|
|
||||||
Name: mysql-connector-python
|
|
||||||
Version: 8.0.20
|
|
||||||
Summary: MySQL driver written in Python
|
|
||||||
Home-page: http://dev.mysql.com/doc/connector-python/en/index.html
|
|
||||||
Author: Oracle and/or its affiliates
|
|
||||||
Author-email: UNKNOWN
|
|
||||||
License: GNU GPLv2 (with FOSS License Exception)
|
|
||||||
Download-URL: http://dev.mysql.com/downloads/connector/python/
|
|
||||||
Keywords: mysql db
|
|
||||||
Platform: UNKNOWN
|
|
||||||
Classifier: Development Status :: 5 - Production/Stable
|
|
||||||
Classifier: Environment :: Other Environment
|
|
||||||
Classifier: Intended Audience :: Developers
|
|
||||||
Classifier: Intended Audience :: Education
|
|
||||||
Classifier: Intended Audience :: Information Technology
|
|
||||||
Classifier: Intended Audience :: System Administrators
|
|
||||||
Classifier: License :: OSI Approved :: GNU General Public License (GPL)
|
|
||||||
Classifier: Operating System :: OS Independent
|
|
||||||
Classifier: Programming Language :: Python :: 2.7
|
|
||||||
Classifier: Programming Language :: Python :: 3
|
|
||||||
Classifier: Programming Language :: Python :: 3.4
|
|
||||||
Classifier: Programming Language :: Python :: 3.5
|
|
||||||
Classifier: Programming Language :: Python :: 3.6
|
|
||||||
Classifier: Programming Language :: Python :: 3.7
|
|
||||||
Classifier: Programming Language :: Python :: 3.8
|
|
||||||
Classifier: Topic :: Database
|
|
||||||
Classifier: Topic :: Software Development
|
|
||||||
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
||||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
||||||
Requires-Dist: protobuf (>=3.0.0)
|
|
||||||
Provides-Extra: dns-srv
|
|
||||||
Requires-Dist: dnspython (>=1.16.0); extra == 'dns-srv'
|
|
||||||
|
|
||||||
|
|
||||||
MySQL driver written in Python which does not depend on MySQL C client
|
|
||||||
libraries and implements the DB API v2.0 specification (PEP-249).
|
|
||||||
|
|
||||||
|
|
@ -1,144 +0,0 @@
|
|||||||
_mysql_connector.cp36-win_amd64.pyd,sha256=_x0K06MChy1ItNaXk1HSNy6SxXiy6svhlcSHl4v76nc,54784
|
|
||||||
_mysqlxpb.cp36-win_amd64.pyd,sha256=MK_cq1nVLCnSKr51xwI6UQqlQfD-dGx-aQnRABqBcaE,1373184
|
|
||||||
libcrypto-1_1-x64.dll,sha256=YOcwgdJItW7uYyj1IGmry1CwZAuzhoevjP0xLk4yxsA,3384320
|
|
||||||
libmysql.dll,sha256=Kbaosg4XYXEzOnvo9IU2bAmgGOtAyFufmRTiDZfJfaE,6803456
|
|
||||||
libssl-1_1-x64.dll,sha256=7MpG3q8W0lyjhnt9uDTF37OlAFFc0-gKIBfttGTXJAA,679424
|
|
||||||
mysql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
||||||
mysql/__pycache__/__init__.cpython-36.pyc,,
|
|
||||||
mysql/connector/__init__.py,sha256=c2jSvxQQpfu5CmNKZVJMrmnMzHO0l1ErcRisxQ-37-0,10904
|
|
||||||
mysql/connector/__pycache__/__init__.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/abstracts.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/authentication.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/catch23.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/charsets.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/connection.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/connection_cext.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/constants.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/conversion.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/cursor.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/cursor_cext.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/custom_types.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/dbapi.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/errorcode.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/errors.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/network.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/optionfiles.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/pooling.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/protocol.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/utils.cpython-36.pyc,,
|
|
||||||
mysql/connector/__pycache__/version.cpython-36.pyc,,
|
|
||||||
mysql/connector/abstracts.py,sha256=ZQpZUfX2TIL-H7FsRA-An5Ii4wROmrum7QloSmB3w-U,51050
|
|
||||||
mysql/connector/authentication.py,sha256=vI_gc_C58T8q_lH83odBeiP1Go4Z21TdFCHsaYV5AT0,9332
|
|
||||||
mysql/connector/catch23.py,sha256=K-MOHoU2qIV3DjCMbd0jeCl-ZOOaL9mTiQnOjF6pZ_E,3842
|
|
||||||
mysql/connector/charsets.py,sha256=gYthYrxbLW2CMzgEJHZscLUtoskR-RmmBDDTAMzvPGc,15499
|
|
||||||
mysql/connector/connection.py,sha256=VsF_zDtPsKKeMBpviAhTGr-QUeQXOA9Fo1IDr0v0OYk,43928
|
|
||||||
mysql/connector/connection_cext.py,sha256=ria2gsiR46z2sW2S0u3-JYMTXHjsoi8KSzRWysuPla0,25535
|
|
||||||
mysql/connector/constants.py,sha256=jkQXQRGh53t9TshdzZLenb6gyOI3yzx3_5fsMUB-04I,38595
|
|
||||||
mysql/connector/conversion.py,sha256=Rakosq89FTFWRQvu9N-y3iLM_w-smA54GK-dubI3nmE,23946
|
|
||||||
mysql/connector/cursor.py,sha256=xaUoFfsv8MNdKaUK5QCF1NLVpfNl4UWX5Zc7KvNpR1g,47107
|
|
||||||
mysql/connector/cursor_cext.py,sha256=6HJ2paOH1C61UrVcV36Bv5yFseaHq29VxnWKP7o4dw8,32605
|
|
||||||
mysql/connector/custom_types.py,sha256=loK__Wv4CzemP5XWrmrYnnWVck6aHMiFKxm3d5t4EUM,1956
|
|
||||||
mysql/connector/dbapi.py,sha256=SqfBKwNzR1wTbbQmFGRbPwGMimwO4Y8fTQpxWu_nLQg,2621
|
|
||||||
mysql/connector/django/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
||||||
mysql/connector/django/__pycache__/__init__.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/__pycache__/base.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/__pycache__/client.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/__pycache__/compiler.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/__pycache__/creation.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/__pycache__/features.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/__pycache__/introspection.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/__pycache__/operations.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/__pycache__/schema.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/__pycache__/validation.cpython-36.pyc,,
|
|
||||||
mysql/connector/django/base.py,sha256=_aTtKmhNTpGHSnh78UlDSfeVD_wiYCZyhCbmrLyxYtA,19945
|
|
||||||
mysql/connector/django/client.py,sha256=jCs7IrYLcS1I7D590iGakVCluw8G2-0HbkiMuRefphA,1789
|
|
||||||
mysql/connector/django/compiler.py,sha256=x3RQeYGmJxmHG8qG-Q9InpjpkI9T6LTOOetHKn75vSk,1320
|
|
||||||
mysql/connector/django/creation.py,sha256=5nOshpsfnH7DouXan5N9r52e35s5ojvSXeh3eYb3duA,3261
|
|
||||||
mysql/connector/django/features.py,sha256=nhi6ylYlnbpFeBMDziwch9139I4kuNBpoJUtsmJ8wEU,3994
|
|
||||||
mysql/connector/django/introspection.py,sha256=KCjYsolrK7ZjhXMR3bsoYdxZUq0QNcbTIRK1QD6dPrQ,10255
|
|
||||||
mysql/connector/django/operations.py,sha256=BOJWLU2eCwESax6nOZs-dK4Zt8iA3BP-bMyFUD16F4E,9162
|
|
||||||
mysql/connector/django/schema.py,sha256=G6WSqMufph-v9f4ITTIrYikuxZHZp-XQv_Hk79nooeg,3439
|
|
||||||
mysql/connector/django/validation.py,sha256=1tZiAmG4dyUPe_zc9KKDng7iDB7O0nTH4dXi4LnkUlI,1475
|
|
||||||
mysql/connector/errorcode.py,sha256=mfN2OEviYJTRZYUxTglYs-FfCySKnfBV5Mz2bD6m2nQ,162714
|
|
||||||
mysql/connector/errors.py,sha256=WioN1nzwt8Qk9la-SOR9CWWM6wsdf4i1xndGPLwfPp8,10454
|
|
||||||
mysql/connector/locales/__init__.py,sha256=H08wYvK1J2dfeJ-bBhFJh_w5LV2WAAl1FohCkXvL284,2721
|
|
||||||
mysql/connector/locales/__pycache__/__init__.cpython-36.pyc,,
|
|
||||||
mysql/connector/locales/eng/__init__.py,sha256=gdSd1bVd0dn4lcJxV3kOS9CimOfjmnybT_aUY31U4V8,1444
|
|
||||||
mysql/connector/locales/eng/__pycache__/__init__.cpython-36.pyc,,
|
|
||||||
mysql/connector/locales/eng/__pycache__/client_error.cpython-36.pyc,,
|
|
||||||
mysql/connector/locales/eng/client_error.py,sha256=2eCKiJTqYEojaVkTI8QCr_Gi4p8rYrz5y_D5yxVB3N4,6477
|
|
||||||
mysql/connector/network.py,sha256=nN8S8Byx7PoVZTye6ct0H21bEf95qgW2KOcWCRha--8,23281
|
|
||||||
mysql/connector/optionfiles.py,sha256=xoODByARjph6Rt9n0TYBI9f3juxQ-WQsaAodYVDLEEs,13373
|
|
||||||
mysql/connector/pooling.py,sha256=BLsR63EC8fiSagxTp-6K_TLaqwFXvygUXSAgcuHEQH8,12811
|
|
||||||
mysql/connector/protocol.py,sha256=6uYzn4Q38sY6qrvohSVh-zOiI2u_v1TUCpzRCH8MH9Y,29453
|
|
||||||
mysql/connector/utils.py,sha256=f5Afr64RxnP5KmPkb_XOW817INt77y2jEL-9O_HizHY,12447
|
|
||||||
mysql/connector/version.py,sha256=OE_rhFaCC9leZIeqJQDiQ0UmzdEqw9ON9PmOmxUo_3k,1872
|
|
||||||
mysql_connector_python-8.0.20.dist-info/DESCRIPTION.rst,sha256=CEUYu85-QAwzvjm7FPY9XbD-EvomP_xM6Jze03ijsUY,140
|
|
||||||
mysql_connector_python-8.0.20.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
|
||||||
mysql_connector_python-8.0.20.dist-info/METADATA,sha256=RLtXl-TB_qdl_cc0exSkPRXWHquKeB-xPxWrASIVtRg,1629
|
|
||||||
mysql_connector_python-8.0.20.dist-info/RECORD,,
|
|
||||||
mysql_connector_python-8.0.20.dist-info/WHEEL,sha256=3o6dJ54ci-MtRFdJCPkLCK5G-vO7QSv3lIQ-NrhglGk,106
|
|
||||||
mysql_connector_python-8.0.20.dist-info/metadata.json,sha256=MMASLLVONfwrXCEAiRY_4SjezsJpC-ybRKwqNyW75BU,1541
|
|
||||||
mysql_connector_python-8.0.20.dist-info/top_level.txt,sha256=ENfchIvxULFOQVHrVTCEURaZRfdXyBiO_V27EMhrbgY,40
|
|
||||||
mysqlx/__init__.py,sha256=dAyuH-LodxAhedHSitKijodQ05cbS46xxlGKD9aFO4k,30830
|
|
||||||
mysqlx/__pycache__/__init__.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/authentication.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/charsets.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/compat.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/connection.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/constants.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/crud.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/dbdoc.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/errorcode.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/errors.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/expr.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/helpers.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/protocol.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/result.cpython-36.pyc,,
|
|
||||||
mysqlx/__pycache__/statement.cpython-36.pyc,,
|
|
||||||
mysqlx/authentication.py,sha256=4V4Wm8rUDrLF3Qkkt1I8YGJ5YqPticXJLKoKyPeDAiQ,5739
|
|
||||||
mysqlx/charsets.py,sha256=8veRUPKYm-AaQDxU542kFdTCDuqX8myjlt9Z1TsVW3I,15499
|
|
||||||
mysqlx/compat.py,sha256=RuivbMYALSiZ4si4g0cBMM1rn8S6FeYjui0ubSmmltk,2929
|
|
||||||
mysqlx/connection.py,sha256=0xbeJlTDMq4v2P6NVLaHPYgWcTNi8ZXzyq14Cic-b58,81021
|
|
||||||
mysqlx/constants.py,sha256=TMVzgfcJa33qGcQ0XgPbA7ZRbAKQpU5h_kvEMXAdQIQ,15189
|
|
||||||
mysqlx/crud.py,sha256=30bIS06fpslFIsFpuj4QSsr7UPE2H4LBp1ocxfMJyBU,19886
|
|
||||||
mysqlx/dbdoc.py,sha256=682HZd4unre6Q0_ghvYyMNfyygTn10y9OJXLtGNCLEI,3838
|
|
||||||
mysqlx/errorcode.py,sha256=mfN2OEviYJTRZYUxTglYs-FfCySKnfBV5Mz2bD6m2nQ,162714
|
|
||||||
mysqlx/errors.py,sha256=8LSYwcgm37V6wHw69pYX-i9gmr2z9Z9L46dGzhDiSrs,9248
|
|
||||||
mysqlx/expr.py,sha256=pQuNG7HqXnKRNbPZZkLgNeDmPM_aGPPJ8o5rGnGHW_E,47598
|
|
||||||
mysqlx/helpers.py,sha256=PmIdVcfI4DqVJZ91OmMNpruxajdPGAMxmEDiSMnaoNM,6932
|
|
||||||
mysqlx/locales/__init__.py,sha256=1fK6KuOCErHt9QyuNg03DwEaKk4my8wguXL4bk5J2CI,2722
|
|
||||||
mysqlx/locales/__pycache__/__init__.cpython-36.pyc,,
|
|
||||||
mysqlx/locales/eng/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
||||||
mysqlx/locales/eng/__pycache__/__init__.cpython-36.pyc,,
|
|
||||||
mysqlx/locales/eng/__pycache__/client_error.cpython-36.pyc,,
|
|
||||||
mysqlx/locales/eng/client_error.py,sha256=2eCKiJTqYEojaVkTI8QCr_Gi4p8rYrz5y_D5yxVB3N4,6477
|
|
||||||
mysqlx/protobuf/__init__.py,sha256=juaXug0wYhcN5OWmjfwKe6M7WqYBt-Lbf6Fde2lgkaM,16857
|
|
||||||
mysqlx/protobuf/__pycache__/__init__.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_connection_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_crud_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_cursor_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_datatypes_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_expect_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_expr_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_notice_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_prepare_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_resultset_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_session_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/__pycache__/mysqlx_sql_pb2.cpython-36.pyc,,
|
|
||||||
mysqlx/protobuf/mysqlx_connection_pb2.py,sha256=AuYi4t8H03wMlKN7b5ipb-jod-AUKK0xKfGPeAk9qsY,6731
|
|
||||||
mysqlx/protobuf/mysqlx_crud_pb2.py,sha256=VY50m_5bcHsE793LhJyw0Da7v_rc8Utpuw2BdI0z-Iw,48783
|
|
||||||
mysqlx/protobuf/mysqlx_cursor_pb2.py,sha256=OSNw9NmLTEbd-3ZciFkr8hEfMdjg5X1_T5WV7Ci6IcI,7778
|
|
||||||
mysqlx/protobuf/mysqlx_datatypes_pb2.py,sha256=xEyGdw_MBmvFYyOuo7qs4TfIQbYR5Czxr9q4CT5op6o,16608
|
|
||||||
mysqlx/protobuf/mysqlx_expect_pb2.py,sha256=3fRkBT91-LsP6DVo_t4lZ6aOT1S9yUQWOXeAtk5TLdA,7743
|
|
||||||
mysqlx/protobuf/mysqlx_expr_pb2.py,sha256=s_UmqzAZRQYzb8VXaRm-pT3E_rTe1K8hi5y0-tlR_pk,21417
|
|
||||||
mysqlx/protobuf/mysqlx_notice_pb2.py,sha256=bWnEtMbSbUTFE9lvGh4VK4tPe_xD3KuRwOx4pzqB1Rw,16036
|
|
||||||
mysqlx/protobuf/mysqlx_pb2.py,sha256=WuKz6FjD60tvPz05AXb7yvshOFD8tIaZHH2UTa6LXTA,12973
|
|
||||||
mysqlx/protobuf/mysqlx_prepare_pb2.py,sha256=5w-H0FswTkUzNAJfdUqVm3LfInRJ59NS8wDlZyXWMVE,10834
|
|
||||||
mysqlx/protobuf/mysqlx_resultset_pb2.py,sha256=AMNZi7fLqaht1cISdDac-ZQgr9PWjDvKcYXChEnOLNw,14625
|
|
||||||
mysqlx/protobuf/mysqlx_session_pb2.py,sha256=u8NLII-SkqA0NK_QawB9SRa6qNs7ssqqVsxanBQCS0Y,7056
|
|
||||||
mysqlx/protobuf/mysqlx_sql_pb2.py,sha256=tEOt3AJfOKu98yrgxKKtI4ciwN10AuWEWGdeR-xJSdM,4193
|
|
||||||
mysqlx/protocol.py,sha256=_Vh8wy4T1cwSCvTwMBEHK568EX7kkJ6XC-gkRyHly2w,33694
|
|
||||||
mysqlx/result.py,sha256=4WTWX3HLW9KJylGYBj1JS1l1jyz0Zpnm-i7BayioSYY,31195
|
|
||||||
mysqlx/statement.py,sha256=Fsb_PdJc30mEBryI0vcsFQULWvZ5EkzYZ-ZAZutw9tw,46797
|
|
@ -1,5 +0,0 @@
|
|||||||
Wheel-Version: 1.0
|
|
||||||
Generator: bdist_wheel (0.30.0)
|
|
||||||
Root-Is-Purelib: false
|
|
||||||
Tag: cp36-cp36m-win_amd64
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
{"classifiers": ["Development Status :: 5 - Production/Stable", "Environment :: Other Environment", "Intended Audience :: Developers", "Intended Audience :: Education", "Intended Audience :: Information Technology", "Intended Audience :: System Administrators", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Topic :: Database", "Topic :: Software Development", "Topic :: Software Development :: Libraries :: Application Frameworks", "Topic :: Software Development :: Libraries :: Python Modules"], "download_url": "http://dev.mysql.com/downloads/connector/python/", "extensions": {"python.details": {"contacts": [{"name": "Oracle and/or its affiliates", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "http://dev.mysql.com/doc/connector-python/en/index.html"}}}, "extras": ["dns-srv"], "generator": "bdist_wheel (0.30.0)", "keywords": ["mysql", "db"], "license": "GNU GPLv2 (with FOSS License Exception)", "metadata_version": "2.0", "name": "mysql-connector-python", "run_requires": [{"extra": "dns-srv", "requires": ["dnspython (>=1.16.0)"]}, {"requires": ["protobuf (>=3.0.0)"]}], "summary": "MySQL driver written in Python", "version": "8.0.20"}
|
|
@ -1,4 +0,0 @@
|
|||||||
_mysql_connector
|
|
||||||
_mysqlxpb
|
|
||||||
mysql
|
|
||||||
mysqlx
|
|
@ -1,766 +0,0 @@
|
|||||||
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""MySQL X DevAPI Python implementation"""
|
|
||||||
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
import ssl
|
|
||||||
|
|
||||||
from . import constants
|
|
||||||
from .compat import (INT_TYPES, STRING_TYPES, JSONDecodeError, urlparse,
|
|
||||||
unquote, parse_qsl)
|
|
||||||
from .connection import Client, Session
|
|
||||||
from .constants import (Auth, LockContention, OPENSSL_CS_NAMES, SSLMode,
|
|
||||||
TLS_VERSIONS, TLS_CIPHER_SUITES)
|
|
||||||
from .crud import Schema, Collection, Table, View
|
|
||||||
from .dbdoc import DbDoc
|
|
||||||
# pylint: disable=W0622
|
|
||||||
from .errors import (Error, InterfaceError, DatabaseError, NotSupportedError,
|
|
||||||
DataError, IntegrityError, ProgrammingError,
|
|
||||||
OperationalError, InternalError, PoolError, TimeoutError)
|
|
||||||
from .result import (Column, Row, Result, BufferingResult, RowResult,
|
|
||||||
SqlResult, DocResult, ColumnType)
|
|
||||||
from .statement import (Statement, FilterableStatement, SqlStatement,
|
|
||||||
FindStatement, AddStatement, RemoveStatement,
|
|
||||||
ModifyStatement, SelectStatement, InsertStatement,
|
|
||||||
DeleteStatement, UpdateStatement,
|
|
||||||
CreateCollectionIndexStatement, Expr, ReadStatement,
|
|
||||||
WriteStatement)
|
|
||||||
|
|
||||||
from .expr import ExprParser as expr
|
|
||||||
|
|
||||||
_SPLIT_RE = re.compile(r",(?![^\(\)]*\))")
|
|
||||||
_PRIORITY_RE = re.compile(r"^\(address=(.+),priority=(\d+)\)$", re.VERBOSE)
|
|
||||||
_ROUTER_RE = re.compile(r"^\(address=(.+)[,]*\)$", re.VERBOSE)
|
|
||||||
_URI_SCHEME_RE = re.compile(r"^([a-zA-Z][a-zA-Z0-9+\-.]+)://(.*)")
|
|
||||||
_SSL_OPTS = ["ssl-cert", "ssl-ca", "ssl-key", "ssl-crl", "tls-versions",
|
|
||||||
"tls-ciphersuites"]
|
|
||||||
_SESS_OPTS = _SSL_OPTS + ["user", "password", "schema", "host", "port",
|
|
||||||
"routers", "socket", "ssl-mode", "auth", "use-pure",
|
|
||||||
"connect-timeout", "connection-attributes",
|
|
||||||
"dns-srv"]
|
|
||||||
|
|
||||||
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
|
||||||
|
|
||||||
DUPLICATED_IN_LIST_ERROR = (
|
|
||||||
"The '{list}' list must not contain repeated values, the value "
|
|
||||||
"'{value}' is duplicated.")
|
|
||||||
|
|
||||||
TLS_VERSION_ERROR = ("The given tls-version: '{}' is not recognized as a valid "
|
|
||||||
"TLS protocol version (should be one of {}).")
|
|
||||||
|
|
||||||
TLS_VER_NO_SUPPORTED = ("No supported TLS protocol version found in the "
|
|
||||||
"'tls-versions' list '{}'. ")
|
|
||||||
|
|
||||||
TLS_VERSIONS = ["TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"]
|
|
||||||
|
|
||||||
TLS_V1_3_SUPPORTED = False
|
|
||||||
if hasattr(ssl, "HAS_TLSv1_3") and ssl.HAS_TLSv1_3:
|
|
||||||
TLS_V1_3_SUPPORTED = True
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_address_list(path):
|
|
||||||
"""Parses a list of host, port pairs
|
|
||||||
|
|
||||||
Args:
|
|
||||||
path: String containing a list of routers or just router
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Returns a dict with parsed values of host, port and priority if
|
|
||||||
specified.
|
|
||||||
"""
|
|
||||||
path = path.replace(" ", "")
|
|
||||||
array = not("," not in path and path.count(":") > 1
|
|
||||||
and path.count("[") == 1) and path.startswith("[") \
|
|
||||||
and path.endswith("]")
|
|
||||||
|
|
||||||
routers = []
|
|
||||||
address_list = _SPLIT_RE.split(path[1:-1] if array else path)
|
|
||||||
priority_count = 0
|
|
||||||
for address in address_list:
|
|
||||||
router = {}
|
|
||||||
|
|
||||||
match = _PRIORITY_RE.match(address)
|
|
||||||
if match:
|
|
||||||
address = match.group(1)
|
|
||||||
router["priority"] = int(match.group(2))
|
|
||||||
priority_count += 1
|
|
||||||
else:
|
|
||||||
match = _ROUTER_RE.match(address)
|
|
||||||
if match:
|
|
||||||
address = match.group(1)
|
|
||||||
router["priority"] = 100
|
|
||||||
|
|
||||||
match = urlparse("//{0}".format(address))
|
|
||||||
if not match.hostname:
|
|
||||||
raise InterfaceError("Invalid address: {0}".format(address))
|
|
||||||
|
|
||||||
try:
|
|
||||||
router.update(host=match.hostname, port=match.port)
|
|
||||||
except ValueError as err:
|
|
||||||
raise ProgrammingError("Invalid URI: {0}".format(err), 4002)
|
|
||||||
|
|
||||||
routers.append(router)
|
|
||||||
|
|
||||||
if 0 < priority_count < len(address_list):
|
|
||||||
raise ProgrammingError("You must either assign no priority to any "
|
|
||||||
"of the routers or give a priority for "
|
|
||||||
"every router", 4000)
|
|
||||||
|
|
||||||
return {"routers": routers} if array else routers[0]
|
|
||||||
|
|
||||||
|
|
||||||
def _parse_connection_uri(uri):
|
|
||||||
"""Parses the connection string and returns a dictionary with the
|
|
||||||
connection settings.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
uri: mysqlx URI scheme to connect to a MySQL server/farm.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Returns a dict with parsed values of credentials and address of the
|
|
||||||
MySQL server/farm.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.InterfaceError`: If contains a duplicate option or
|
|
||||||
URI scheme is not valid.
|
|
||||||
"""
|
|
||||||
settings = {"schema": ""}
|
|
||||||
|
|
||||||
match = _URI_SCHEME_RE.match(uri)
|
|
||||||
scheme, uri = match.groups() if match else ("mysqlx", uri)
|
|
||||||
|
|
||||||
if scheme not in ("mysqlx", "mysqlx+srv"):
|
|
||||||
raise InterfaceError("Scheme '{0}' is not valid".format(scheme))
|
|
||||||
|
|
||||||
if scheme == "mysqlx+srv":
|
|
||||||
settings["dns-srv"] = True
|
|
||||||
|
|
||||||
userinfo, tmp = uri.partition("@")[::2]
|
|
||||||
host, query_str = tmp.partition("?")[::2]
|
|
||||||
|
|
||||||
pos = host.rfind("/")
|
|
||||||
if host[pos:].find(")") == -1 and pos > 0:
|
|
||||||
host, settings["schema"] = host.rsplit("/", 1)
|
|
||||||
host = host.strip("()")
|
|
||||||
|
|
||||||
if not host or not userinfo or ":" not in userinfo:
|
|
||||||
raise InterfaceError("Malformed URI '{0}'".format(uri))
|
|
||||||
user, password = userinfo.split(":", 1)
|
|
||||||
settings["user"], settings["password"] = unquote(user), unquote(password)
|
|
||||||
|
|
||||||
if host.startswith(("/", "..", ".")):
|
|
||||||
settings["socket"] = unquote(host)
|
|
||||||
elif host.startswith("\\."):
|
|
||||||
raise InterfaceError("Windows Pipe is not supported")
|
|
||||||
else:
|
|
||||||
settings.update(_parse_address_list(host))
|
|
||||||
|
|
||||||
invalid_options = ("user", "password", "dns-srv")
|
|
||||||
for key, val in parse_qsl(query_str, True):
|
|
||||||
opt = key.replace("_", "-").lower()
|
|
||||||
if opt in invalid_options:
|
|
||||||
raise InterfaceError("Invalid option: '{0}'".format(key))
|
|
||||||
if opt in settings:
|
|
||||||
raise InterfaceError("Duplicate option: '{0}'".format(key))
|
|
||||||
if opt in _SSL_OPTS:
|
|
||||||
settings[opt] = unquote(val.strip("()"))
|
|
||||||
else:
|
|
||||||
val_str = val.lower()
|
|
||||||
if val_str in ("1", "true"):
|
|
||||||
settings[opt] = True
|
|
||||||
elif val_str in ("0", "false"):
|
|
||||||
settings[opt] = False
|
|
||||||
else:
|
|
||||||
settings[opt] = val_str
|
|
||||||
return settings
|
|
||||||
|
|
||||||
|
|
||||||
def _validate_settings(settings):
|
|
||||||
"""Validates the settings to be passed to a Session object
|
|
||||||
the port values are converted to int if specified or set to 33060
|
|
||||||
otherwise. The priority values for each router is converted to int
|
|
||||||
if specified.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
settings: dict containing connection settings.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.InterfaceError`: On any configuration issue.
|
|
||||||
"""
|
|
||||||
invalid_opts = set(settings.keys()).difference(_SESS_OPTS)
|
|
||||||
if invalid_opts:
|
|
||||||
raise InterfaceError("Invalid option(s): '{0}'"
|
|
||||||
"".format("', '".join(invalid_opts)))
|
|
||||||
|
|
||||||
if "routers" in settings:
|
|
||||||
for router in settings["routers"]:
|
|
||||||
_validate_hosts(router, 33060)
|
|
||||||
elif "host" in settings:
|
|
||||||
_validate_hosts(settings)
|
|
||||||
|
|
||||||
if "ssl-mode" in settings:
|
|
||||||
try:
|
|
||||||
settings["ssl-mode"] = settings["ssl-mode"].lower()
|
|
||||||
SSLMode.index(settings["ssl-mode"])
|
|
||||||
except (AttributeError, ValueError):
|
|
||||||
raise InterfaceError("Invalid SSL Mode '{0}'"
|
|
||||||
"".format(settings["ssl-mode"]))
|
|
||||||
if settings["ssl-mode"] == SSLMode.DISABLED and \
|
|
||||||
any(key in settings for key in _SSL_OPTS):
|
|
||||||
raise InterfaceError("SSL options used with ssl-mode 'disabled'")
|
|
||||||
|
|
||||||
if "ssl-crl" in settings and not "ssl-ca" in settings:
|
|
||||||
raise InterfaceError("CA Certificate not provided")
|
|
||||||
if "ssl-key" in settings and not "ssl-cert" in settings:
|
|
||||||
raise InterfaceError("Client Certificate not provided")
|
|
||||||
|
|
||||||
if not "ssl-ca" in settings and settings.get("ssl-mode") \
|
|
||||||
in [SSLMode.VERIFY_IDENTITY, SSLMode.VERIFY_CA]:
|
|
||||||
raise InterfaceError("Cannot verify Server without CA")
|
|
||||||
if "ssl-ca" in settings and settings.get("ssl-mode") \
|
|
||||||
not in [SSLMode.VERIFY_IDENTITY, SSLMode.VERIFY_CA]:
|
|
||||||
raise InterfaceError("Must verify Server if CA is provided")
|
|
||||||
|
|
||||||
if "auth" in settings:
|
|
||||||
try:
|
|
||||||
settings["auth"] = settings["auth"].lower()
|
|
||||||
Auth.index(settings["auth"])
|
|
||||||
except (AttributeError, ValueError):
|
|
||||||
raise InterfaceError("Invalid Auth '{0}'".format(settings["auth"]))
|
|
||||||
|
|
||||||
if "connection-attributes" in settings:
|
|
||||||
validate_connection_attributes(settings)
|
|
||||||
|
|
||||||
if "connect-timeout" in settings:
|
|
||||||
try:
|
|
||||||
if isinstance(settings["connect-timeout"], STRING_TYPES):
|
|
||||||
settings["connect-timeout"] = int(settings["connect-timeout"])
|
|
||||||
if not isinstance(settings["connect-timeout"], INT_TYPES) \
|
|
||||||
or settings["connect-timeout"] < 0:
|
|
||||||
raise ValueError
|
|
||||||
except ValueError:
|
|
||||||
raise TypeError("The connection timeout value must be a positive "
|
|
||||||
"integer (including 0)")
|
|
||||||
|
|
||||||
if "dns-srv" in settings:
|
|
||||||
if not isinstance(settings["dns-srv"], bool):
|
|
||||||
raise InterfaceError("The value of 'dns-srv' must be a boolean")
|
|
||||||
if settings.get("socket"):
|
|
||||||
raise InterfaceError("Using Unix domain sockets with DNS SRV "
|
|
||||||
"lookup is not allowed")
|
|
||||||
if settings.get("port"):
|
|
||||||
raise InterfaceError("Specifying a port number with DNS SRV "
|
|
||||||
"lookup is not allowed")
|
|
||||||
if settings.get("routers"):
|
|
||||||
raise InterfaceError("Specifying multiple hostnames with DNS "
|
|
||||||
"SRV look up is not allowed")
|
|
||||||
elif "host" in settings and not settings.get("port"):
|
|
||||||
settings["port"] = 33060
|
|
||||||
|
|
||||||
if "tls-versions" in settings:
|
|
||||||
validate_tls_versions(settings)
|
|
||||||
|
|
||||||
if "tls-ciphersuites" in settings:
|
|
||||||
validate_tls_ciphersuites(settings)
|
|
||||||
|
|
||||||
|
|
||||||
def _validate_hosts(settings, default_port=None):
|
|
||||||
"""Validate hosts.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
settings (dict): Settings dictionary.
|
|
||||||
default_port (int): Default connection port.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.InterfaceError`: If priority or port are invalid.
|
|
||||||
"""
|
|
||||||
if "priority" in settings and settings["priority"]:
|
|
||||||
try:
|
|
||||||
settings["priority"] = int(settings["priority"])
|
|
||||||
if settings["priority"] < 0 or settings["priority"] > 100:
|
|
||||||
raise ProgrammingError("Invalid priority value, "
|
|
||||||
"must be between 0 and 100", 4007)
|
|
||||||
except NameError:
|
|
||||||
raise ProgrammingError("Invalid priority", 4007)
|
|
||||||
except ValueError:
|
|
||||||
raise ProgrammingError(
|
|
||||||
"Invalid priority: {}".format(settings["priority"]), 4007)
|
|
||||||
|
|
||||||
if "port" in settings and settings["port"]:
|
|
||||||
try:
|
|
||||||
settings["port"] = int(settings["port"])
|
|
||||||
except NameError:
|
|
||||||
raise InterfaceError("Invalid port")
|
|
||||||
elif "host" in settings and default_port:
|
|
||||||
settings["port"] = default_port
|
|
||||||
|
|
||||||
|
|
||||||
def validate_connection_attributes(settings):
|
|
||||||
"""Validate connection-attributes.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
settings (dict): Settings dictionary.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.InterfaceError`: If attribute name or value exceeds size.
|
|
||||||
"""
|
|
||||||
attributes = {}
|
|
||||||
if "connection-attributes" not in settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
conn_attrs = settings["connection-attributes"]
|
|
||||||
|
|
||||||
if isinstance(conn_attrs, STRING_TYPES):
|
|
||||||
if conn_attrs == "":
|
|
||||||
settings["connection-attributes"] = {}
|
|
||||||
return
|
|
||||||
if not (conn_attrs.startswith("[") and conn_attrs.endswith("]")) and \
|
|
||||||
not conn_attrs in ['False', "false", "True", "true"]:
|
|
||||||
raise InterfaceError("The value of 'connection-attributes' must "
|
|
||||||
"be a boolean or a list of key-value pairs, "
|
|
||||||
"found: '{}'".format(conn_attrs))
|
|
||||||
elif conn_attrs in ['False', "false", "True", "true"]:
|
|
||||||
if conn_attrs in ['False', "false"]:
|
|
||||||
settings["connection-attributes"] = False
|
|
||||||
else:
|
|
||||||
settings["connection-attributes"] = {}
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
conn_attributes = conn_attrs[1:-1].split(",")
|
|
||||||
for attr in conn_attributes:
|
|
||||||
if attr == "":
|
|
||||||
continue
|
|
||||||
attr_name_val = attr.split('=')
|
|
||||||
attr_name = attr_name_val[0]
|
|
||||||
attr_val = attr_name_val[1] if len(attr_name_val) > 1 else ""
|
|
||||||
if attr_name in attributes:
|
|
||||||
raise InterfaceError("Duplicate key '{}' used in "
|
|
||||||
"connection-attributes"
|
|
||||||
"".format(attr_name))
|
|
||||||
else:
|
|
||||||
attributes[attr_name] = attr_val
|
|
||||||
elif isinstance(conn_attrs, dict):
|
|
||||||
for attr_name in conn_attrs:
|
|
||||||
attr_value = conn_attrs[attr_name]
|
|
||||||
if not isinstance(attr_value, STRING_TYPES):
|
|
||||||
attr_value = repr(attr_value)
|
|
||||||
attributes[attr_name] = attr_value
|
|
||||||
elif isinstance(conn_attrs, bool) or conn_attrs in [0, 1]:
|
|
||||||
if conn_attrs:
|
|
||||||
settings["connection-attributes"] = {}
|
|
||||||
else:
|
|
||||||
settings["connection-attributes"] = False
|
|
||||||
return
|
|
||||||
elif isinstance(conn_attrs, set):
|
|
||||||
for attr_name in conn_attrs:
|
|
||||||
attributes[attr_name] = ""
|
|
||||||
elif isinstance(conn_attrs, list):
|
|
||||||
for attr in conn_attrs:
|
|
||||||
if attr == "":
|
|
||||||
continue
|
|
||||||
attr_name_val = attr.split('=')
|
|
||||||
attr_name = attr_name_val[0]
|
|
||||||
attr_val = attr_name_val[1] if len(attr_name_val) > 1 else ""
|
|
||||||
if attr_name in attributes:
|
|
||||||
raise InterfaceError("Duplicate key '{}' used in "
|
|
||||||
"connection-attributes"
|
|
||||||
"".format(attr_name))
|
|
||||||
else:
|
|
||||||
attributes[attr_name] = attr_val
|
|
||||||
elif not isinstance(conn_attrs, bool):
|
|
||||||
raise InterfaceError("connection-attributes must be Boolean or a list "
|
|
||||||
"of key-value pairs, found: '{}'"
|
|
||||||
"".format(conn_attrs))
|
|
||||||
|
|
||||||
if attributes:
|
|
||||||
for attr_name in attributes:
|
|
||||||
attr_value = attributes[attr_name]
|
|
||||||
|
|
||||||
# Validate name type
|
|
||||||
if not isinstance(attr_name, STRING_TYPES):
|
|
||||||
raise InterfaceError("Attribute name '{}' must be a string"
|
|
||||||
"type".format(attr_name))
|
|
||||||
# Validate attribute name limit 32 characters
|
|
||||||
if len(attr_name) > 32:
|
|
||||||
raise InterfaceError("Attribute name '{}' exceeds 32 "
|
|
||||||
"characters limit size".format(attr_name))
|
|
||||||
# Validate names in connection-attributes cannot start with "_"
|
|
||||||
if attr_name.startswith("_"):
|
|
||||||
raise InterfaceError("Key names in connection-attributes "
|
|
||||||
"cannot start with '_', found: '{}'"
|
|
||||||
"".format(attr_name))
|
|
||||||
|
|
||||||
# Validate value type
|
|
||||||
if not isinstance(attr_value, STRING_TYPES):
|
|
||||||
raise InterfaceError("Attribute '{}' value: '{}' must "
|
|
||||||
"be a string type"
|
|
||||||
"".format(attr_name, attr_value))
|
|
||||||
# Validate attribute value limit 1024 characters
|
|
||||||
if len(attr_value) > 1024:
|
|
||||||
raise InterfaceError("Attribute '{}' value: '{}' "
|
|
||||||
"exceeds 1024 characters limit size"
|
|
||||||
"".format(attr_name, attr_value))
|
|
||||||
|
|
||||||
settings["connection-attributes"] = attributes
|
|
||||||
|
|
||||||
|
|
||||||
def validate_tls_versions(settings):
|
|
||||||
"""Validate tls-versions.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
settings (dict): Settings dictionary.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.InterfaceError`: If tls-versions name is not valid.
|
|
||||||
"""
|
|
||||||
tls_versions = []
|
|
||||||
if "tls-versions" not in settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
tls_versions_settings = settings["tls-versions"]
|
|
||||||
|
|
||||||
if isinstance(tls_versions_settings, STRING_TYPES):
|
|
||||||
if not (tls_versions_settings.startswith("[") and
|
|
||||||
tls_versions_settings.endswith("]")):
|
|
||||||
raise InterfaceError("tls-versions must be a list, found: '{}'"
|
|
||||||
"".format(tls_versions_settings))
|
|
||||||
else:
|
|
||||||
tls_vers = tls_versions_settings[1:-1].split(",")
|
|
||||||
for tls_ver in tls_vers:
|
|
||||||
tls_version = tls_ver.strip()
|
|
||||||
if tls_version == "":
|
|
||||||
continue
|
|
||||||
if tls_version not in TLS_VERSIONS:
|
|
||||||
raise InterfaceError(TLS_VERSION_ERROR.format(tls_version,
|
|
||||||
TLS_VERSIONS))
|
|
||||||
else:
|
|
||||||
if tls_version in tls_versions:
|
|
||||||
raise InterfaceError(
|
|
||||||
DUPLICATED_IN_LIST_ERROR.format(
|
|
||||||
list="tls_versions", value=tls_version))
|
|
||||||
tls_versions.append(tls_version)
|
|
||||||
elif isinstance(tls_versions_settings, list):
|
|
||||||
if not tls_versions_settings:
|
|
||||||
raise InterfaceError("At least one TLS protocol version must be "
|
|
||||||
"specified in 'tls-versions' list.")
|
|
||||||
for tls_ver in tls_versions_settings:
|
|
||||||
if tls_ver not in TLS_VERSIONS:
|
|
||||||
raise InterfaceError(TLS_VERSION_ERROR.format(tls_ver,
|
|
||||||
TLS_VERSIONS))
|
|
||||||
elif tls_ver in tls_versions:
|
|
||||||
raise InterfaceError(
|
|
||||||
DUPLICATED_IN_LIST_ERROR.format(list="tls_versions",
|
|
||||||
value=tls_ver))
|
|
||||||
else:
|
|
||||||
tls_versions.append(tls_ver)
|
|
||||||
|
|
||||||
elif isinstance(tls_versions_settings, set):
|
|
||||||
for tls_ver in tls_versions_settings:
|
|
||||||
if tls_ver not in TLS_VERSIONS:
|
|
||||||
raise InterfaceError(TLS_VERSION_ERROR.format(tls_ver,
|
|
||||||
TLS_VERSIONS))
|
|
||||||
else:
|
|
||||||
tls_versions.append(tls_ver)
|
|
||||||
else:
|
|
||||||
raise InterfaceError("tls-versions should be a list with one or more "
|
|
||||||
"of versions in {}. found: '{}'"
|
|
||||||
"".format(", ".join(TLS_VERSIONS), tls_versions))
|
|
||||||
|
|
||||||
if not tls_versions:
|
|
||||||
raise InterfaceError("At least one TLS protocol version must be "
|
|
||||||
"specified in 'tls-versions' list.")
|
|
||||||
|
|
||||||
if tls_versions == ["TLSv1.3"] and not TLS_V1_3_SUPPORTED:
|
|
||||||
raise InterfaceError(
|
|
||||||
TLS_VER_NO_SUPPORTED.format(tls_versions, TLS_VERSIONS))
|
|
||||||
|
|
||||||
settings["tls-versions"] = tls_versions
|
|
||||||
|
|
||||||
|
|
||||||
def validate_tls_ciphersuites(settings):
|
|
||||||
"""Validate tls-ciphersuites.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
settings (dict): Settings dictionary.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.InterfaceError`: If tls-ciphersuites name is not valid.
|
|
||||||
"""
|
|
||||||
tls_ciphersuites = []
|
|
||||||
if "tls-ciphersuites" not in settings:
|
|
||||||
return
|
|
||||||
|
|
||||||
tls_ciphersuites_settings = settings["tls-ciphersuites"]
|
|
||||||
|
|
||||||
if isinstance(tls_ciphersuites_settings, STRING_TYPES):
|
|
||||||
if not (tls_ciphersuites_settings.startswith("[") and
|
|
||||||
tls_ciphersuites_settings.endswith("]")):
|
|
||||||
raise InterfaceError("tls-ciphersuites must be a list, found: '{}'"
|
|
||||||
"".format(tls_ciphersuites_settings))
|
|
||||||
else:
|
|
||||||
tls_css = tls_ciphersuites_settings[1:-1].split(",")
|
|
||||||
if not tls_css:
|
|
||||||
raise InterfaceError("No valid cipher suite found in the "
|
|
||||||
"'tls-ciphersuites' list.")
|
|
||||||
for tls_cs in tls_css:
|
|
||||||
tls_cs = tls_cs.strip().upper()
|
|
||||||
if tls_cs:
|
|
||||||
tls_ciphersuites.append(tls_cs)
|
|
||||||
elif isinstance(tls_ciphersuites_settings, list):
|
|
||||||
tls_ciphersuites = [tls_cs for tls_cs in tls_ciphersuites_settings
|
|
||||||
if tls_cs]
|
|
||||||
|
|
||||||
elif isinstance(tls_ciphersuites_settings, set):
|
|
||||||
for tls_cs in tls_ciphersuites:
|
|
||||||
if tls_cs:
|
|
||||||
tls_ciphersuites.append(tls_cs)
|
|
||||||
else:
|
|
||||||
raise InterfaceError("tls-ciphersuites should be a list with one or "
|
|
||||||
"more ciphersuites. Found: '{}'"
|
|
||||||
"".format(tls_ciphersuites_settings))
|
|
||||||
|
|
||||||
tls_versions = TLS_VERSIONS[:] if settings.get("tls-versions", None) \
|
|
||||||
is None else settings["tls-versions"][:]
|
|
||||||
|
|
||||||
# A newer TLS version can use a cipher introduced on
|
|
||||||
# an older version.
|
|
||||||
tls_versions.sort(reverse=True)
|
|
||||||
newer_tls_ver = tls_versions[0]
|
|
||||||
|
|
||||||
translated_names = []
|
|
||||||
iani_cipher_suites_names = {}
|
|
||||||
ossl_cipher_suites_names = []
|
|
||||||
|
|
||||||
# Old ciphers can work with new TLS versions.
|
|
||||||
# Find all the ciphers introduced on previous TLS versions
|
|
||||||
for tls_ver in TLS_VERSIONS[:TLS_VERSIONS.index(newer_tls_ver) + 1]:
|
|
||||||
iani_cipher_suites_names.update(TLS_CIPHER_SUITES[tls_ver])
|
|
||||||
ossl_cipher_suites_names.extend(OPENSSL_CS_NAMES[tls_ver])
|
|
||||||
|
|
||||||
for name in tls_ciphersuites:
|
|
||||||
if "-" in name and name in ossl_cipher_suites_names:
|
|
||||||
translated_names.append(name)
|
|
||||||
elif name in iani_cipher_suites_names:
|
|
||||||
translated_name = iani_cipher_suites_names[name]
|
|
||||||
if translated_name in translated_names:
|
|
||||||
raise AttributeError(
|
|
||||||
DUPLICATED_IN_LIST_ERROR.format(
|
|
||||||
list="tls_ciphersuites", value=translated_name))
|
|
||||||
else:
|
|
||||||
translated_names.append(translated_name)
|
|
||||||
else:
|
|
||||||
raise InterfaceError(
|
|
||||||
"The value '{}' in cipher suites is not a valid "
|
|
||||||
"cipher suite".format(name))
|
|
||||||
|
|
||||||
if not translated_names:
|
|
||||||
raise InterfaceError("No valid cipher suite found in the "
|
|
||||||
"'tls-ciphersuites' list.")
|
|
||||||
|
|
||||||
settings["tls-ciphersuites"] = translated_names
|
|
||||||
|
|
||||||
|
|
||||||
def _get_connection_settings(*args, **kwargs):
|
|
||||||
"""Parses the connection string and returns a dictionary with the
|
|
||||||
connection settings.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
*args: Variable length argument list with the connection data used
|
|
||||||
to connect to the database. It can be a dictionary or a
|
|
||||||
connection string.
|
|
||||||
**kwargs: Arbitrary keyword arguments with connection data used to
|
|
||||||
connect to the database.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Session: Session object.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
TypeError: If connection timeout is not a positive integer.
|
|
||||||
:class:`mysqlx.InterfaceError`: If settings not provided.
|
|
||||||
"""
|
|
||||||
settings = {}
|
|
||||||
if args:
|
|
||||||
if isinstance(args[0], STRING_TYPES):
|
|
||||||
settings = _parse_connection_uri(args[0])
|
|
||||||
elif isinstance(args[0], dict):
|
|
||||||
for key, val in args[0].items():
|
|
||||||
settings[key.replace("_", "-")] = val
|
|
||||||
elif kwargs:
|
|
||||||
for key, val in kwargs.items():
|
|
||||||
settings[key.replace("_", "-")] = val
|
|
||||||
|
|
||||||
if not settings:
|
|
||||||
raise InterfaceError("Settings not provided")
|
|
||||||
|
|
||||||
_validate_settings(settings)
|
|
||||||
return settings
|
|
||||||
|
|
||||||
|
|
||||||
def get_session(*args, **kwargs):
|
|
||||||
"""Creates a Session instance using the provided connection data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
*args: Variable length argument list with the connection data used
|
|
||||||
to connect to a MySQL server. It can be a dictionary or a
|
|
||||||
connection string.
|
|
||||||
**kwargs: Arbitrary keyword arguments with connection data used to
|
|
||||||
connect to the database.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Session: Session object.
|
|
||||||
"""
|
|
||||||
settings = _get_connection_settings(*args, **kwargs)
|
|
||||||
return Session(settings)
|
|
||||||
|
|
||||||
|
|
||||||
def get_client(connection_string, options_string):
|
|
||||||
"""Creates a Client instance with the provided connection data and settings.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
connection_string: A string or a dict type object to indicate the \
|
|
||||||
connection data used to connect to a MySQL server.
|
|
||||||
|
|
||||||
The string must have the following uri format::
|
|
||||||
|
|
||||||
cnx_str = 'mysqlx://{user}:{pwd}@{host}:{port}'
|
|
||||||
cnx_str = ('mysqlx://{user}:{pwd}@['
|
|
||||||
' (address={host}:{port}, priority=n),'
|
|
||||||
' (address={host}:{port}, priority=n), ...]'
|
|
||||||
' ?[option=value]')
|
|
||||||
|
|
||||||
And the dictionary::
|
|
||||||
|
|
||||||
cnx_dict = {
|
|
||||||
'host': 'The host where the MySQL product is running',
|
|
||||||
'port': '(int) the port number configured for X protocol',
|
|
||||||
'user': 'The user name account',
|
|
||||||
'password': 'The password for the given user account',
|
|
||||||
'ssl-mode': 'The flags for ssl mode in mysqlx.SSLMode.FLAG',
|
|
||||||
'ssl-ca': 'The path to the ca.cert'
|
|
||||||
"connect-timeout": '(int) milliseconds to wait on timeout'
|
|
||||||
}
|
|
||||||
|
|
||||||
options_string: A string in the form of a document or a dictionary \
|
|
||||||
type with configuration for the client.
|
|
||||||
|
|
||||||
Current options include::
|
|
||||||
|
|
||||||
options = {
|
|
||||||
'pooling': {
|
|
||||||
'enabled': (bool), # [True | False], True by default
|
|
||||||
'max_size': (int), # Maximum connections per pool
|
|
||||||
"max_idle_time": (int), # milliseconds that a
|
|
||||||
# connection will remain active while not in use.
|
|
||||||
# By default 0, means infinite.
|
|
||||||
"queue_timeout": (int), # milliseconds a request will
|
|
||||||
# wait for a connection to become available.
|
|
||||||
# By default 0, means infinite.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Client: Client object.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.13
|
|
||||||
"""
|
|
||||||
if not isinstance(connection_string, (STRING_TYPES, dict)):
|
|
||||||
raise InterfaceError("connection_data must be a string or dict")
|
|
||||||
|
|
||||||
settings_dict = _get_connection_settings(connection_string)
|
|
||||||
|
|
||||||
if not isinstance(options_string, (STRING_TYPES, dict)):
|
|
||||||
raise InterfaceError("connection_options must be a string or dict")
|
|
||||||
|
|
||||||
if isinstance(options_string, STRING_TYPES):
|
|
||||||
try:
|
|
||||||
options_dict = json.loads(options_string)
|
|
||||||
except JSONDecodeError:
|
|
||||||
raise InterfaceError("'pooling' options must be given in the form "
|
|
||||||
"of a document or dict")
|
|
||||||
else:
|
|
||||||
options_dict = {}
|
|
||||||
for key, value in options_string.items():
|
|
||||||
options_dict[key.replace("-", "_")] = value
|
|
||||||
|
|
||||||
if not isinstance(options_dict, dict):
|
|
||||||
raise InterfaceError("'pooling' options must be given in the form of a "
|
|
||||||
"document or dict")
|
|
||||||
pooling_options_dict = {}
|
|
||||||
if "pooling" in options_dict:
|
|
||||||
pooling_options = options_dict.pop("pooling")
|
|
||||||
if not isinstance(pooling_options, (dict)):
|
|
||||||
raise InterfaceError("'pooling' options must be given in the form "
|
|
||||||
"document or dict")
|
|
||||||
# Fill default pooling settings
|
|
||||||
pooling_options_dict["enabled"] = pooling_options.pop("enabled", True)
|
|
||||||
pooling_options_dict["max_size"] = pooling_options.pop("max_size", 25)
|
|
||||||
pooling_options_dict["max_idle_time"] = \
|
|
||||||
pooling_options.pop("max_idle_time", 0)
|
|
||||||
pooling_options_dict["queue_timeout"] = \
|
|
||||||
pooling_options.pop("queue_timeout", 0)
|
|
||||||
|
|
||||||
# No other options besides pooling are supported
|
|
||||||
if len(pooling_options) > 0:
|
|
||||||
raise InterfaceError("Unrecognized pooling options: {}"
|
|
||||||
"".format(pooling_options))
|
|
||||||
# No other options besides pooling are supported
|
|
||||||
if len(options_dict) > 0:
|
|
||||||
raise InterfaceError("Unrecognized connection options: {}"
|
|
||||||
"".format(options_dict.keys()))
|
|
||||||
|
|
||||||
return Client(settings_dict, pooling_options_dict)
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
# mysqlx.connection
|
|
||||||
"Client", "Session", "get_client", "get_session", "expr",
|
|
||||||
|
|
||||||
# mysqlx.constants
|
|
||||||
"Auth", "LockContention", "SSLMode",
|
|
||||||
|
|
||||||
# mysqlx.crud
|
|
||||||
"Schema", "Collection", "Table", "View",
|
|
||||||
|
|
||||||
# mysqlx.errors
|
|
||||||
"Error", "InterfaceError", "DatabaseError", "NotSupportedError",
|
|
||||||
"DataError", "IntegrityError", "ProgrammingError", "OperationalError",
|
|
||||||
"InternalError", "PoolError", "TimeoutError",
|
|
||||||
|
|
||||||
# mysqlx.result
|
|
||||||
"Column", "Row", "Result", "BufferingResult", "RowResult",
|
|
||||||
"SqlResult", "DocResult", "ColumnType",
|
|
||||||
|
|
||||||
# mysqlx.statement
|
|
||||||
"DbDoc", "Statement", "FilterableStatement", "SqlStatement",
|
|
||||||
"FindStatement", "AddStatement", "RemoveStatement", "ModifyStatement",
|
|
||||||
"SelectStatement", "InsertStatement", "DeleteStatement", "UpdateStatement",
|
|
||||||
"CreateCollectionIndexStatement", "Expr",
|
|
||||||
]
|
|
@ -1,180 +0,0 @@
|
|||||||
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Implementation of MySQL Authentication Plugin."""
|
|
||||||
|
|
||||||
import hashlib
|
|
||||||
import struct
|
|
||||||
|
|
||||||
from .compat import PY3, UNICODE_TYPES, hexlify
|
|
||||||
|
|
||||||
|
|
||||||
def xor_string(hash1, hash2, hash_size):
|
|
||||||
"""Encrypt/Decrypt function used for password encryption in
|
|
||||||
authentication, using a simple XOR.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
hash1 (str): The first hash.
|
|
||||||
hash2 (str): The second hash.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: A string with the xor applied.
|
|
||||||
"""
|
|
||||||
if PY3:
|
|
||||||
xored = [h1 ^ h2 for (h1, h2) in zip(hash1, hash2)]
|
|
||||||
else:
|
|
||||||
xored = [ord(h1) ^ ord(h2) for (h1, h2) in zip(hash1, hash2)]
|
|
||||||
return struct.pack("{0}B".format(hash_size), *xored)
|
|
||||||
|
|
||||||
|
|
||||||
class BaseAuthPlugin(object):
|
|
||||||
"""Base class for implementing the authentication plugins."""
|
|
||||||
def __init__(self, username=None, password=None):
|
|
||||||
self._username = username
|
|
||||||
self._password = password
|
|
||||||
|
|
||||||
def name(self):
|
|
||||||
"""Returns the plugin name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The plugin name.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def auth_name(self):
|
|
||||||
"""Returns the authentication name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The authentication name.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
|
|
||||||
class MySQL41AuthPlugin(BaseAuthPlugin):
|
|
||||||
"""Class implementing the MySQL Native Password authentication plugin."""
|
|
||||||
def name(self):
|
|
||||||
"""Returns the plugin name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The plugin name.
|
|
||||||
"""
|
|
||||||
return "MySQL 4.1 Authentication Plugin"
|
|
||||||
|
|
||||||
def auth_name(self):
|
|
||||||
"""Returns the authentication name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The authentication name.
|
|
||||||
"""
|
|
||||||
return "MYSQL41"
|
|
||||||
|
|
||||||
def auth_data(self, data):
|
|
||||||
"""Hashing for MySQL 4.1 authentication.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
data (str): The authentication data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The authentication response.
|
|
||||||
"""
|
|
||||||
if self._password:
|
|
||||||
password = self._password.encode("utf-8") \
|
|
||||||
if isinstance(self._password, UNICODE_TYPES) else self._password
|
|
||||||
hash1 = hashlib.sha1(password).digest()
|
|
||||||
hash2 = hashlib.sha1(hash1).digest()
|
|
||||||
xored = xor_string(hash1, hashlib.sha1(data + hash2).digest(), 20)
|
|
||||||
return "{0}\0{1}\0*{2}\0".format("", self._username, hexlify(xored))
|
|
||||||
return "{0}\0{1}\0".format("", self._username)
|
|
||||||
|
|
||||||
|
|
||||||
class PlainAuthPlugin(BaseAuthPlugin):
|
|
||||||
"""Class implementing the MySQL Plain authentication plugin."""
|
|
||||||
def name(self):
|
|
||||||
"""Returns the plugin name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The plugin name.
|
|
||||||
"""
|
|
||||||
return "Plain Authentication Plugin"
|
|
||||||
|
|
||||||
def auth_name(self):
|
|
||||||
"""Returns the authentication name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The authentication name.
|
|
||||||
"""
|
|
||||||
return "PLAIN"
|
|
||||||
|
|
||||||
def auth_data(self):
|
|
||||||
"""Returns the authentication data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The authentication data.
|
|
||||||
"""
|
|
||||||
password = self._password.encode("utf-8") \
|
|
||||||
if isinstance(self._password, UNICODE_TYPES) and not PY3 \
|
|
||||||
else self._password
|
|
||||||
return "\0{0}\0{1}".format(self._username, password)
|
|
||||||
|
|
||||||
|
|
||||||
class Sha256MemoryAuthPlugin(BaseAuthPlugin):
|
|
||||||
"""Class implementing the SHA256_MEMORY authentication plugin."""
|
|
||||||
def name(self):
|
|
||||||
"""Returns the plugin name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The plugin name.
|
|
||||||
"""
|
|
||||||
return "SHA256_MEMORY Authentication Plugin"
|
|
||||||
|
|
||||||
def auth_name(self):
|
|
||||||
"""Returns the authentication name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The authentication name.
|
|
||||||
"""
|
|
||||||
return "SHA256_MEMORY"
|
|
||||||
|
|
||||||
def auth_data(self, data):
|
|
||||||
"""Hashing for SHA256_MEMORY authentication.
|
|
||||||
|
|
||||||
The scramble is of the form:
|
|
||||||
SHA256(SHA256(SHA256(PASSWORD)),NONCE) XOR SHA256(PASSWORD)
|
|
||||||
|
|
||||||
Args:
|
|
||||||
data (str): The authentication data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The authentication response.
|
|
||||||
"""
|
|
||||||
password = self._password.encode("utf-8") \
|
|
||||||
if isinstance(self._password, UNICODE_TYPES) else self._password
|
|
||||||
hash1 = hashlib.sha256(password).digest()
|
|
||||||
hash2 = hashlib.sha256(hashlib.sha256(hash1).digest() + data).digest()
|
|
||||||
xored = xor_string(hash2, hash1, 32)
|
|
||||||
return "\0{0}\0{1}".format(self._username, hexlify(xored))
|
|
@ -1,350 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
# This file was auto-generated.
|
|
||||||
_GENERATED_ON = '2019-04-29'
|
|
||||||
_MYSQL_VERSION = (8, 0, 17)
|
|
||||||
|
|
||||||
"""This module contains the MySQL Server Character Sets"""
|
|
||||||
|
|
||||||
MYSQL_CHARACTER_SETS = [
|
|
||||||
# (character set name, collation, default)
|
|
||||||
None,
|
|
||||||
("big5", "big5_chinese_ci", True), # 1
|
|
||||||
("latin2", "latin2_czech_cs", False), # 2
|
|
||||||
("dec8", "dec8_swedish_ci", True), # 3
|
|
||||||
("cp850", "cp850_general_ci", True), # 4
|
|
||||||
("latin1", "latin1_german1_ci", False), # 5
|
|
||||||
("hp8", "hp8_english_ci", True), # 6
|
|
||||||
("koi8r", "koi8r_general_ci", True), # 7
|
|
||||||
("latin1", "latin1_swedish_ci", True), # 8
|
|
||||||
("latin2", "latin2_general_ci", True), # 9
|
|
||||||
("swe7", "swe7_swedish_ci", True), # 10
|
|
||||||
("ascii", "ascii_general_ci", True), # 11
|
|
||||||
("ujis", "ujis_japanese_ci", True), # 12
|
|
||||||
("sjis", "sjis_japanese_ci", True), # 13
|
|
||||||
("cp1251", "cp1251_bulgarian_ci", False), # 14
|
|
||||||
("latin1", "latin1_danish_ci", False), # 15
|
|
||||||
("hebrew", "hebrew_general_ci", True), # 16
|
|
||||||
None,
|
|
||||||
("tis620", "tis620_thai_ci", True), # 18
|
|
||||||
("euckr", "euckr_korean_ci", True), # 19
|
|
||||||
("latin7", "latin7_estonian_cs", False), # 20
|
|
||||||
("latin2", "latin2_hungarian_ci", False), # 21
|
|
||||||
("koi8u", "koi8u_general_ci", True), # 22
|
|
||||||
("cp1251", "cp1251_ukrainian_ci", False), # 23
|
|
||||||
("gb2312", "gb2312_chinese_ci", True), # 24
|
|
||||||
("greek", "greek_general_ci", True), # 25
|
|
||||||
("cp1250", "cp1250_general_ci", True), # 26
|
|
||||||
("latin2", "latin2_croatian_ci", False), # 27
|
|
||||||
("gbk", "gbk_chinese_ci", True), # 28
|
|
||||||
("cp1257", "cp1257_lithuanian_ci", False), # 29
|
|
||||||
("latin5", "latin5_turkish_ci", True), # 30
|
|
||||||
("latin1", "latin1_german2_ci", False), # 31
|
|
||||||
("armscii8", "armscii8_general_ci", True), # 32
|
|
||||||
("utf8", "utf8_general_ci", True), # 33
|
|
||||||
("cp1250", "cp1250_czech_cs", False), # 34
|
|
||||||
("ucs2", "ucs2_general_ci", True), # 35
|
|
||||||
("cp866", "cp866_general_ci", True), # 36
|
|
||||||
("keybcs2", "keybcs2_general_ci", True), # 37
|
|
||||||
("macce", "macce_general_ci", True), # 38
|
|
||||||
("macroman", "macroman_general_ci", True), # 39
|
|
||||||
("cp852", "cp852_general_ci", True), # 40
|
|
||||||
("latin7", "latin7_general_ci", True), # 41
|
|
||||||
("latin7", "latin7_general_cs", False), # 42
|
|
||||||
("macce", "macce_bin", False), # 43
|
|
||||||
("cp1250", "cp1250_croatian_ci", False), # 44
|
|
||||||
("utf8mb4", "utf8mb4_general_ci", False), # 45
|
|
||||||
("utf8mb4", "utf8mb4_bin", False), # 46
|
|
||||||
("latin1", "latin1_bin", False), # 47
|
|
||||||
("latin1", "latin1_general_ci", False), # 48
|
|
||||||
("latin1", "latin1_general_cs", False), # 49
|
|
||||||
("cp1251", "cp1251_bin", False), # 50
|
|
||||||
("cp1251", "cp1251_general_ci", True), # 51
|
|
||||||
("cp1251", "cp1251_general_cs", False), # 52
|
|
||||||
("macroman", "macroman_bin", False), # 53
|
|
||||||
("utf16", "utf16_general_ci", True), # 54
|
|
||||||
("utf16", "utf16_bin", False), # 55
|
|
||||||
("utf16le", "utf16le_general_ci", True), # 56
|
|
||||||
("cp1256", "cp1256_general_ci", True), # 57
|
|
||||||
("cp1257", "cp1257_bin", False), # 58
|
|
||||||
("cp1257", "cp1257_general_ci", True), # 59
|
|
||||||
("utf32", "utf32_general_ci", True), # 60
|
|
||||||
("utf32", "utf32_bin", False), # 61
|
|
||||||
("utf16le", "utf16le_bin", False), # 62
|
|
||||||
("binary", "binary", True), # 63
|
|
||||||
("armscii8", "armscii8_bin", False), # 64
|
|
||||||
("ascii", "ascii_bin", False), # 65
|
|
||||||
("cp1250", "cp1250_bin", False), # 66
|
|
||||||
("cp1256", "cp1256_bin", False), # 67
|
|
||||||
("cp866", "cp866_bin", False), # 68
|
|
||||||
("dec8", "dec8_bin", False), # 69
|
|
||||||
("greek", "greek_bin", False), # 70
|
|
||||||
("hebrew", "hebrew_bin", False), # 71
|
|
||||||
("hp8", "hp8_bin", False), # 72
|
|
||||||
("keybcs2", "keybcs2_bin", False), # 73
|
|
||||||
("koi8r", "koi8r_bin", False), # 74
|
|
||||||
("koi8u", "koi8u_bin", False), # 75
|
|
||||||
("utf8", "utf8_tolower_ci", False), # 76
|
|
||||||
("latin2", "latin2_bin", False), # 77
|
|
||||||
("latin5", "latin5_bin", False), # 78
|
|
||||||
("latin7", "latin7_bin", False), # 79
|
|
||||||
("cp850", "cp850_bin", False), # 80
|
|
||||||
("cp852", "cp852_bin", False), # 81
|
|
||||||
("swe7", "swe7_bin", False), # 82
|
|
||||||
("utf8", "utf8_bin", False), # 83
|
|
||||||
("big5", "big5_bin", False), # 84
|
|
||||||
("euckr", "euckr_bin", False), # 85
|
|
||||||
("gb2312", "gb2312_bin", False), # 86
|
|
||||||
("gbk", "gbk_bin", False), # 87
|
|
||||||
("sjis", "sjis_bin", False), # 88
|
|
||||||
("tis620", "tis620_bin", False), # 89
|
|
||||||
("ucs2", "ucs2_bin", False), # 90
|
|
||||||
("ujis", "ujis_bin", False), # 91
|
|
||||||
("geostd8", "geostd8_general_ci", True), # 92
|
|
||||||
("geostd8", "geostd8_bin", False), # 93
|
|
||||||
("latin1", "latin1_spanish_ci", False), # 94
|
|
||||||
("cp932", "cp932_japanese_ci", True), # 95
|
|
||||||
("cp932", "cp932_bin", False), # 96
|
|
||||||
("eucjpms", "eucjpms_japanese_ci", True), # 97
|
|
||||||
("eucjpms", "eucjpms_bin", False), # 98
|
|
||||||
("cp1250", "cp1250_polish_ci", False), # 99
|
|
||||||
None,
|
|
||||||
("utf16", "utf16_unicode_ci", False), # 101
|
|
||||||
("utf16", "utf16_icelandic_ci", False), # 102
|
|
||||||
("utf16", "utf16_latvian_ci", False), # 103
|
|
||||||
("utf16", "utf16_romanian_ci", False), # 104
|
|
||||||
("utf16", "utf16_slovenian_ci", False), # 105
|
|
||||||
("utf16", "utf16_polish_ci", False), # 106
|
|
||||||
("utf16", "utf16_estonian_ci", False), # 107
|
|
||||||
("utf16", "utf16_spanish_ci", False), # 108
|
|
||||||
("utf16", "utf16_swedish_ci", False), # 109
|
|
||||||
("utf16", "utf16_turkish_ci", False), # 110
|
|
||||||
("utf16", "utf16_czech_ci", False), # 111
|
|
||||||
("utf16", "utf16_danish_ci", False), # 112
|
|
||||||
("utf16", "utf16_lithuanian_ci", False), # 113
|
|
||||||
("utf16", "utf16_slovak_ci", False), # 114
|
|
||||||
("utf16", "utf16_spanish2_ci", False), # 115
|
|
||||||
("utf16", "utf16_roman_ci", False), # 116
|
|
||||||
("utf16", "utf16_persian_ci", False), # 117
|
|
||||||
("utf16", "utf16_esperanto_ci", False), # 118
|
|
||||||
("utf16", "utf16_hungarian_ci", False), # 119
|
|
||||||
("utf16", "utf16_sinhala_ci", False), # 120
|
|
||||||
("utf16", "utf16_german2_ci", False), # 121
|
|
||||||
("utf16", "utf16_croatian_ci", False), # 122
|
|
||||||
("utf16", "utf16_unicode_520_ci", False), # 123
|
|
||||||
("utf16", "utf16_vietnamese_ci", False), # 124
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("ucs2", "ucs2_unicode_ci", False), # 128
|
|
||||||
("ucs2", "ucs2_icelandic_ci", False), # 129
|
|
||||||
("ucs2", "ucs2_latvian_ci", False), # 130
|
|
||||||
("ucs2", "ucs2_romanian_ci", False), # 131
|
|
||||||
("ucs2", "ucs2_slovenian_ci", False), # 132
|
|
||||||
("ucs2", "ucs2_polish_ci", False), # 133
|
|
||||||
("ucs2", "ucs2_estonian_ci", False), # 134
|
|
||||||
("ucs2", "ucs2_spanish_ci", False), # 135
|
|
||||||
("ucs2", "ucs2_swedish_ci", False), # 136
|
|
||||||
("ucs2", "ucs2_turkish_ci", False), # 137
|
|
||||||
("ucs2", "ucs2_czech_ci", False), # 138
|
|
||||||
("ucs2", "ucs2_danish_ci", False), # 139
|
|
||||||
("ucs2", "ucs2_lithuanian_ci", False), # 140
|
|
||||||
("ucs2", "ucs2_slovak_ci", False), # 141
|
|
||||||
("ucs2", "ucs2_spanish2_ci", False), # 142
|
|
||||||
("ucs2", "ucs2_roman_ci", False), # 143
|
|
||||||
("ucs2", "ucs2_persian_ci", False), # 144
|
|
||||||
("ucs2", "ucs2_esperanto_ci", False), # 145
|
|
||||||
("ucs2", "ucs2_hungarian_ci", False), # 146
|
|
||||||
("ucs2", "ucs2_sinhala_ci", False), # 147
|
|
||||||
("ucs2", "ucs2_german2_ci", False), # 148
|
|
||||||
("ucs2", "ucs2_croatian_ci", False), # 149
|
|
||||||
("ucs2", "ucs2_unicode_520_ci", False), # 150
|
|
||||||
("ucs2", "ucs2_vietnamese_ci", False), # 151
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("ucs2", "ucs2_general_mysql500_ci", False), # 159
|
|
||||||
("utf32", "utf32_unicode_ci", False), # 160
|
|
||||||
("utf32", "utf32_icelandic_ci", False), # 161
|
|
||||||
("utf32", "utf32_latvian_ci", False), # 162
|
|
||||||
("utf32", "utf32_romanian_ci", False), # 163
|
|
||||||
("utf32", "utf32_slovenian_ci", False), # 164
|
|
||||||
("utf32", "utf32_polish_ci", False), # 165
|
|
||||||
("utf32", "utf32_estonian_ci", False), # 166
|
|
||||||
("utf32", "utf32_spanish_ci", False), # 167
|
|
||||||
("utf32", "utf32_swedish_ci", False), # 168
|
|
||||||
("utf32", "utf32_turkish_ci", False), # 169
|
|
||||||
("utf32", "utf32_czech_ci", False), # 170
|
|
||||||
("utf32", "utf32_danish_ci", False), # 171
|
|
||||||
("utf32", "utf32_lithuanian_ci", False), # 172
|
|
||||||
("utf32", "utf32_slovak_ci", False), # 173
|
|
||||||
("utf32", "utf32_spanish2_ci", False), # 174
|
|
||||||
("utf32", "utf32_roman_ci", False), # 175
|
|
||||||
("utf32", "utf32_persian_ci", False), # 176
|
|
||||||
("utf32", "utf32_esperanto_ci", False), # 177
|
|
||||||
("utf32", "utf32_hungarian_ci", False), # 178
|
|
||||||
("utf32", "utf32_sinhala_ci", False), # 179
|
|
||||||
("utf32", "utf32_german2_ci", False), # 180
|
|
||||||
("utf32", "utf32_croatian_ci", False), # 181
|
|
||||||
("utf32", "utf32_unicode_520_ci", False), # 182
|
|
||||||
("utf32", "utf32_vietnamese_ci", False), # 183
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("utf8", "utf8_unicode_ci", False), # 192
|
|
||||||
("utf8", "utf8_icelandic_ci", False), # 193
|
|
||||||
("utf8", "utf8_latvian_ci", False), # 194
|
|
||||||
("utf8", "utf8_romanian_ci", False), # 195
|
|
||||||
("utf8", "utf8_slovenian_ci", False), # 196
|
|
||||||
("utf8", "utf8_polish_ci", False), # 197
|
|
||||||
("utf8", "utf8_estonian_ci", False), # 198
|
|
||||||
("utf8", "utf8_spanish_ci", False), # 199
|
|
||||||
("utf8", "utf8_swedish_ci", False), # 200
|
|
||||||
("utf8", "utf8_turkish_ci", False), # 201
|
|
||||||
("utf8", "utf8_czech_ci", False), # 202
|
|
||||||
("utf8", "utf8_danish_ci", False), # 203
|
|
||||||
("utf8", "utf8_lithuanian_ci", False), # 204
|
|
||||||
("utf8", "utf8_slovak_ci", False), # 205
|
|
||||||
("utf8", "utf8_spanish2_ci", False), # 206
|
|
||||||
("utf8", "utf8_roman_ci", False), # 207
|
|
||||||
("utf8", "utf8_persian_ci", False), # 208
|
|
||||||
("utf8", "utf8_esperanto_ci", False), # 209
|
|
||||||
("utf8", "utf8_hungarian_ci", False), # 210
|
|
||||||
("utf8", "utf8_sinhala_ci", False), # 211
|
|
||||||
("utf8", "utf8_german2_ci", False), # 212
|
|
||||||
("utf8", "utf8_croatian_ci", False), # 213
|
|
||||||
("utf8", "utf8_unicode_520_ci", False), # 214
|
|
||||||
("utf8", "utf8_vietnamese_ci", False), # 215
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("utf8", "utf8_general_mysql500_ci", False), # 223
|
|
||||||
("utf8mb4", "utf8mb4_unicode_ci", False), # 224
|
|
||||||
("utf8mb4", "utf8mb4_icelandic_ci", False), # 225
|
|
||||||
("utf8mb4", "utf8mb4_latvian_ci", False), # 226
|
|
||||||
("utf8mb4", "utf8mb4_romanian_ci", False), # 227
|
|
||||||
("utf8mb4", "utf8mb4_slovenian_ci", False), # 228
|
|
||||||
("utf8mb4", "utf8mb4_polish_ci", False), # 229
|
|
||||||
("utf8mb4", "utf8mb4_estonian_ci", False), # 230
|
|
||||||
("utf8mb4", "utf8mb4_spanish_ci", False), # 231
|
|
||||||
("utf8mb4", "utf8mb4_swedish_ci", False), # 232
|
|
||||||
("utf8mb4", "utf8mb4_turkish_ci", False), # 233
|
|
||||||
("utf8mb4", "utf8mb4_czech_ci", False), # 234
|
|
||||||
("utf8mb4", "utf8mb4_danish_ci", False), # 235
|
|
||||||
("utf8mb4", "utf8mb4_lithuanian_ci", False), # 236
|
|
||||||
("utf8mb4", "utf8mb4_slovak_ci", False), # 237
|
|
||||||
("utf8mb4", "utf8mb4_spanish2_ci", False), # 238
|
|
||||||
("utf8mb4", "utf8mb4_roman_ci", False), # 239
|
|
||||||
("utf8mb4", "utf8mb4_persian_ci", False), # 240
|
|
||||||
("utf8mb4", "utf8mb4_esperanto_ci", False), # 241
|
|
||||||
("utf8mb4", "utf8mb4_hungarian_ci", False), # 242
|
|
||||||
("utf8mb4", "utf8mb4_sinhala_ci", False), # 243
|
|
||||||
("utf8mb4", "utf8mb4_german2_ci", False), # 244
|
|
||||||
("utf8mb4", "utf8mb4_croatian_ci", False), # 245
|
|
||||||
("utf8mb4", "utf8mb4_unicode_520_ci", False), # 246
|
|
||||||
("utf8mb4", "utf8mb4_vietnamese_ci", False), # 247
|
|
||||||
("gb18030", "gb18030_chinese_ci", True), # 248
|
|
||||||
("gb18030", "gb18030_bin", False), # 249
|
|
||||||
("gb18030", "gb18030_unicode_520_ci", False), # 250
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_0900_ai_ci", True), # 255
|
|
||||||
("utf8mb4", "utf8mb4_de_pb_0900_ai_ci", False), # 256
|
|
||||||
("utf8mb4", "utf8mb4_is_0900_ai_ci", False), # 257
|
|
||||||
("utf8mb4", "utf8mb4_lv_0900_ai_ci", False), # 258
|
|
||||||
("utf8mb4", "utf8mb4_ro_0900_ai_ci", False), # 259
|
|
||||||
("utf8mb4", "utf8mb4_sl_0900_ai_ci", False), # 260
|
|
||||||
("utf8mb4", "utf8mb4_pl_0900_ai_ci", False), # 261
|
|
||||||
("utf8mb4", "utf8mb4_et_0900_ai_ci", False), # 262
|
|
||||||
("utf8mb4", "utf8mb4_es_0900_ai_ci", False), # 263
|
|
||||||
("utf8mb4", "utf8mb4_sv_0900_ai_ci", False), # 264
|
|
||||||
("utf8mb4", "utf8mb4_tr_0900_ai_ci", False), # 265
|
|
||||||
("utf8mb4", "utf8mb4_cs_0900_ai_ci", False), # 266
|
|
||||||
("utf8mb4", "utf8mb4_da_0900_ai_ci", False), # 267
|
|
||||||
("utf8mb4", "utf8mb4_lt_0900_ai_ci", False), # 268
|
|
||||||
("utf8mb4", "utf8mb4_sk_0900_ai_ci", False), # 269
|
|
||||||
("utf8mb4", "utf8mb4_es_trad_0900_ai_ci", False), # 270
|
|
||||||
("utf8mb4", "utf8mb4_la_0900_ai_ci", False), # 271
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_eo_0900_ai_ci", False), # 273
|
|
||||||
("utf8mb4", "utf8mb4_hu_0900_ai_ci", False), # 274
|
|
||||||
("utf8mb4", "utf8mb4_hr_0900_ai_ci", False), # 275
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_vi_0900_ai_ci", False), # 277
|
|
||||||
("utf8mb4", "utf8mb4_0900_as_cs", False), # 278
|
|
||||||
("utf8mb4", "utf8mb4_de_pb_0900_as_cs", False), # 279
|
|
||||||
("utf8mb4", "utf8mb4_is_0900_as_cs", False), # 280
|
|
||||||
("utf8mb4", "utf8mb4_lv_0900_as_cs", False), # 281
|
|
||||||
("utf8mb4", "utf8mb4_ro_0900_as_cs", False), # 282
|
|
||||||
("utf8mb4", "utf8mb4_sl_0900_as_cs", False), # 283
|
|
||||||
("utf8mb4", "utf8mb4_pl_0900_as_cs", False), # 284
|
|
||||||
("utf8mb4", "utf8mb4_et_0900_as_cs", False), # 285
|
|
||||||
("utf8mb4", "utf8mb4_es_0900_as_cs", False), # 286
|
|
||||||
("utf8mb4", "utf8mb4_sv_0900_as_cs", False), # 287
|
|
||||||
("utf8mb4", "utf8mb4_tr_0900_as_cs", False), # 288
|
|
||||||
("utf8mb4", "utf8mb4_cs_0900_as_cs", False), # 289
|
|
||||||
("utf8mb4", "utf8mb4_da_0900_as_cs", False), # 290
|
|
||||||
("utf8mb4", "utf8mb4_lt_0900_as_cs", False), # 291
|
|
||||||
("utf8mb4", "utf8mb4_sk_0900_as_cs", False), # 292
|
|
||||||
("utf8mb4", "utf8mb4_es_trad_0900_as_cs", False), # 293
|
|
||||||
("utf8mb4", "utf8mb4_la_0900_as_cs", False), # 294
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_eo_0900_as_cs", False), # 296
|
|
||||||
("utf8mb4", "utf8mb4_hu_0900_as_cs", False), # 297
|
|
||||||
("utf8mb4", "utf8mb4_hr_0900_as_cs", False), # 298
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_vi_0900_as_cs", False), # 300
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
("utf8mb4", "utf8mb4_ja_0900_as_cs", False), # 303
|
|
||||||
("utf8mb4", "utf8mb4_ja_0900_as_cs_ks", False), # 304
|
|
||||||
("utf8mb4", "utf8mb4_0900_as_ci", False), # 305
|
|
||||||
("utf8mb4", "utf8mb4_ru_0900_ai_ci", False), # 306
|
|
||||||
("utf8mb4", "utf8mb4_ru_0900_as_cs", False), # 307
|
|
||||||
("utf8mb4", "utf8mb4_zh_0900_as_cs", False), # 308
|
|
||||||
("utf8mb4", "utf8mb4_0900_bin", False), # 309
|
|
||||||
]
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
|||||||
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""This module handles compatibility issues between Python 2 and Python 3."""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import decimal
|
|
||||||
import binascii
|
|
||||||
|
|
||||||
|
|
||||||
PY3 = sys.version_info[0] == 3
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=E0401,E0602,E0611,W0611,
|
|
||||||
if PY3:
|
|
||||||
import queue
|
|
||||||
try:
|
|
||||||
from json.decoder import JSONDecodeError
|
|
||||||
except ImportError:
|
|
||||||
JSONDecodeError = ValueError
|
|
||||||
from urllib.parse import urlparse, unquote, parse_qsl
|
|
||||||
|
|
||||||
def hexlify(data):
|
|
||||||
"""Return the hexadecimal representation of the binary data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
data (str): The binary data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bytes: The hexadecimal representation of data.
|
|
||||||
"""
|
|
||||||
return binascii.hexlify(data).decode("utf-8")
|
|
||||||
|
|
||||||
NUMERIC_TYPES = (int, float, decimal.Decimal,)
|
|
||||||
INT_TYPES = (int,)
|
|
||||||
UNICODE_TYPES = (str,)
|
|
||||||
STRING_TYPES = (str,)
|
|
||||||
BYTE_TYPES = (bytearray, bytes,)
|
|
||||||
MAX_INT = sys.maxsize
|
|
||||||
else:
|
|
||||||
import Queue as queue
|
|
||||||
from urlparse import urlparse, unquote, parse_qsl
|
|
||||||
|
|
||||||
def hexlify(data):
|
|
||||||
"""Return the hexadecimal representation of the binary data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
data (str): The binary data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bytes: The hexadecimal representation of data.
|
|
||||||
"""
|
|
||||||
return data.encode("hex")
|
|
||||||
|
|
||||||
NUMERIC_TYPES = (int, float, decimal.Decimal, long,)
|
|
||||||
INT_TYPES = (int, long,)
|
|
||||||
UNICODE_TYPES = (unicode,)
|
|
||||||
STRING_TYPES = (str, unicode,)
|
|
||||||
BYTE_TYPES = (bytearray,)
|
|
||||||
MAX_INT = sys.maxint # pylint: disable=E1101
|
|
||||||
JSONDecodeError = ValueError
|
|
File diff suppressed because it is too large
Load Diff
@ -1,313 +0,0 @@
|
|||||||
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Constants."""
|
|
||||||
|
|
||||||
from collections import namedtuple
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=C0103
|
|
||||||
def create_enum(name, fields, values=None):
|
|
||||||
"""Emulates an enum by creating a namedtuple.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name (string): The type name.
|
|
||||||
fields (tuple): The fields names.
|
|
||||||
values (tuple): The values of the fields.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
namedtuple: A namedtuple object.
|
|
||||||
"""
|
|
||||||
Enum = namedtuple(name, fields)
|
|
||||||
if values is None:
|
|
||||||
return Enum(*fields)
|
|
||||||
return Enum(*values)
|
|
||||||
|
|
||||||
|
|
||||||
SSLMode = create_enum("SSLMode",
|
|
||||||
("REQUIRED", "DISABLED", "VERIFY_CA", "VERIFY_IDENTITY"),
|
|
||||||
("required", "disabled", "verify_ca", "verify_identity"))
|
|
||||||
Auth = create_enum("Auth",
|
|
||||||
("PLAIN", "MYSQL41", "SHA256_MEMORY"),
|
|
||||||
("plain", "mysql41", "sha256_memory"))
|
|
||||||
LockContention = create_enum("LockContention",
|
|
||||||
("DEFAULT", "NOWAIT", "SKIP_LOCKED"), (0, 1, 2))
|
|
||||||
|
|
||||||
TLS_VERSIONS = ["TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"]
|
|
||||||
|
|
||||||
# TLS v1.0 cipher suites IANI to OpenSSL name translation
|
|
||||||
TLSV1_CIPHER_SUITES = {
|
|
||||||
"TLS_RSA_WITH_NULL_MD5": "NULL-MD5",
|
|
||||||
"TLS_RSA_WITH_NULL_SHA": "NULL-SHA",
|
|
||||||
"TLS_RSA_WITH_RC4_128_MD5": "RC4-MD5",
|
|
||||||
"TLS_RSA_WITH_RC4_128_SHA": "RC4-SHA",
|
|
||||||
"TLS_RSA_WITH_IDEA_CBC_SHA": "IDEA-CBC-SHA",
|
|
||||||
"TLS_RSA_WITH_3DES_EDE_CBC_SHA": "DES-CBC3-SHA",
|
|
||||||
|
|
||||||
"TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA": "Not implemented.",
|
|
||||||
"TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA": "Not implemented.",
|
|
||||||
"TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA": "DHE-DSS-DES-CBC3-SHA",
|
|
||||||
"TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA": "DHE-RSA-DES-CBC3-SHA",
|
|
||||||
|
|
||||||
"TLS_DH_anon_WITH_RC4_128_MD5": "ADH-RC4-MD5",
|
|
||||||
"TLS_DH_anon_WITH_3DES_EDE_CBC_SHA": "ADH-DES-CBC3-SHA",
|
|
||||||
|
|
||||||
# AES cipher suites from RFC3268, extending TLS v1.0
|
|
||||||
"TLS_RSA_WITH_AES_128_CBC_SHA": "AES128-SHA",
|
|
||||||
"TLS_RSA_WITH_AES_256_CBC_SHA": "AES256-SHA",
|
|
||||||
|
|
||||||
"TLS_DH_DSS_WITH_AES_128_CBC_SHA": "DH-DSS-AES128-SHA",
|
|
||||||
"TLS_DH_DSS_WITH_AES_256_CBC_SHA": "DH-DSS-AES256-SHA",
|
|
||||||
"TLS_DH_RSA_WITH_AES_128_CBC_SHA": "DH-RSA-AES128-SHA",
|
|
||||||
"TLS_DH_RSA_WITH_AES_256_CBC_SHA": "DH-RSA-AES256-SHA",
|
|
||||||
|
|
||||||
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA": "DHE-DSS-AES128-SHA",
|
|
||||||
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA": "DHE-DSS-AES256-SHA",
|
|
||||||
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA": "DHE-RSA-AES128-SHA",
|
|
||||||
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA": "DHE-RSA-AES256-SHA",
|
|
||||||
|
|
||||||
"TLS_DH_anon_WITH_AES_128_CBC_SHA": "ADH-AES128-SHA",
|
|
||||||
"TLS_DH_anon_WITH_AES_256_CBC_SHA": "ADH-AES256-SHA",
|
|
||||||
|
|
||||||
# Camellia cipher suites from RFC4132, extending TLS v1.0
|
|
||||||
"TLS_RSA_WITH_CAMELLIA_128_CBC_SHA": "CAMELLIA128-SHA",
|
|
||||||
"TLS_RSA_WITH_CAMELLIA_256_CBC_SHA": "CAMELLIA256-SHA",
|
|
||||||
|
|
||||||
"TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA": "DH-DSS-CAMELLIA128-SHA",
|
|
||||||
"TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA": "DH-DSS-CAMELLIA256-SHA",
|
|
||||||
"TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA": "DH-RSA-CAMELLIA128-SHA",
|
|
||||||
"TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA": "DH-RSA-CAMELLIA256-SHA",
|
|
||||||
|
|
||||||
"TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA": "DHE-DSS-CAMELLIA128-SHA",
|
|
||||||
"TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA": "DHE-DSS-CAMELLIA256-SHA",
|
|
||||||
"TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA": "DHE-RSA-CAMELLIA128-SHA",
|
|
||||||
"TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA": "DHE-RSA-CAMELLIA256-SHA",
|
|
||||||
|
|
||||||
"TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA": "ADH-CAMELLIA128-SHA",
|
|
||||||
"TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA": "ADH-CAMELLIA256-SHA",
|
|
||||||
|
|
||||||
# SEED cipher suites from RFC4162, extending TLS v1.0
|
|
||||||
"TLS_RSA_WITH_SEED_CBC_SHA": "SEED-SHA",
|
|
||||||
|
|
||||||
"TLS_DH_DSS_WITH_SEED_CBC_SHA": "DH-DSS-SEED-SHA",
|
|
||||||
"TLS_DH_RSA_WITH_SEED_CBC_SHA": "DH-RSA-SEED-SHA",
|
|
||||||
|
|
||||||
"TLS_DHE_DSS_WITH_SEED_CBC_SHA": "DHE-DSS-SEED-SHA",
|
|
||||||
"TLS_DHE_RSA_WITH_SEED_CBC_SHA": "DHE-RSA-SEED-SHA",
|
|
||||||
|
|
||||||
"TLS_DH_anon_WITH_SEED_CBC_SHA": "ADH-SEED-SHA",
|
|
||||||
|
|
||||||
# GOST cipher suites from draft-chudov-cryptopro-cptls, extending TLS v1.0
|
|
||||||
"TLS_GOSTR341094_WITH_28147_CNT_IMIT": "GOST94-GOST89-GOST89",
|
|
||||||
"TLS_GOSTR341001_WITH_28147_CNT_IMIT": "GOST2001-GOST89-GOST89",
|
|
||||||
"TLS_GOSTR341094_WITH_NULL_GOSTR3411": "GOST94-NULL-GOST94",
|
|
||||||
"TLS_GOSTR341001_WITH_NULL_GOSTR3411": "GOST2001-NULL-GOST94"}
|
|
||||||
|
|
||||||
# TLS v1.1 cipher suites IANI to OpenSSL name translation
|
|
||||||
TLSV1_1_CIPHER_SUITES = TLSV1_CIPHER_SUITES
|
|
||||||
|
|
||||||
# TLS v1.2 cipher suites IANI to OpenSSL name translation
|
|
||||||
TLSV1_2_CIPHER_SUITES = {
|
|
||||||
"TLS_RSA_WITH_NULL_SHA256": "NULL-SHA256",
|
|
||||||
|
|
||||||
"TLS_RSA_WITH_AES_128_CBC_SHA256": "AES128-SHA256",
|
|
||||||
"TLS_RSA_WITH_AES_256_CBC_SHA256": "AES256-SHA256",
|
|
||||||
"TLS_RSA_WITH_AES_128_GCM_SHA256": "AES128-GCM-SHA256",
|
|
||||||
"TLS_RSA_WITH_AES_256_GCM_SHA384": "AES256-GCM-SHA384",
|
|
||||||
|
|
||||||
"TLS_DH_RSA_WITH_AES_128_CBC_SHA256": "DH-RSA-AES128-SHA256",
|
|
||||||
"TLS_DH_RSA_WITH_AES_256_CBC_SHA256": "DH-RSA-AES256-SHA256",
|
|
||||||
"TLS_DH_RSA_WITH_AES_128_GCM_SHA256": "DH-RSA-AES128-GCM-SHA256",
|
|
||||||
"TLS_DH_RSA_WITH_AES_256_GCM_SHA384": "DH-RSA-AES256-GCM-SHA384",
|
|
||||||
|
|
||||||
"TLS_DH_DSS_WITH_AES_128_CBC_SHA256": "DH-DSS-AES128-SHA256",
|
|
||||||
"TLS_DH_DSS_WITH_AES_256_CBC_SHA256": "DH-DSS-AES256-SHA256",
|
|
||||||
"TLS_DH_DSS_WITH_AES_128_GCM_SHA256": "DH-DSS-AES128-GCM-SHA256",
|
|
||||||
"TLS_DH_DSS_WITH_AES_256_GCM_SHA384": "DH-DSS-AES256-GCM-SHA384",
|
|
||||||
|
|
||||||
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256": "DHE-RSA-AES128-SHA256",
|
|
||||||
"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256": "DHE-RSA-AES256-SHA256",
|
|
||||||
"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256": "DHE-RSA-AES128-GCM-SHA256",
|
|
||||||
"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384": "DHE-RSA-AES256-GCM-SHA384",
|
|
||||||
|
|
||||||
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA256": "DHE-DSS-AES128-SHA256",
|
|
||||||
"TLS_DHE_DSS_WITH_AES_256_CBC_SHA256": "DHE-DSS-AES256-SHA256",
|
|
||||||
"TLS_DHE_DSS_WITH_AES_128_GCM_SHA256": "DHE-DSS-AES128-GCM-SHA256",
|
|
||||||
"TLS_DHE_DSS_WITH_AES_256_GCM_SHA384": "DHE-DSS-AES256-GCM-SHA384",
|
|
||||||
|
|
||||||
"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256": "ECDHE-RSA-AES128-SHA256",
|
|
||||||
"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384": "ECDHE-RSA-AES256-SHA384",
|
|
||||||
"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": "ECDHE-RSA-AES128-GCM-SHA256",
|
|
||||||
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": "ECDHE-RSA-AES256-GCM-SHA384",
|
|
||||||
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256": "ECDHE-ECDSA-AES128-SHA256",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384": "ECDHE-ECDSA-AES256-SHA384",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": "ECDHE-ECDSA-AES128-GCM-SHA256",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": "ECDHE-ECDSA-AES256-GCM-SHA384",
|
|
||||||
|
|
||||||
"TLS_DH_anon_WITH_AES_128_CBC_SHA256": "ADH-AES128-SHA256",
|
|
||||||
"TLS_DH_anon_WITH_AES_256_CBC_SHA256": "ADH-AES256-SHA256",
|
|
||||||
"TLS_DH_anon_WITH_AES_128_GCM_SHA256": "ADH-AES128-GCM-SHA256",
|
|
||||||
"TLS_DH_anon_WITH_AES_256_GCM_SHA384": "ADH-AES256-GCM-SHA384",
|
|
||||||
|
|
||||||
"RSA_WITH_AES_128_CCM": "AES128-CCM",
|
|
||||||
"RSA_WITH_AES_256_CCM": "AES256-CCM",
|
|
||||||
"DHE_RSA_WITH_AES_128_CCM": "DHE-RSA-AES128-CCM",
|
|
||||||
"DHE_RSA_WITH_AES_256_CCM": "DHE-RSA-AES256-CCM",
|
|
||||||
"RSA_WITH_AES_128_CCM_8": "AES128-CCM8",
|
|
||||||
"RSA_WITH_AES_256_CCM_8": "AES256-CCM8",
|
|
||||||
"DHE_RSA_WITH_AES_128_CCM_8": "DHE-RSA-AES128-CCM8",
|
|
||||||
"DHE_RSA_WITH_AES_256_CCM_8": "DHE-RSA-AES256-CCM8",
|
|
||||||
"ECDHE_ECDSA_WITH_AES_128_CCM": "ECDHE-ECDSA-AES128-CCM",
|
|
||||||
"ECDHE_ECDSA_WITH_AES_256_CCM": "ECDHE-ECDSA-AES256-CCM",
|
|
||||||
"ECDHE_ECDSA_WITH_AES_128_CCM_8": "ECDHE-ECDSA-AES128-CCM8",
|
|
||||||
"ECDHE_ECDSA_WITH_AES_256_CCM_8": "ECDHE-ECDSA-AES256-CCM8",
|
|
||||||
|
|
||||||
# ARIA cipher suites from RFC6209, extending TLS v1.2
|
|
||||||
"TLS_RSA_WITH_ARIA_128_GCM_SHA256": "ARIA128-GCM-SHA256",
|
|
||||||
"TLS_RSA_WITH_ARIA_256_GCM_SHA384": "ARIA256-GCM-SHA384",
|
|
||||||
"TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256": "DHE-RSA-ARIA128-GCM-SHA256",
|
|
||||||
"TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384": "DHE-RSA-ARIA256-GCM-SHA384",
|
|
||||||
"TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256": "DHE-DSS-ARIA128-GCM-SHA256",
|
|
||||||
"TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384": "DHE-DSS-ARIA256-GCM-SHA384",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256": "ECDHE-ECDSA-ARIA128-GCM-SHA256",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384": "ECDHE-ECDSA-ARIA256-GCM-SHA384",
|
|
||||||
"TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256": "ECDHE-ARIA128-GCM-SHA256",
|
|
||||||
"TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384": "ECDHE-ARIA256-GCM-SHA384",
|
|
||||||
"TLS_PSK_WITH_ARIA_128_GCM_SHA256": "PSK-ARIA128-GCM-SHA256",
|
|
||||||
"TLS_PSK_WITH_ARIA_256_GCM_SHA384": "PSK-ARIA256-GCM-SHA384",
|
|
||||||
"TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256": "DHE-PSK-ARIA128-GCM-SHA256",
|
|
||||||
"TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384": "DHE-PSK-ARIA256-GCM-SHA384",
|
|
||||||
"TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256": "RSA-PSK-ARIA128-GCM-SHA256",
|
|
||||||
"TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384": "RSA-PSK-ARIA256-GCM-SHA384",
|
|
||||||
|
|
||||||
# Camellia HMAC-Based cipher suites from RFC6367, extending TLS v1.2
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256": "ECDHE-ECDSA-CAMELLIA128-SHA256",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384": "ECDHE-ECDSA-CAMELLIA256-SHA384",
|
|
||||||
"TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256": "ECDHE-RSA-CAMELLIA128-SHA256",
|
|
||||||
"TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384": "ECDHE-RSA-CAMELLIA256-SHA384",
|
|
||||||
|
|
||||||
# Pre-shared keying (PSK) cipher suites",
|
|
||||||
"PSK_WITH_NULL_SHA": "PSK-NULL-SHA",
|
|
||||||
"DHE_PSK_WITH_NULL_SHA": "DHE-PSK-NULL-SHA",
|
|
||||||
"RSA_PSK_WITH_NULL_SHA": "RSA-PSK-NULL-SHA",
|
|
||||||
|
|
||||||
"PSK_WITH_RC4_128_SHA": "PSK-RC4-SHA",
|
|
||||||
"PSK_WITH_3DES_EDE_CBC_SHA": "PSK-3DES-EDE-CBC-SHA",
|
|
||||||
"PSK_WITH_AES_128_CBC_SHA": "PSK-AES128-CBC-SHA",
|
|
||||||
"PSK_WITH_AES_256_CBC_SHA": "PSK-AES256-CBC-SHA",
|
|
||||||
|
|
||||||
"DHE_PSK_WITH_RC4_128_SHA": "DHE-PSK-RC4-SHA",
|
|
||||||
"DHE_PSK_WITH_3DES_EDE_CBC_SHA": "DHE-PSK-3DES-EDE-CBC-SHA",
|
|
||||||
"DHE_PSK_WITH_AES_128_CBC_SHA": "DHE-PSK-AES128-CBC-SHA",
|
|
||||||
"DHE_PSK_WITH_AES_256_CBC_SHA": "DHE-PSK-AES256-CBC-SHA",
|
|
||||||
|
|
||||||
"RSA_PSK_WITH_RC4_128_SHA": "RSA-PSK-RC4-SHA",
|
|
||||||
"RSA_PSK_WITH_3DES_EDE_CBC_SHA": "RSA-PSK-3DES-EDE-CBC-SHA",
|
|
||||||
"RSA_PSK_WITH_AES_128_CBC_SHA": "RSA-PSK-AES128-CBC-SHA",
|
|
||||||
"RSA_PSK_WITH_AES_256_CBC_SHA": "RSA-PSK-AES256-CBC-SHA",
|
|
||||||
|
|
||||||
"PSK_WITH_AES_128_GCM_SHA256": "PSK-AES128-GCM-SHA256",
|
|
||||||
"PSK_WITH_AES_256_GCM_SHA384": "PSK-AES256-GCM-SHA384",
|
|
||||||
"DHE_PSK_WITH_AES_128_GCM_SHA256": "DHE-PSK-AES128-GCM-SHA256",
|
|
||||||
"DHE_PSK_WITH_AES_256_GCM_SHA384": "DHE-PSK-AES256-GCM-SHA384",
|
|
||||||
"RSA_PSK_WITH_AES_128_GCM_SHA256": "RSA-PSK-AES128-GCM-SHA256",
|
|
||||||
"RSA_PSK_WITH_AES_256_GCM_SHA384": "RSA-PSK-AES256-GCM-SHA384",
|
|
||||||
|
|
||||||
"PSK_WITH_AES_128_CBC_SHA256": "PSK-AES128-CBC-SHA256",
|
|
||||||
"PSK_WITH_AES_256_CBC_SHA384": "PSK-AES256-CBC-SHA384",
|
|
||||||
"PSK_WITH_NULL_SHA256": "PSK-NULL-SHA256",
|
|
||||||
"PSK_WITH_NULL_SHA384": "PSK-NULL-SHA384",
|
|
||||||
"DHE_PSK_WITH_AES_128_CBC_SHA256": "DHE-PSK-AES128-CBC-SHA256",
|
|
||||||
"DHE_PSK_WITH_AES_256_CBC_SHA384": "DHE-PSK-AES256-CBC-SHA384",
|
|
||||||
"DHE_PSK_WITH_NULL_SHA256": "DHE-PSK-NULL-SHA256",
|
|
||||||
"DHE_PSK_WITH_NULL_SHA384": "DHE-PSK-NULL-SHA384",
|
|
||||||
"RSA_PSK_WITH_AES_128_CBC_SHA256": "RSA-PSK-AES128-CBC-SHA256",
|
|
||||||
"RSA_PSK_WITH_AES_256_CBC_SHA384": "RSA-PSK-AES256-CBC-SHA384",
|
|
||||||
"RSA_PSK_WITH_NULL_SHA256": "RSA-PSK-NULL-SHA256",
|
|
||||||
"RSA_PSK_WITH_NULL_SHA384": "RSA-PSK-NULL-SHA384",
|
|
||||||
|
|
||||||
"ECDHE_PSK_WITH_RC4_128_SHA": "ECDHE-PSK-RC4-SHA",
|
|
||||||
"ECDHE_PSK_WITH_3DES_EDE_CBC_SHA": "ECDHE-PSK-3DES-EDE-CBC-SHA",
|
|
||||||
"ECDHE_PSK_WITH_AES_128_CBC_SHA": "ECDHE-PSK-AES128-CBC-SHA",
|
|
||||||
"ECDHE_PSK_WITH_AES_256_CBC_SHA": "ECDHE-PSK-AES256-CBC-SHA",
|
|
||||||
"ECDHE_PSK_WITH_AES_128_CBC_SHA256": "ECDHE-PSK-AES128-CBC-SHA256",
|
|
||||||
"ECDHE_PSK_WITH_AES_256_CBC_SHA384": "ECDHE-PSK-AES256-CBC-SHA384",
|
|
||||||
"ECDHE_PSK_WITH_NULL_SHA": "ECDHE-PSK-NULL-SHA",
|
|
||||||
"ECDHE_PSK_WITH_NULL_SHA256": "ECDHE-PSK-NULL-SHA256",
|
|
||||||
"ECDHE_PSK_WITH_NULL_SHA384": "ECDHE-PSK-NULL-SHA384",
|
|
||||||
|
|
||||||
"PSK_WITH_CAMELLIA_128_CBC_SHA256": "PSK-CAMELLIA128-SHA256",
|
|
||||||
"PSK_WITH_CAMELLIA_256_CBC_SHA384": "PSK-CAMELLIA256-SHA384",
|
|
||||||
|
|
||||||
"DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256": "DHE-PSK-CAMELLIA128-SHA256",
|
|
||||||
"DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384": "DHE-PSK-CAMELLIA256-SHA384",
|
|
||||||
|
|
||||||
"RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256": "RSA-PSK-CAMELLIA128-SHA256",
|
|
||||||
"RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384": "RSA-PSK-CAMELLIA256-SHA384",
|
|
||||||
|
|
||||||
"ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256": "ECDHE-PSK-CAMELLIA128-SHA256",
|
|
||||||
"ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384": "ECDHE-PSK-CAMELLIA256-SHA384",
|
|
||||||
|
|
||||||
"PSK_WITH_AES_128_CCM": "PSK-AES128-CCM",
|
|
||||||
"PSK_WITH_AES_256_CCM": "PSK-AES256-CCM",
|
|
||||||
"DHE_PSK_WITH_AES_128_CCM": "DHE-PSK-AES128-CCM",
|
|
||||||
"DHE_PSK_WITH_AES_256_CCM": "DHE-PSK-AES256-CCM",
|
|
||||||
"PSK_WITH_AES_128_CCM_8": "PSK-AES128-CCM8",
|
|
||||||
"PSK_WITH_AES_256_CCM_8": "PSK-AES256-CCM8",
|
|
||||||
"DHE_PSK_WITH_AES_128_CCM_8": "DHE-PSK-AES128-CCM8",
|
|
||||||
"DHE_PSK_WITH_AES_256_CCM_8": "DHE-PSK-AES256-CCM8",
|
|
||||||
|
|
||||||
# ChaCha20-Poly1305 cipher suites, extending TLS v1.2
|
|
||||||
"TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": "ECDHE-RSA-CHACHA20-POLY1305",
|
|
||||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256": "ECDHE-ECDSA-CHACHA20-POLY1305",
|
|
||||||
"TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256": "DHE-RSA-CHACHA20-POLY1305",
|
|
||||||
"TLS_PSK_WITH_CHACHA20_POLY1305_SHA256": "PSK-CHACHA20-POLY1305",
|
|
||||||
"TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256": "ECDHE-PSK-CHACHA20-POLY1305",
|
|
||||||
"TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256": "DHE-PSK-CHACHA20-POLY1305",
|
|
||||||
"TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256": "RSA-PSK-CHACHA20-POLY1305"}
|
|
||||||
|
|
||||||
# TLS v1.3 cipher suites IANI to OpenSSL name translation
|
|
||||||
TLSV1_3_CIPHER_SUITES = {
|
|
||||||
"TLS_AES_128_GCM_SHA256": "TLS_AES_128_GCM_SHA256",
|
|
||||||
"TLS_AES_256_GCM_SHA384": "TLS_AES_256_GCM_SHA384",
|
|
||||||
"TLS_CHACHA20_POLY1305_SHA256": "TLS_CHACHA20_POLY1305_SHA256",
|
|
||||||
"TLS_AES_128_CCM_SHA256": "TLS_AES_128_CCM_SHA256",
|
|
||||||
"TLS_AES_128_CCM_8_SHA256": "TLS_AES_128_CCM_8_SHA256"}
|
|
||||||
|
|
||||||
TLS_CIPHER_SUITES = {
|
|
||||||
"TLSv1": TLSV1_CIPHER_SUITES,
|
|
||||||
"TLSv1.1": TLSV1_1_CIPHER_SUITES,
|
|
||||||
"TLSv1.2": TLSV1_2_CIPHER_SUITES,
|
|
||||||
"TLSv1.3": TLSV1_3_CIPHER_SUITES}
|
|
||||||
|
|
||||||
OPENSSL_CS_NAMES = {
|
|
||||||
"TLSv1": TLSV1_CIPHER_SUITES.values(),
|
|
||||||
"TLSv1.1": TLSV1_1_CIPHER_SUITES.values(),
|
|
||||||
"TLSv1.2": TLSV1_2_CIPHER_SUITES.values(),
|
|
||||||
"TLSv1.3": TLSV1_3_CIPHER_SUITES.values()}
|
|
@ -1,590 +0,0 @@
|
|||||||
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Implementation of the CRUD database objects."""
|
|
||||||
|
|
||||||
from .dbdoc import DbDoc
|
|
||||||
from .errorcode import ER_NO_SUCH_TABLE
|
|
||||||
from .errors import OperationalError, ProgrammingError
|
|
||||||
from .helpers import deprecated, escape, quote_identifier
|
|
||||||
from .statement import (FindStatement, AddStatement, RemoveStatement,
|
|
||||||
ModifyStatement, SelectStatement, InsertStatement,
|
|
||||||
DeleteStatement, UpdateStatement,
|
|
||||||
CreateCollectionIndexStatement)
|
|
||||||
|
|
||||||
|
|
||||||
_COUNT_VIEWS_QUERY = ("SELECT COUNT(*) FROM information_schema.views "
|
|
||||||
"WHERE table_schema = '{0}' AND table_name = '{1}'")
|
|
||||||
_COUNT_TABLES_QUERY = ("SELECT COUNT(*) FROM information_schema.tables "
|
|
||||||
"WHERE table_schema = '{0}' AND table_name = '{1}'")
|
|
||||||
_COUNT_SCHEMAS_QUERY = ("SELECT COUNT(*) FROM information_schema.schemata "
|
|
||||||
"WHERE schema_name = '{0}'")
|
|
||||||
_COUNT_QUERY = "SELECT COUNT(*) FROM {0}.{1}"
|
|
||||||
_DROP_TABLE_QUERY = "DROP TABLE IF EXISTS {0}.{1}"
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseObject(object):
|
|
||||||
"""Provides base functionality for database objects.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
schema (mysqlx.Schema): The Schema object.
|
|
||||||
name (str): The database object name.
|
|
||||||
"""
|
|
||||||
def __init__(self, schema, name):
|
|
||||||
self._schema = schema
|
|
||||||
self._name = name
|
|
||||||
self._session = self._schema.get_session()
|
|
||||||
self._connection = self._session.get_connection()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def session(self):
|
|
||||||
""":class:`mysqlx.Session`: The Session object.
|
|
||||||
"""
|
|
||||||
return self._session
|
|
||||||
|
|
||||||
@property
|
|
||||||
def schema(self):
|
|
||||||
""":class:`mysqlx.Schema`: The Schema object.
|
|
||||||
"""
|
|
||||||
return self._schema
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""str: The name of this database object.
|
|
||||||
"""
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
def get_connection(self):
|
|
||||||
"""Returns the underlying connection.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.connection.Connection: The connection object.
|
|
||||||
"""
|
|
||||||
return self._connection
|
|
||||||
|
|
||||||
def get_session(self):
|
|
||||||
"""Returns the session of this database object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Session: The Session object.
|
|
||||||
"""
|
|
||||||
return self._session
|
|
||||||
|
|
||||||
def get_schema(self):
|
|
||||||
"""Returns the Schema object of this database object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Schema: The Schema object.
|
|
||||||
"""
|
|
||||||
return self._schema
|
|
||||||
|
|
||||||
def get_name(self):
|
|
||||||
"""Returns the name of this database object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The name of this database object.
|
|
||||||
"""
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
def exists_in_database(self):
|
|
||||||
"""Verifies if this object exists in the database.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: `True` if object exists in database.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: This method must be implemented.
|
|
||||||
"""
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
@deprecated("8.0.12", "Use 'exists_in_database()' method instead")
|
|
||||||
def am_i_real(self):
|
|
||||||
"""Verifies if this object exists in the database.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: `True` if object exists in database.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
NotImplementedError: This method must be implemented.
|
|
||||||
|
|
||||||
.. deprecated:: 8.0.12
|
|
||||||
Use ``exists_in_database()`` method instead.
|
|
||||||
"""
|
|
||||||
return self.exists_in_database()
|
|
||||||
|
|
||||||
@deprecated("8.0.12", "Use 'get_name()' method instead")
|
|
||||||
def who_am_i(self):
|
|
||||||
"""Returns the name of this database object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The name of this database object.
|
|
||||||
|
|
||||||
.. deprecated:: 8.0.12
|
|
||||||
Use ``get_name()`` method instead.
|
|
||||||
"""
|
|
||||||
return self.get_name()
|
|
||||||
|
|
||||||
|
|
||||||
class Schema(DatabaseObject):
|
|
||||||
"""A client-side representation of a database schema. Provides access to
|
|
||||||
the schema contents.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
session (mysqlx.XSession): Session object.
|
|
||||||
name (str): The Schema name.
|
|
||||||
"""
|
|
||||||
def __init__(self, session, name):
|
|
||||||
self._session = session
|
|
||||||
super(Schema, self).__init__(self, name)
|
|
||||||
|
|
||||||
def exists_in_database(self):
|
|
||||||
"""Verifies if this object exists in the database.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: `True` if object exists in database.
|
|
||||||
"""
|
|
||||||
sql = _COUNT_SCHEMAS_QUERY.format(escape(self._name))
|
|
||||||
return self._connection.execute_sql_scalar(sql) == 1
|
|
||||||
|
|
||||||
def get_collections(self):
|
|
||||||
"""Returns a list of collections for this schema.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
`list`: List of Collection objects.
|
|
||||||
"""
|
|
||||||
rows = self._connection.get_row_result("list_objects",
|
|
||||||
{"schema": self._name})
|
|
||||||
rows.fetch_all()
|
|
||||||
collections = []
|
|
||||||
for row in rows:
|
|
||||||
if row["type"] != "COLLECTION":
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
collection = Collection(self, row["TABLE_NAME"])
|
|
||||||
except ValueError:
|
|
||||||
collection = Collection(self, row["name"])
|
|
||||||
collections.append(collection)
|
|
||||||
return collections
|
|
||||||
|
|
||||||
def get_collection_as_table(self, name, check_existence=False):
|
|
||||||
"""Returns a a table object for the given collection
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Table: Table object.
|
|
||||||
|
|
||||||
"""
|
|
||||||
return self.get_table(name, check_existence)
|
|
||||||
|
|
||||||
def get_tables(self):
|
|
||||||
"""Returns a list of tables for this schema.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
`list`: List of Table objects.
|
|
||||||
"""
|
|
||||||
rows = self._connection.get_row_result("list_objects",
|
|
||||||
{"schema": self._name})
|
|
||||||
rows.fetch_all()
|
|
||||||
tables = []
|
|
||||||
object_types = ("TABLE", "VIEW",)
|
|
||||||
for row in rows:
|
|
||||||
if row["type"] in object_types:
|
|
||||||
try:
|
|
||||||
table = Table(self, row["TABLE_NAME"])
|
|
||||||
except ValueError:
|
|
||||||
table = Table(self, row["name"])
|
|
||||||
tables.append(table)
|
|
||||||
return tables
|
|
||||||
|
|
||||||
def get_table(self, name, check_existence=False):
|
|
||||||
"""Returns the table of the given name for this schema.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Table: Table object.
|
|
||||||
"""
|
|
||||||
table = Table(self, name)
|
|
||||||
if check_existence:
|
|
||||||
if not table.exists_in_database():
|
|
||||||
raise ProgrammingError("Table does not exist")
|
|
||||||
return table
|
|
||||||
|
|
||||||
def get_view(self, name, check_existence=False):
|
|
||||||
"""Returns the view of the given name for this schema.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.View: View object.
|
|
||||||
"""
|
|
||||||
view = View(self, name)
|
|
||||||
if check_existence:
|
|
||||||
if not view.exists_in_database():
|
|
||||||
raise ProgrammingError("View does not exist")
|
|
||||||
return view
|
|
||||||
|
|
||||||
def get_collection(self, name, check_existence=False):
|
|
||||||
"""Returns the collection of the given name for this schema.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Collection: Collection object.
|
|
||||||
"""
|
|
||||||
collection = Collection(self, name)
|
|
||||||
if check_existence:
|
|
||||||
if not collection.exists_in_database():
|
|
||||||
raise ProgrammingError("Collection does not exist")
|
|
||||||
return collection
|
|
||||||
|
|
||||||
def drop_collection(self, name):
|
|
||||||
"""Drops a collection.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name (str): The name of the collection to be dropped.
|
|
||||||
"""
|
|
||||||
self._connection.execute_nonquery(
|
|
||||||
"sql", _DROP_TABLE_QUERY.format(quote_identifier(self._name),
|
|
||||||
quote_identifier(name)), False)
|
|
||||||
|
|
||||||
def create_collection(self, name, reuse=False):
|
|
||||||
"""Creates in the current schema a new collection with the specified
|
|
||||||
name and retrieves an object representing the new collection created.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name (str): The name of the collection.
|
|
||||||
reuse (bool): `True` to reuse an existing collection.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Collection: Collection object.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.ProgrammingError`: If ``reuse`` is False and
|
|
||||||
collection exists.
|
|
||||||
"""
|
|
||||||
if not name:
|
|
||||||
raise ProgrammingError("Collection name is invalid")
|
|
||||||
collection = Collection(self, name)
|
|
||||||
if not collection.exists_in_database():
|
|
||||||
self._connection.execute_nonquery("mysqlx", "create_collection",
|
|
||||||
True, {"schema": self._name,
|
|
||||||
"name": name})
|
|
||||||
elif not reuse:
|
|
||||||
raise ProgrammingError("Collection already exists")
|
|
||||||
return collection
|
|
||||||
|
|
||||||
|
|
||||||
class Collection(DatabaseObject):
|
|
||||||
"""Represents a collection of documents on a schema.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
schema (mysqlx.Schema): The Schema object.
|
|
||||||
name (str): The collection name.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def exists_in_database(self):
|
|
||||||
"""Verifies if this object exists in the database.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: `True` if object exists in database.
|
|
||||||
"""
|
|
||||||
sql = _COUNT_TABLES_QUERY.format(escape(self._schema.name),
|
|
||||||
escape(self._name))
|
|
||||||
return self._connection.execute_sql_scalar(sql) == 1
|
|
||||||
|
|
||||||
def find(self, condition=None):
|
|
||||||
"""Retrieves documents from a collection.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
condition (Optional[str]): The string with the filter expression of
|
|
||||||
the documents to be retrieved.
|
|
||||||
"""
|
|
||||||
stmt = FindStatement(self, condition)
|
|
||||||
stmt.stmt_id = self._connection.get_next_statement_id()
|
|
||||||
return stmt
|
|
||||||
|
|
||||||
def add(self, *values):
|
|
||||||
"""Adds a list of documents to a collection.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
*values: The document list to be added into the collection.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.AddStatement: AddStatement object.
|
|
||||||
"""
|
|
||||||
return AddStatement(self).add(*values)
|
|
||||||
|
|
||||||
|
|
||||||
def remove(self, condition):
|
|
||||||
"""Removes documents based on the ``condition``.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
condition (str): The string with the filter expression of the
|
|
||||||
documents to be removed.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.RemoveStatement: RemoveStatement object.
|
|
||||||
|
|
||||||
.. versionchanged:: 8.0.12
|
|
||||||
The ``condition`` parameter is now mandatory.
|
|
||||||
"""
|
|
||||||
stmt = RemoveStatement(self, condition)
|
|
||||||
stmt.stmt_id = self._connection.get_next_statement_id()
|
|
||||||
return stmt
|
|
||||||
|
|
||||||
def modify(self, condition):
|
|
||||||
"""Modifies documents based on the ``condition``.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
condition (str): The string with the filter expression of the
|
|
||||||
documents to be modified.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.ModifyStatement: ModifyStatement object.
|
|
||||||
|
|
||||||
.. versionchanged:: 8.0.12
|
|
||||||
The ``condition`` parameter is now mandatory.
|
|
||||||
"""
|
|
||||||
stmt = ModifyStatement(self, condition)
|
|
||||||
stmt.stmt_id = self._connection.get_next_statement_id()
|
|
||||||
return stmt
|
|
||||||
|
|
||||||
def count(self):
|
|
||||||
"""Counts the documents in the collection.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: The total of documents in the collection.
|
|
||||||
"""
|
|
||||||
sql = _COUNT_QUERY.format(quote_identifier(self._schema.name),
|
|
||||||
quote_identifier(self._name))
|
|
||||||
try:
|
|
||||||
res = self._connection.execute_sql_scalar(sql)
|
|
||||||
except OperationalError as err:
|
|
||||||
if err.errno == ER_NO_SUCH_TABLE:
|
|
||||||
raise OperationalError(
|
|
||||||
"Collection '{}' does not exist in schema '{}'"
|
|
||||||
"".format(self._name, self._schema.name))
|
|
||||||
raise
|
|
||||||
return res
|
|
||||||
|
|
||||||
def create_index(self, index_name, fields_desc):
|
|
||||||
"""Creates a collection index.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
index_name (str): Index name.
|
|
||||||
fields_desc (dict): A dictionary containing the fields members that
|
|
||||||
constraints the index to be created. It must
|
|
||||||
have the form as shown in the following::
|
|
||||||
|
|
||||||
{"fields": [{"field": member_path,
|
|
||||||
"type": member_type,
|
|
||||||
"required": member_required,
|
|
||||||
"array": array,
|
|
||||||
"collation": collation,
|
|
||||||
"options": options,
|
|
||||||
"srid": srid},
|
|
||||||
# {... more members,
|
|
||||||
# repeated as many times
|
|
||||||
# as needed}
|
|
||||||
],
|
|
||||||
"type": type}
|
|
||||||
"""
|
|
||||||
return CreateCollectionIndexStatement(self, index_name, fields_desc)
|
|
||||||
|
|
||||||
def drop_index(self, index_name):
|
|
||||||
"""Drops a collection index.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
index_name (str): Index name.
|
|
||||||
"""
|
|
||||||
self._connection.execute_nonquery("mysqlx", "drop_collection_index",
|
|
||||||
False, {"schema": self._schema.name,
|
|
||||||
"collection": self._name,
|
|
||||||
"name": index_name})
|
|
||||||
|
|
||||||
def replace_one(self, doc_id, doc):
|
|
||||||
"""Replaces the Document matching the document ID with a new document
|
|
||||||
provided.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
doc_id (str): Document ID
|
|
||||||
doc (:class:`mysqlx.DbDoc` or `dict`): New Document
|
|
||||||
"""
|
|
||||||
return self.modify("_id = :id").set("$", doc) \
|
|
||||||
.bind("id", doc_id).execute()
|
|
||||||
|
|
||||||
def add_or_replace_one(self, doc_id, doc):
|
|
||||||
"""Upserts the Document matching the document ID with a new document
|
|
||||||
provided.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
doc_id (str): Document ID
|
|
||||||
doc (:class:`mysqlx.DbDoc` or dict): New Document
|
|
||||||
"""
|
|
||||||
if not isinstance(doc, DbDoc):
|
|
||||||
doc = DbDoc(doc)
|
|
||||||
return self.add(doc.copy(doc_id)).upsert(True).execute()
|
|
||||||
|
|
||||||
def get_one(self, doc_id):
|
|
||||||
"""Returns a Document matching the Document ID.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
doc_id (str): Document ID
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.DbDoc: The Document matching the Document ID.
|
|
||||||
"""
|
|
||||||
result = self.find("_id = :id").bind("id", doc_id).execute()
|
|
||||||
doc = result.fetch_one()
|
|
||||||
self._connection.fetch_active_result()
|
|
||||||
return doc
|
|
||||||
|
|
||||||
def remove_one(self, doc_id):
|
|
||||||
"""Removes a Document matching the Document ID.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
doc_id (str): Document ID
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.Result: Result object.
|
|
||||||
"""
|
|
||||||
return self.remove("_id = :id").bind("id", doc_id).execute()
|
|
||||||
|
|
||||||
|
|
||||||
class Table(DatabaseObject):
|
|
||||||
"""Represents a database table on a schema.
|
|
||||||
|
|
||||||
Provides access to the table through standard INSERT/SELECT/UPDATE/DELETE
|
|
||||||
statements.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
schema (mysqlx.Schema): The Schema object.
|
|
||||||
name (str): The table name.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def exists_in_database(self):
|
|
||||||
"""Verifies if this object exists in the database.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: `True` if object exists in database.
|
|
||||||
"""
|
|
||||||
sql = _COUNT_TABLES_QUERY.format(escape(self._schema.name),
|
|
||||||
escape(self._name))
|
|
||||||
return self._connection.execute_sql_scalar(sql) == 1
|
|
||||||
|
|
||||||
def select(self, *fields):
|
|
||||||
"""Creates a new :class:`mysqlx.SelectStatement` object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
*fields: The fields to be retrieved.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.SelectStatement: SelectStatement object
|
|
||||||
"""
|
|
||||||
stmt = SelectStatement(self, *fields)
|
|
||||||
stmt.stmt_id = self._connection.get_next_statement_id()
|
|
||||||
return stmt
|
|
||||||
|
|
||||||
def insert(self, *fields):
|
|
||||||
"""Creates a new :class:`mysqlx.InsertStatement` object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
*fields: The fields to be inserted.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.InsertStatement: InsertStatement object
|
|
||||||
"""
|
|
||||||
stmt = InsertStatement(self, *fields)
|
|
||||||
stmt.stmt_id = self._connection.get_next_statement_id()
|
|
||||||
return stmt
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
"""Creates a new :class:`mysqlx.UpdateStatement` object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.UpdateStatement: UpdateStatement object
|
|
||||||
"""
|
|
||||||
stmt = UpdateStatement(self)
|
|
||||||
stmt.stmt_id = self._connection.get_next_statement_id()
|
|
||||||
return stmt
|
|
||||||
|
|
||||||
def delete(self):
|
|
||||||
"""Creates a new :class:`mysqlx.DeleteStatement` object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.DeleteStatement: DeleteStatement object
|
|
||||||
|
|
||||||
.. versionchanged:: 8.0.12
|
|
||||||
The ``condition`` parameter was removed.
|
|
||||||
"""
|
|
||||||
stmt = DeleteStatement(self)
|
|
||||||
stmt.stmt_id = self._connection.get_next_statement_id()
|
|
||||||
return stmt
|
|
||||||
|
|
||||||
def count(self):
|
|
||||||
"""Counts the rows in the table.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: The total of rows in the table.
|
|
||||||
"""
|
|
||||||
sql = _COUNT_QUERY.format(quote_identifier(self._schema.name),
|
|
||||||
quote_identifier(self._name))
|
|
||||||
try:
|
|
||||||
res = self._connection.execute_sql_scalar(sql)
|
|
||||||
except OperationalError as err:
|
|
||||||
if err.errno == ER_NO_SUCH_TABLE:
|
|
||||||
raise OperationalError(
|
|
||||||
"Table '{}' does not exist in schema '{}'"
|
|
||||||
"".format(self._name, self._schema.name))
|
|
||||||
raise
|
|
||||||
return res
|
|
||||||
|
|
||||||
def is_view(self):
|
|
||||||
"""Determine if the underlying object is a view or not.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: `True` if the underlying object is a view.
|
|
||||||
"""
|
|
||||||
sql = _COUNT_VIEWS_QUERY.format(escape(self._schema.name),
|
|
||||||
escape(self._name))
|
|
||||||
return self._connection.execute_sql_scalar(sql) == 1
|
|
||||||
|
|
||||||
|
|
||||||
class View(Table):
|
|
||||||
"""Represents a database view on a schema.
|
|
||||||
|
|
||||||
Provides a mechanism for creating, alter and drop views.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
schema (mysqlx.Schema): The Schema object.
|
|
||||||
name (str): The table name.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def exists_in_database(self):
|
|
||||||
"""Verifies if this object exists in the database.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
bool: `True` if object exists in database.
|
|
||||||
"""
|
|
||||||
sql = _COUNT_VIEWS_QUERY.format(escape(self._schema.name),
|
|
||||||
escape(self._name))
|
|
||||||
return self._connection.execute_sql_scalar(sql) == 1
|
|
@ -1,112 +0,0 @@
|
|||||||
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Implementation of the DbDoc."""
|
|
||||||
|
|
||||||
import json
|
|
||||||
|
|
||||||
from .compat import STRING_TYPES
|
|
||||||
from .errors import ProgrammingError
|
|
||||||
|
|
||||||
|
|
||||||
class ExprJSONEncoder(json.JSONEncoder):
|
|
||||||
"""A :class:`json.JSONEncoder` subclass, which enables encoding of
|
|
||||||
:class:`mysqlx.ExprParser` objects."""
|
|
||||||
def default(self, o): # pylint: disable=E0202
|
|
||||||
if hasattr(o, "expr"):
|
|
||||||
return "{0}".format(o)
|
|
||||||
# Let the base class default method raise the TypeError
|
|
||||||
return json.JSONEncoder.default(self, o)
|
|
||||||
|
|
||||||
|
|
||||||
class DbDoc(object):
|
|
||||||
"""Represents a generic document in JSON format.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value (object): The value can be a JSON string or a dict.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError: If ``value`` type is not a basestring or dict.
|
|
||||||
"""
|
|
||||||
def __init__(self, value):
|
|
||||||
if isinstance(value, dict):
|
|
||||||
self.__dict__ = value
|
|
||||||
elif isinstance(value, STRING_TYPES):
|
|
||||||
self.__dict__ = json.loads(value)
|
|
||||||
else:
|
|
||||||
raise ValueError("Unable to handle type: {0}".format(type(value)))
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.as_str()
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return repr(self.__dict__)
|
|
||||||
|
|
||||||
def __setitem__(self, index, value):
|
|
||||||
if index == "_id":
|
|
||||||
raise ProgrammingError("Cannot modify _id")
|
|
||||||
self.__dict__[index] = value
|
|
||||||
|
|
||||||
def __getitem__(self, index):
|
|
||||||
return self.__dict__[index]
|
|
||||||
|
|
||||||
def copy(self, doc_id=None):
|
|
||||||
"""Returns a new copy of a :class:`mysqlx.DbDoc` object containing the
|
|
||||||
`doc_id` provided. If `doc_id` is not provided, it will be removed from
|
|
||||||
new :class:`mysqlx.DbDoc` object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
doc_id (Optional[str]): Document ID
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.DbDoc: A new instance of DbDoc containing the _id provided
|
|
||||||
"""
|
|
||||||
new_dict = self.__dict__.copy()
|
|
||||||
if doc_id:
|
|
||||||
new_dict["_id"] = doc_id
|
|
||||||
elif "_id" in new_dict:
|
|
||||||
del new_dict["_id"]
|
|
||||||
return DbDoc(new_dict)
|
|
||||||
|
|
||||||
def keys(self):
|
|
||||||
"""Returns the keys.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
`list`: The keys.
|
|
||||||
"""
|
|
||||||
return self.__dict__.keys()
|
|
||||||
|
|
||||||
def as_str(self):
|
|
||||||
"""Serialize :class:`mysqlx.DbDoc` to a JSON formatted ``str``.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: A JSON formatted ``str`` representation of the document.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
return json.dumps(self.__dict__, cls=ExprJSONEncoder)
|
|
File diff suppressed because it is too large
Load Diff
@ -1,284 +0,0 @@
|
|||||||
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Implementation of the Python Database API Specification v2.0 exceptions."""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import struct
|
|
||||||
|
|
||||||
from .locales import get_client_error
|
|
||||||
|
|
||||||
PY2 = sys.version_info[0] == 2
|
|
||||||
|
|
||||||
if PY2:
|
|
||||||
# pylint: disable=E0602
|
|
||||||
def struct_unpack(fmt, buf):
|
|
||||||
"""Wrapper around struct.unpack handling buffer as bytes and strings.
|
|
||||||
"""
|
|
||||||
if isinstance(buf, (bytearray, bytes)):
|
|
||||||
return struct.unpack_from(fmt, buffer(buf))
|
|
||||||
return struct.unpack_from(fmt, buf)
|
|
||||||
# pylint: enable=E0602
|
|
||||||
else:
|
|
||||||
from struct import unpack as struct_unpack
|
|
||||||
|
|
||||||
|
|
||||||
class Error(Exception):
|
|
||||||
"""Exception that is base class for all other error exceptions."""
|
|
||||||
def __init__(self, msg=None, errno=None, values=None, sqlstate=None):
|
|
||||||
super(Error, self).__init__()
|
|
||||||
self.msg = msg
|
|
||||||
self._full_msg = self.msg
|
|
||||||
self.errno = errno or -1
|
|
||||||
self.sqlstate = sqlstate
|
|
||||||
|
|
||||||
if not self.msg and (2000 <= self.errno < 3000):
|
|
||||||
self.msg = get_client_error(self.errno)
|
|
||||||
if values is not None:
|
|
||||||
try:
|
|
||||||
self.msg = self.msg % values
|
|
||||||
except TypeError as err:
|
|
||||||
self.msg = "{0} (Warning: {1})".format(self.msg, str(err))
|
|
||||||
elif not self.msg:
|
|
||||||
self._full_msg = self.msg = "Unknown error"
|
|
||||||
|
|
||||||
if self.msg and self.errno != -1:
|
|
||||||
fields = {
|
|
||||||
"errno": self.errno,
|
|
||||||
"msg": self.msg.encode("utf8") if PY2 else self.msg
|
|
||||||
}
|
|
||||||
if self.sqlstate:
|
|
||||||
fmt = "{errno} ({state}): {msg}"
|
|
||||||
fields["state"] = self.sqlstate
|
|
||||||
else:
|
|
||||||
fmt = "{errno}: {msg}"
|
|
||||||
self._full_msg = fmt.format(**fields)
|
|
||||||
|
|
||||||
self.args = (self.errno, self._full_msg, self.sqlstate)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._full_msg
|
|
||||||
|
|
||||||
|
|
||||||
class InterfaceError(Error):
|
|
||||||
"""Exception for errors related to the interface."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DatabaseError(Error):
|
|
||||||
"""Exception for errors related to the database."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class InternalError(DatabaseError):
|
|
||||||
"""Exception for errors internal database errors."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class OperationalError(DatabaseError):
|
|
||||||
"""Exception for errors related to the database's operation."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ProgrammingError(DatabaseError):
|
|
||||||
"""Exception for errors programming errors."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class IntegrityError(DatabaseError):
|
|
||||||
"""Exception for errors regarding relational integrity."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class DataError(DatabaseError):
|
|
||||||
"""Exception for errors reporting problems with processed data."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class NotSupportedError(DatabaseError):
|
|
||||||
"""Exception for errors when an unsupported database feature was used."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class PoolError(Error):
|
|
||||||
"""Exception for errors relating to connection pooling."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
# pylint: disable=W0622
|
|
||||||
class TimeoutError(Error):
|
|
||||||
"""Exception for errors relating to connection timeout."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def intread(buf):
|
|
||||||
"""Unpacks the given buffer to an integer."""
|
|
||||||
try:
|
|
||||||
if isinstance(buf, int):
|
|
||||||
return buf
|
|
||||||
length = len(buf)
|
|
||||||
if length == 1:
|
|
||||||
return buf[0]
|
|
||||||
elif length <= 4:
|
|
||||||
tmp = buf + b"\x00" * (4 - length)
|
|
||||||
return struct_unpack("<I", tmp)[0]
|
|
||||||
tmp = buf + b"\x00" * (8 - length)
|
|
||||||
return struct_unpack("<Q", tmp)[0]
|
|
||||||
except:
|
|
||||||
raise
|
|
||||||
|
|
||||||
|
|
||||||
def read_int(buf, size):
|
|
||||||
"""Read an integer from buffer.
|
|
||||||
|
|
||||||
Returns a tuple (truncated buffer, int).
|
|
||||||
"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
res = intread(buf[0:size])
|
|
||||||
except:
|
|
||||||
raise
|
|
||||||
|
|
||||||
return (buf[size:], res)
|
|
||||||
|
|
||||||
|
|
||||||
def read_bytes(buf, size):
|
|
||||||
"""Reads bytes from a buffer.
|
|
||||||
|
|
||||||
Returns a tuple with buffer less the read bytes, and the bytes.
|
|
||||||
"""
|
|
||||||
res = buf[0:size]
|
|
||||||
return (buf[size:], res)
|
|
||||||
|
|
||||||
|
|
||||||
def get_mysql_exception(errno, msg=None, sqlstate=None):
|
|
||||||
"""Get the exception matching the MySQL error.
|
|
||||||
|
|
||||||
This function will return an exception based on the SQLState. The given
|
|
||||||
message will be passed on in the returned exception.
|
|
||||||
|
|
||||||
Returns an Exception.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
return _ERROR_EXCEPTIONS[errno](msg=msg, errno=errno,
|
|
||||||
sqlstate=sqlstate)
|
|
||||||
except KeyError:
|
|
||||||
# Error was not mapped to particular exception
|
|
||||||
pass
|
|
||||||
|
|
||||||
if not sqlstate:
|
|
||||||
return DatabaseError(msg=msg, errno=errno)
|
|
||||||
|
|
||||||
try:
|
|
||||||
return _SQLSTATE_CLASS_EXCEPTION[sqlstate[0:2]](msg=msg, errno=errno,
|
|
||||||
sqlstate=sqlstate)
|
|
||||||
except KeyError:
|
|
||||||
# Return default InterfaceError
|
|
||||||
return DatabaseError(msg=msg, errno=errno, sqlstate=sqlstate)
|
|
||||||
|
|
||||||
|
|
||||||
def get_exception(packet):
|
|
||||||
"""Returns an exception object based on the MySQL error.
|
|
||||||
|
|
||||||
Returns an exception object based on the MySQL error in the given
|
|
||||||
packet.
|
|
||||||
|
|
||||||
Returns an Error-Object.
|
|
||||||
"""
|
|
||||||
errno = errmsg = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
if packet[4] != 255:
|
|
||||||
raise ValueError("Packet is not an error packet")
|
|
||||||
except IndexError as err:
|
|
||||||
return InterfaceError("Failed getting Error information ({0})"
|
|
||||||
"".format(err))
|
|
||||||
|
|
||||||
sqlstate = None
|
|
||||||
try:
|
|
||||||
packet = packet[5:]
|
|
||||||
packet, errno = read_int(packet, 2)
|
|
||||||
if packet[0] != 35:
|
|
||||||
# Error without SQLState
|
|
||||||
if isinstance(packet, (bytes, bytearray)):
|
|
||||||
errmsg = packet.decode("utf8")
|
|
||||||
else:
|
|
||||||
errmsg = packet
|
|
||||||
else:
|
|
||||||
packet, sqlstate = read_bytes(packet[1:], 5)
|
|
||||||
sqlstate = sqlstate.decode("utf8")
|
|
||||||
errmsg = packet.decode("utf8")
|
|
||||||
except Exception as err: # pylint: disable=W0703
|
|
||||||
return InterfaceError("Failed getting Error information ({0})"
|
|
||||||
"".format(err))
|
|
||||||
else:
|
|
||||||
return get_mysql_exception(errno, errmsg, sqlstate)
|
|
||||||
|
|
||||||
|
|
||||||
_SQLSTATE_CLASS_EXCEPTION = {
|
|
||||||
"02": DataError, # no data
|
|
||||||
"07": DatabaseError, # dynamic SQL error
|
|
||||||
"08": OperationalError, # connection exception
|
|
||||||
"0A": NotSupportedError, # feature not supported
|
|
||||||
"21": DataError, # cardinality violation
|
|
||||||
"22": DataError, # data exception
|
|
||||||
"23": IntegrityError, # integrity constraint violation
|
|
||||||
"24": ProgrammingError, # invalid cursor state
|
|
||||||
"25": ProgrammingError, # invalid transaction state
|
|
||||||
"26": ProgrammingError, # invalid SQL statement name
|
|
||||||
"27": ProgrammingError, # triggered data change violation
|
|
||||||
"28": ProgrammingError, # invalid authorization specification
|
|
||||||
"2A": ProgrammingError, # direct SQL syntax error or access rule violation
|
|
||||||
"2B": DatabaseError, # dependent privilege descriptors still exist
|
|
||||||
"2C": ProgrammingError, # invalid character set name
|
|
||||||
"2D": DatabaseError, # invalid transaction termination
|
|
||||||
"2E": DatabaseError, # invalid connection name
|
|
||||||
"33": DatabaseError, # invalid SQL descriptor name
|
|
||||||
"34": ProgrammingError, # invalid cursor name
|
|
||||||
"35": ProgrammingError, # invalid condition number
|
|
||||||
"37": ProgrammingError, # dynamic SQL syntax error or access rule violation
|
|
||||||
"3C": ProgrammingError, # ambiguous cursor name
|
|
||||||
"3D": ProgrammingError, # invalid catalog name
|
|
||||||
"3F": ProgrammingError, # invalid schema name
|
|
||||||
"40": InternalError, # transaction rollback
|
|
||||||
"42": ProgrammingError, # syntax error or access rule violation
|
|
||||||
"44": InternalError, # with check option violation
|
|
||||||
"HZ": OperationalError, # remote database access
|
|
||||||
"XA": IntegrityError,
|
|
||||||
"0K": OperationalError,
|
|
||||||
"HY": DatabaseError, # default when no SQLState provided by MySQL server
|
|
||||||
}
|
|
||||||
|
|
||||||
_ERROR_EXCEPTIONS = {
|
|
||||||
1243: ProgrammingError,
|
|
||||||
1210: ProgrammingError,
|
|
||||||
2002: InterfaceError,
|
|
||||||
2013: OperationalError,
|
|
||||||
2049: NotSupportedError,
|
|
||||||
2055: OperationalError,
|
|
||||||
2061: InterfaceError,
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,194 +0,0 @@
|
|||||||
# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
"""This module contains helper functions."""
|
|
||||||
|
|
||||||
import functools
|
|
||||||
import inspect
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from .compat import NUMERIC_TYPES
|
|
||||||
from .constants import TLS_CIPHER_SUITES, TLS_VERSIONS
|
|
||||||
from .errors import InterfaceError
|
|
||||||
|
|
||||||
|
|
||||||
def encode_to_bytes(value, encoding="utf-8"):
|
|
||||||
"""Returns an encoded version of the string as a bytes object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
encoding (str): The encoding.
|
|
||||||
|
|
||||||
Resturns:
|
|
||||||
bytes: The encoded version of the string as a bytes object.
|
|
||||||
"""
|
|
||||||
return value if isinstance(value, bytes) else value.encode(encoding)
|
|
||||||
|
|
||||||
|
|
||||||
def decode_from_bytes(value, encoding="utf-8"):
|
|
||||||
"""Returns a string decoded from the given bytes.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value (bytes): The value to be decoded.
|
|
||||||
encoding (str): The encoding.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The value decoded from bytes.
|
|
||||||
"""
|
|
||||||
return value.decode(encoding) if isinstance(value, bytes) else value
|
|
||||||
|
|
||||||
|
|
||||||
def get_item_or_attr(obj, key):
|
|
||||||
"""Get item from dictionary or attribute from object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
obj (object): Dictionary or object.
|
|
||||||
key (str): Key.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
object: The object for the provided key.
|
|
||||||
"""
|
|
||||||
return obj[key] if isinstance(obj, dict) else getattr(obj, key)
|
|
||||||
|
|
||||||
|
|
||||||
def escape(*args):
|
|
||||||
"""Escapes special characters as they are expected to be when MySQL
|
|
||||||
receives them.
|
|
||||||
As found in MySQL source mysys/charset.c
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value (object): Value to be escaped.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The value if not a string, or the escaped string.
|
|
||||||
"""
|
|
||||||
def _escape(value):
|
|
||||||
"""Escapes special characters."""
|
|
||||||
if value is None:
|
|
||||||
return value
|
|
||||||
elif isinstance(value, NUMERIC_TYPES):
|
|
||||||
return value
|
|
||||||
if isinstance(value, (bytes, bytearray)):
|
|
||||||
value = value.replace(b'\\', b'\\\\')
|
|
||||||
value = value.replace(b'\n', b'\\n')
|
|
||||||
value = value.replace(b'\r', b'\\r')
|
|
||||||
value = value.replace(b'\047', b'\134\047') # single quotes
|
|
||||||
value = value.replace(b'\042', b'\134\042') # double quotes
|
|
||||||
value = value.replace(b'\032', b'\134\032') # for Win32
|
|
||||||
else:
|
|
||||||
value = value.replace('\\', '\\\\')
|
|
||||||
value = value.replace('\n', '\\n')
|
|
||||||
value = value.replace('\r', '\\r')
|
|
||||||
value = value.replace('\047', '\134\047') # single quotes
|
|
||||||
value = value.replace('\042', '\134\042') # double quotes
|
|
||||||
value = value.replace('\032', '\134\032') # for Win32
|
|
||||||
return value
|
|
||||||
if len(args) > 1:
|
|
||||||
return [_escape(arg) for arg in args]
|
|
||||||
return _escape(args[0])
|
|
||||||
|
|
||||||
|
|
||||||
def quote_identifier(identifier, sql_mode=""):
|
|
||||||
"""Quote the given identifier with backticks, converting backticks (`)
|
|
||||||
in the identifier name with the correct escape sequence (``) unless the
|
|
||||||
identifier is quoted (") as in sql_mode set to ANSI_QUOTES.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
identifier (str): Identifier to quote.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: Returns string with the identifier quoted with backticks.
|
|
||||||
"""
|
|
||||||
if sql_mode == "ANSI_QUOTES":
|
|
||||||
return '"{0}"'.format(identifier.replace('"', '""'))
|
|
||||||
return "`{0}`".format(identifier.replace("`", "``"))
|
|
||||||
|
|
||||||
|
|
||||||
def deprecated(version=None, reason=None):
|
|
||||||
"""This is a decorator used to mark functions as deprecated.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
version (Optional[string]): Version when was deprecated.
|
|
||||||
reason (Optional[string]): Reason or extra information to be shown.
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
|
|
||||||
.. code-block:: python
|
|
||||||
|
|
||||||
from mysqlx.helpers import deprecated
|
|
||||||
|
|
||||||
@deprecated('8.0.12', 'Please use other_function() instead')
|
|
||||||
def deprecated_function(x, y):
|
|
||||||
return x + y
|
|
||||||
"""
|
|
||||||
def decorate(func):
|
|
||||||
"""Decorate function."""
|
|
||||||
@functools.wraps(func)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
"""Wrapper function.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
*args: Variable length argument list.
|
|
||||||
**kwargs: Arbitrary keyword arguments.
|
|
||||||
"""
|
|
||||||
message = ["'{}' is deprecated".format(func.__name__)]
|
|
||||||
if version:
|
|
||||||
message.append(" since version {}".format(version))
|
|
||||||
if reason:
|
|
||||||
message.append(". {}".format(reason))
|
|
||||||
frame = inspect.currentframe().f_back
|
|
||||||
warnings.warn_explicit("".join(message),
|
|
||||||
category=DeprecationWarning,
|
|
||||||
filename=inspect.getfile(frame.f_code),
|
|
||||||
lineno=frame.f_lineno)
|
|
||||||
return func(*args, **kwargs)
|
|
||||||
return wrapper
|
|
||||||
return decorate
|
|
||||||
|
|
||||||
def iani_to_openssl_cs_name(tls_version, cipher_suites_names):
|
|
||||||
"""Translates a cipher suites names list; from IANI names to OpenSSL names.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
TLS_version (str): The TLS version to look at for a translation.
|
|
||||||
cipher_suite_names (list): A list of cipher suites names.
|
|
||||||
"""
|
|
||||||
translated_names = []
|
|
||||||
|
|
||||||
cipher_suites = {}#TLS_CIPHER_SUITES[TLS_version]
|
|
||||||
|
|
||||||
# Find the previews TLS versions of the given on TLS_version
|
|
||||||
for index in range(TLS_VERSIONS.index(tls_version) + 1):
|
|
||||||
cipher_suites.update(TLS_CIPHER_SUITES[TLS_VERSIONS[index]])
|
|
||||||
|
|
||||||
for name in cipher_suites_names:
|
|
||||||
if "-" in name:
|
|
||||||
translated_names.append(name)
|
|
||||||
elif name in cipher_suites:
|
|
||||||
translated_names.append(cipher_suites[name])
|
|
||||||
else:
|
|
||||||
raise InterfaceError("The '{}' in cipher suites is not a valid "
|
|
||||||
"cipher suite".format(name))
|
|
||||||
return translated_names
|
|
@ -1,73 +0,0 @@
|
|||||||
# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Translations"""
|
|
||||||
|
|
||||||
__all__ = ["get_client_error"]
|
|
||||||
|
|
||||||
from .. import errorcode
|
|
||||||
|
|
||||||
|
|
||||||
def get_client_error(error, language="eng"):
|
|
||||||
"""Lookup client error
|
|
||||||
|
|
||||||
This function will lookup the client error message based on the given
|
|
||||||
error and return the error message. If the error was not found,
|
|
||||||
None will be returned.
|
|
||||||
|
|
||||||
Error can be either an integer or a string. For example:
|
|
||||||
error: 2000
|
|
||||||
error: CR_UNKNOWN_ERROR
|
|
||||||
|
|
||||||
The language attribute can be used to retrieve a localized message, when
|
|
||||||
available.
|
|
||||||
|
|
||||||
Returns a string or None.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
tmp = __import__("mysqlx.locales.{0}".format(language),
|
|
||||||
globals(), locals(), ["client_error"])
|
|
||||||
except ImportError:
|
|
||||||
raise ImportError("No localization support for language '{0}'"
|
|
||||||
"".format(language))
|
|
||||||
client_error = tmp.client_error
|
|
||||||
|
|
||||||
if isinstance(error, int):
|
|
||||||
errno = error
|
|
||||||
for key, value in errorcode.__dict__.items():
|
|
||||||
if value == errno:
|
|
||||||
error = key
|
|
||||||
break
|
|
||||||
|
|
||||||
if isinstance(error, (str)):
|
|
||||||
try:
|
|
||||||
return getattr(client_error, error)
|
|
||||||
except AttributeError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
raise ValueError("Error argument needs to be either an integer or string")
|
|
@ -1,102 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
# This file was auto-generated.
|
|
||||||
_GENERATED_ON = '2018-03-16'
|
|
||||||
_MYSQL_VERSION = (8, 0, 11)
|
|
||||||
|
|
||||||
# Start MySQL Error messages
|
|
||||||
CR_UNKNOWN_ERROR = u"Unknown MySQL error"
|
|
||||||
CR_SOCKET_CREATE_ERROR = u"Can't create UNIX socket (%s)"
|
|
||||||
CR_CONNECTION_ERROR = u"Can't connect to local MySQL server through socket '%-.100s' (%s)"
|
|
||||||
CR_CONN_HOST_ERROR = u"Can't connect to MySQL server on '%-.100s' (%s)"
|
|
||||||
CR_IPSOCK_ERROR = u"Can't create TCP/IP socket (%s)"
|
|
||||||
CR_UNKNOWN_HOST = u"Unknown MySQL server host '%-.100s' (%s)"
|
|
||||||
CR_SERVER_GONE_ERROR = u"MySQL server has gone away"
|
|
||||||
CR_VERSION_ERROR = u"Protocol mismatch; server version = %s, client version = %s"
|
|
||||||
CR_OUT_OF_MEMORY = u"MySQL client ran out of memory"
|
|
||||||
CR_WRONG_HOST_INFO = u"Wrong host info"
|
|
||||||
CR_LOCALHOST_CONNECTION = u"Localhost via UNIX socket"
|
|
||||||
CR_TCP_CONNECTION = u"%-.100s via TCP/IP"
|
|
||||||
CR_SERVER_HANDSHAKE_ERR = u"Error in server handshake"
|
|
||||||
CR_SERVER_LOST = u"Lost connection to MySQL server during query"
|
|
||||||
CR_COMMANDS_OUT_OF_SYNC = u"Commands out of sync; you can't run this command now"
|
|
||||||
CR_NAMEDPIPE_CONNECTION = u"Named pipe: %-.32s"
|
|
||||||
CR_NAMEDPIPEWAIT_ERROR = u"Can't wait for named pipe to host: %-.64s pipe: %-.32s (%s)"
|
|
||||||
CR_NAMEDPIPEOPEN_ERROR = u"Can't open named pipe to host: %-.64s pipe: %-.32s (%s)"
|
|
||||||
CR_NAMEDPIPESETSTATE_ERROR = u"Can't set state of named pipe to host: %-.64s pipe: %-.32s (%s)"
|
|
||||||
CR_CANT_READ_CHARSET = u"Can't initialize character set %-.32s (path: %-.100s)"
|
|
||||||
CR_NET_PACKET_TOO_LARGE = u"Got packet bigger than 'max_allowed_packet' bytes"
|
|
||||||
CR_EMBEDDED_CONNECTION = u"Embedded server"
|
|
||||||
CR_PROBE_SLAVE_STATUS = u"Error on SHOW SLAVE STATUS:"
|
|
||||||
CR_PROBE_SLAVE_HOSTS = u"Error on SHOW SLAVE HOSTS:"
|
|
||||||
CR_PROBE_SLAVE_CONNECT = u"Error connecting to slave:"
|
|
||||||
CR_PROBE_MASTER_CONNECT = u"Error connecting to master:"
|
|
||||||
CR_SSL_CONNECTION_ERROR = u"SSL connection error: %-.100s"
|
|
||||||
CR_MALFORMED_PACKET = u"Malformed packet"
|
|
||||||
CR_WRONG_LICENSE = u"This client library is licensed only for use with MySQL servers having '%s' license"
|
|
||||||
CR_NULL_POINTER = u"Invalid use of null pointer"
|
|
||||||
CR_NO_PREPARE_STMT = u"Statement not prepared"
|
|
||||||
CR_PARAMS_NOT_BOUND = u"No data supplied for parameters in prepared statement"
|
|
||||||
CR_DATA_TRUNCATED = u"Data truncated"
|
|
||||||
CR_NO_PARAMETERS_EXISTS = u"No parameters exist in the statement"
|
|
||||||
CR_INVALID_PARAMETER_NO = u"Invalid parameter number"
|
|
||||||
CR_INVALID_BUFFER_USE = u"Can't send long data for non-string/non-binary data types (parameter: %s)"
|
|
||||||
CR_UNSUPPORTED_PARAM_TYPE = u"Using unsupported buffer type: %s (parameter: %s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECTION = u"Shared memory: %-.100s"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_REQUEST_ERROR = u"Can't open shared memory; client could not create request event (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_ANSWER_ERROR = u"Can't open shared memory; no answer event received from server (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_FILE_MAP_ERROR = u"Can't open shared memory; server could not allocate file mapping (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_MAP_ERROR = u"Can't open shared memory; server could not get pointer to file mapping (%s)"
|
|
||||||
CR_SHARED_MEMORY_FILE_MAP_ERROR = u"Can't open shared memory; client could not allocate file mapping (%s)"
|
|
||||||
CR_SHARED_MEMORY_MAP_ERROR = u"Can't open shared memory; client could not get pointer to file mapping (%s)"
|
|
||||||
CR_SHARED_MEMORY_EVENT_ERROR = u"Can't open shared memory; client could not create %s event (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_ABANDONED_ERROR = u"Can't open shared memory; no answer from server (%s)"
|
|
||||||
CR_SHARED_MEMORY_CONNECT_SET_ERROR = u"Can't open shared memory; cannot send request event to server (%s)"
|
|
||||||
CR_CONN_UNKNOW_PROTOCOL = u"Wrong or unknown protocol"
|
|
||||||
CR_INVALID_CONN_HANDLE = u"Invalid connection handle"
|
|
||||||
CR_UNUSED_1 = u"Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)"
|
|
||||||
CR_FETCH_CANCELED = u"Row retrieval was canceled by mysql_stmt_close() call"
|
|
||||||
CR_NO_DATA = u"Attempt to read column without prior row fetch"
|
|
||||||
CR_NO_STMT_METADATA = u"Prepared statement contains no metadata"
|
|
||||||
CR_NO_RESULT_SET = u"Attempt to read a row while there is no result set associated with the statement"
|
|
||||||
CR_NOT_IMPLEMENTED = u"This feature is not implemented yet"
|
|
||||||
CR_SERVER_LOST_EXTENDED = u"Lost connection to MySQL server at '%s', system error: %s"
|
|
||||||
CR_STMT_CLOSED = u"Statement closed indirectly because of a preceding %s() call"
|
|
||||||
CR_NEW_STMT_METADATA = u"The number of columns in the result set differs from the number of bound buffers. You must reset the statement, rebind the result set columns, and execute the statement again"
|
|
||||||
CR_ALREADY_CONNECTED = u"This handle is already connected. Use a separate handle for each connection."
|
|
||||||
CR_AUTH_PLUGIN_CANNOT_LOAD = u"Authentication plugin '%s' cannot be loaded: %s"
|
|
||||||
CR_DUPLICATE_CONNECTION_ATTR = u"There is an attribute with the same name already"
|
|
||||||
CR_AUTH_PLUGIN_ERR = u"Authentication plugin '%s' reported error: %s"
|
|
||||||
CR_INSECURE_API_ERR = u"Insecure API function call: '%s' Use instead: '%s'"
|
|
||||||
CR_FILE_NAME_TOO_LONG = u"File name is too long"
|
|
||||||
CR_SSL_FIPS_MODE_ERR = u"Set FIPS mode ON/STRICT failed"
|
|
||||||
# End MySQL Error messages
|
|
||||||
|
|
@ -1,430 +0,0 @@
|
|||||||
# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""This module contains the implementation of a helper class for MySQL X
|
|
||||||
Protobuf messages."""
|
|
||||||
|
|
||||||
_SERVER_MESSAGES_TUPLES = (
|
|
||||||
("Mysqlx.ServerMessages.Type.OK",
|
|
||||||
"Mysqlx.Ok"),
|
|
||||||
("Mysqlx.ServerMessages.Type.ERROR",
|
|
||||||
"Mysqlx.Error"),
|
|
||||||
("Mysqlx.ServerMessages.Type.CONN_CAPABILITIES",
|
|
||||||
"Mysqlx.Connection.Capabilities"),
|
|
||||||
("Mysqlx.ServerMessages.Type.SESS_AUTHENTICATE_CONTINUE",
|
|
||||||
"Mysqlx.Session.AuthenticateContinue"),
|
|
||||||
("Mysqlx.ServerMessages.Type.SESS_AUTHENTICATE_OK",
|
|
||||||
"Mysqlx.Session.AuthenticateOk"),
|
|
||||||
("Mysqlx.ServerMessages.Type.NOTICE",
|
|
||||||
"Mysqlx.Notice.Frame"),
|
|
||||||
("Mysqlx.ServerMessages.Type.RESULTSET_COLUMN_META_DATA",
|
|
||||||
"Mysqlx.Resultset.ColumnMetaData"),
|
|
||||||
("Mysqlx.ServerMessages.Type.RESULTSET_ROW",
|
|
||||||
"Mysqlx.Resultset.Row"),
|
|
||||||
("Mysqlx.ServerMessages.Type.RESULTSET_FETCH_DONE",
|
|
||||||
"Mysqlx.Resultset.FetchDone"),
|
|
||||||
("Mysqlx.ServerMessages.Type.RESULTSET_FETCH_SUSPENDED",
|
|
||||||
"Mysqlx.Resultset.FetchSuspended"),
|
|
||||||
("Mysqlx.ServerMessages.Type.RESULTSET_FETCH_DONE_MORE_RESULTSETS",
|
|
||||||
"Mysqlx.Resultset.FetchDoneMoreResultsets"),
|
|
||||||
("Mysqlx.ServerMessages.Type.SQL_STMT_EXECUTE_OK",
|
|
||||||
"Mysqlx.Sql.StmtExecuteOk"),
|
|
||||||
("Mysqlx.ServerMessages.Type.RESULTSET_FETCH_DONE_MORE_OUT_PARAMS",
|
|
||||||
"Mysqlx.Resultset.FetchDoneMoreOutParams"),
|
|
||||||
)
|
|
||||||
|
|
||||||
PROTOBUF_REPEATED_TYPES = [list]
|
|
||||||
|
|
||||||
try:
|
|
||||||
import _mysqlxpb
|
|
||||||
SERVER_MESSAGES = dict([(int(_mysqlxpb.enum_value(key)), val)
|
|
||||||
for key, val in _SERVER_MESSAGES_TUPLES])
|
|
||||||
HAVE_MYSQLXPB_CEXT = True
|
|
||||||
except ImportError:
|
|
||||||
HAVE_MYSQLXPB_CEXT = False
|
|
||||||
|
|
||||||
from ..compat import PY3, NUMERIC_TYPES, STRING_TYPES, BYTE_TYPES
|
|
||||||
from ..helpers import encode_to_bytes
|
|
||||||
|
|
||||||
try:
|
|
||||||
from . import mysqlx_connection_pb2
|
|
||||||
from . import mysqlx_crud_pb2
|
|
||||||
from . import mysqlx_datatypes_pb2
|
|
||||||
from . import mysqlx_expect_pb2
|
|
||||||
from . import mysqlx_expr_pb2
|
|
||||||
from . import mysqlx_notice_pb2
|
|
||||||
from . import mysqlx_pb2
|
|
||||||
from . import mysqlx_prepare_pb2
|
|
||||||
from . import mysqlx_resultset_pb2
|
|
||||||
from . import mysqlx_session_pb2
|
|
||||||
from . import mysqlx_sql_pb2
|
|
||||||
|
|
||||||
from google.protobuf import descriptor_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
from google.protobuf import descriptor_pool
|
|
||||||
from google.protobuf import message_factory
|
|
||||||
from google.protobuf.internal.containers import (
|
|
||||||
RepeatedCompositeFieldContainer)
|
|
||||||
try:
|
|
||||||
from google.protobuf.pyext._message import (
|
|
||||||
RepeatedCompositeContainer)
|
|
||||||
PROTOBUF_REPEATED_TYPES.append(RepeatedCompositeContainer)
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
PROTOBUF_REPEATED_TYPES.append(RepeatedCompositeFieldContainer)
|
|
||||||
|
|
||||||
# Dictionary with all messages descriptors
|
|
||||||
_MESSAGES = {}
|
|
||||||
|
|
||||||
# Mysqlx
|
|
||||||
for key, val in mysqlx_pb2.ClientMessages.Type.items():
|
|
||||||
_MESSAGES["Mysqlx.ClientMessages.Type.{0}".format(key)] = val
|
|
||||||
for key, val in mysqlx_pb2.ServerMessages.Type.items():
|
|
||||||
_MESSAGES["Mysqlx.ServerMessages.Type.{0}".format(key)] = val
|
|
||||||
for key, val in mysqlx_pb2.Error.Severity.items():
|
|
||||||
_MESSAGES["Mysqlx.Error.Severity.{0}".format(key)] = val
|
|
||||||
|
|
||||||
# Mysqlx.Crud
|
|
||||||
for key, val in mysqlx_crud_pb2.DataModel.items():
|
|
||||||
_MESSAGES["Mysqlx.Crud.DataModel.{0}".format(key)] = val
|
|
||||||
for key, val in mysqlx_crud_pb2.Find.RowLock.items():
|
|
||||||
_MESSAGES["Mysqlx.Crud.Find.RowLock.{0}".format(key)] = val
|
|
||||||
for key, val in mysqlx_crud_pb2.Order.Direction.items():
|
|
||||||
_MESSAGES["Mysqlx.Crud.Order.Direction.{0}".format(key)] = val
|
|
||||||
for key, val in mysqlx_crud_pb2.UpdateOperation.UpdateType.items():
|
|
||||||
_MESSAGES["Mysqlx.Crud.UpdateOperation.UpdateType.{0}".format(key)] = val
|
|
||||||
|
|
||||||
# Mysqlx.Datatypes
|
|
||||||
for key, val in mysqlx_datatypes_pb2.Scalar.Type.items():
|
|
||||||
_MESSAGES["Mysqlx.Datatypes.Scalar.Type.{0}".format(key)] = val
|
|
||||||
for key, val in mysqlx_datatypes_pb2.Any.Type.items():
|
|
||||||
_MESSAGES["Mysqlx.Datatypes.Any.Type.{0}".format(key)] = val
|
|
||||||
|
|
||||||
# Mysqlx.Expect
|
|
||||||
for key, val in mysqlx_expect_pb2.Open.Condition.ConditionOperation.items():
|
|
||||||
_MESSAGES["Mysqlx.Expect.Open.Condition.ConditionOperation.{0}"
|
|
||||||
"".format(key)] = val
|
|
||||||
for key, val in mysqlx_expect_pb2.Open.Condition.Key.items():
|
|
||||||
_MESSAGES["Mysqlx.Expect.Open.Condition.Key.{0}"
|
|
||||||
"".format(key)] = val
|
|
||||||
for key, val in mysqlx_expect_pb2.Open.CtxOperation.items():
|
|
||||||
_MESSAGES["Mysqlx.Expect.Open.CtxOperation.{0}".format(key)] = val
|
|
||||||
|
|
||||||
# Mysqlx.Expr
|
|
||||||
for key, val in mysqlx_expr_pb2.Expr.Type.items():
|
|
||||||
_MESSAGES["Mysqlx.Expr.Expr.Type.{0}".format(key)] = val
|
|
||||||
for key, val in mysqlx_expr_pb2.DocumentPathItem.Type.items():
|
|
||||||
_MESSAGES["Mysqlx.Expr.DocumentPathItem.Type.{0}".format(key)] = val
|
|
||||||
|
|
||||||
# Mysqlx.Notice
|
|
||||||
for key, val in mysqlx_notice_pb2.Frame.Scope.items():
|
|
||||||
_MESSAGES["Mysqlx.Notice.Frame.Scope.{0}".format(key)] = val
|
|
||||||
for key, val in mysqlx_notice_pb2.Warning.Level.items():
|
|
||||||
_MESSAGES["Mysqlx.Notice.Warning.Level.{0}".format(key)] = val
|
|
||||||
for key, val in mysqlx_notice_pb2.SessionStateChanged.Parameter.items():
|
|
||||||
_MESSAGES["Mysqlx.Notice.SessionStateChanged.Parameter.{0}"
|
|
||||||
"".format(key)] = val
|
|
||||||
|
|
||||||
# Mysql.Prepare
|
|
||||||
for key, val in mysqlx_prepare_pb2.Prepare.OneOfMessage.Type.items():
|
|
||||||
_MESSAGES["Mysqlx.Prepare.Prepare.OneOfMessage.Type.{0}"
|
|
||||||
"".format(key)] = val
|
|
||||||
|
|
||||||
# Mysql.Resultset
|
|
||||||
for key, val in mysqlx_resultset_pb2.ColumnMetaData.FieldType.items():
|
|
||||||
_MESSAGES["Mysqlx.Resultset.ColumnMetaData.FieldType.{0}".format(key)] = val
|
|
||||||
|
|
||||||
# Add messages to the descriptor pool
|
|
||||||
_DESCRIPTOR_DB = descriptor_database.DescriptorDatabase()
|
|
||||||
_DESCRIPTOR_POOL = descriptor_pool.DescriptorPool(_DESCRIPTOR_DB)
|
|
||||||
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_connection_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_crud_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_datatypes_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_expect_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_expr_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_notice_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_prepare_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_resultset_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_session_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
_DESCRIPTOR_DB.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
|
||||||
mysqlx_sql_pb2.DESCRIPTOR.serialized_pb))
|
|
||||||
|
|
||||||
SERVER_MESSAGES = dict(
|
|
||||||
[(_MESSAGES[key], val) for key, val in _SERVER_MESSAGES_TUPLES]
|
|
||||||
)
|
|
||||||
HAVE_PROTOBUF = True
|
|
||||||
|
|
||||||
|
|
||||||
class _mysqlxpb_pure(object):
|
|
||||||
"""This class implements the methods in pure Python used by the
|
|
||||||
_mysqlxpb C++ extension."""
|
|
||||||
|
|
||||||
factory = message_factory.MessageFactory()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def new_message(name):
|
|
||||||
cls = _mysqlxpb_pure.factory.GetPrototype(
|
|
||||||
_DESCRIPTOR_POOL.FindMessageTypeByName(name))
|
|
||||||
return cls()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def enum_value(key):
|
|
||||||
return _MESSAGES[key]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def serialize_message(msg):
|
|
||||||
return msg.SerializeToString()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def parse_message(msg_type_name, payload):
|
|
||||||
msg = _mysqlxpb_pure.new_message(msg_type_name)
|
|
||||||
msg.ParseFromString(payload)
|
|
||||||
return msg
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def parse_server_message(msg_type, payload):
|
|
||||||
msg_type_name = SERVER_MESSAGES.get(msg_type)
|
|
||||||
if not msg_type_name:
|
|
||||||
raise ValueError("Unknown msg_type: {0}".format(msg_type))
|
|
||||||
msg = _mysqlxpb_pure.new_message(msg_type_name)
|
|
||||||
msg.ParseFromString(payload)
|
|
||||||
return msg
|
|
||||||
except ImportError:
|
|
||||||
HAVE_PROTOBUF = False
|
|
||||||
if not HAVE_MYSQLXPB_CEXT:
|
|
||||||
raise ImportError("Protobuf is not available")
|
|
||||||
|
|
||||||
CRUD_PREPARE_MAPPING = {
|
|
||||||
"Mysqlx.ClientMessages.Type.CRUD_FIND": (
|
|
||||||
"Mysqlx.Prepare.Prepare.OneOfMessage.Type.FIND", "find"),
|
|
||||||
"Mysqlx.ClientMessages.Type.CRUD_INSERT": (
|
|
||||||
"Mysqlx.Prepare.Prepare.OneOfMessage.Type.INSERT", "insert"),
|
|
||||||
"Mysqlx.ClientMessages.Type.CRUD_UPDATE": (
|
|
||||||
"Mysqlx.Prepare.Prepare.OneOfMessage.Type.UPDATE", "update"),
|
|
||||||
"Mysqlx.ClientMessages.Type.CRUD_DELETE": (
|
|
||||||
"Mysqlx.Prepare.Prepare.OneOfMessage.Type.DELETE", "delete"),
|
|
||||||
"Mysqlx.ClientMessages.Type.SQL_STMT_EXECUTE": (
|
|
||||||
"Mysqlx.Prepare.Prepare.OneOfMessage.Type.STMT", "stmt_execute")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Protobuf(object):
|
|
||||||
"""Protobuf class acts as a container of the Protobuf message class.
|
|
||||||
It allows the switch between the C extension and pure Python implementation
|
|
||||||
message handlers, by patching the `mysqlxpb` class attribute.
|
|
||||||
"""
|
|
||||||
mysqlxpb = _mysqlxpb if HAVE_MYSQLXPB_CEXT else _mysqlxpb_pure
|
|
||||||
use_pure = False if HAVE_MYSQLXPB_CEXT else True
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def set_use_pure(use_pure):
|
|
||||||
"""Sets whether to use the C extension or pure Python implementation.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
use_pure (bool): `True` to use pure Python implementation.
|
|
||||||
"""
|
|
||||||
if use_pure and not HAVE_PROTOBUF:
|
|
||||||
raise ImportError("Protobuf is not available")
|
|
||||||
elif not use_pure and not HAVE_MYSQLXPB_CEXT:
|
|
||||||
raise ImportError("MySQL X Protobuf C extension is not available")
|
|
||||||
Protobuf.mysqlxpb = _mysqlxpb_pure if use_pure else _mysqlxpb
|
|
||||||
Protobuf.use_pure = use_pure
|
|
||||||
|
|
||||||
|
|
||||||
class Message(object):
|
|
||||||
"""Helper class for interfacing with the MySQL X Protobuf extension.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_type_name (string): Protobuf type name.
|
|
||||||
**kwargs: Arbitrary keyword arguments with values for the message.
|
|
||||||
"""
|
|
||||||
def __init__(self, msg_type_name=None, **kwargs):
|
|
||||||
self.__dict__["_msg"] = Protobuf.mysqlxpb.new_message(msg_type_name) \
|
|
||||||
if msg_type_name else None
|
|
||||||
for key, value in kwargs.items():
|
|
||||||
self.__setattr__(key, value)
|
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
|
||||||
if Protobuf.use_pure:
|
|
||||||
if PY3 and isinstance(value, STRING_TYPES):
|
|
||||||
setattr(self._msg, name, encode_to_bytes(value))
|
|
||||||
elif isinstance(value, (NUMERIC_TYPES, STRING_TYPES, BYTE_TYPES)):
|
|
||||||
setattr(self._msg, name, value)
|
|
||||||
elif isinstance(value, list):
|
|
||||||
getattr(self._msg, name).extend(value)
|
|
||||||
elif isinstance(value, Message):
|
|
||||||
getattr(self._msg, name).MergeFrom(value.get_message())
|
|
||||||
else:
|
|
||||||
getattr(self._msg, name).MergeFrom(value)
|
|
||||||
else:
|
|
||||||
self._msg[name] = value.get_message() \
|
|
||||||
if isinstance(value, Message) else value
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
|
||||||
try:
|
|
||||||
return self._msg[name] if not Protobuf.use_pure \
|
|
||||||
else getattr(self._msg, name)
|
|
||||||
except KeyError:
|
|
||||||
raise AttributeError
|
|
||||||
|
|
||||||
def __setitem__(self, name, value):
|
|
||||||
self.__setattr__(name, value)
|
|
||||||
|
|
||||||
def __getitem__(self, name):
|
|
||||||
return self.__getattr__(name)
|
|
||||||
|
|
||||||
def get(self, name, default=None):
|
|
||||||
"""Returns the value of an element of the message dictionary.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name (string): Key name.
|
|
||||||
default (object): The default value if the key does not exists.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
object: The value of the provided key name.
|
|
||||||
"""
|
|
||||||
return self.__dict__["_msg"].get(name, default) \
|
|
||||||
if not Protobuf.use_pure \
|
|
||||||
else getattr(self.__dict__["_msg"], name, default)
|
|
||||||
|
|
||||||
def set_message(self, msg):
|
|
||||||
"""Sets the message.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg (dict): Dictionary representing a message.
|
|
||||||
"""
|
|
||||||
self.__dict__["_msg"] = msg
|
|
||||||
|
|
||||||
def get_message(self):
|
|
||||||
"""Returns the dictionary representing a message containing parsed
|
|
||||||
data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: The dictionary representing a message containing parsed data.
|
|
||||||
"""
|
|
||||||
return self.__dict__["_msg"]
|
|
||||||
|
|
||||||
def serialize_to_string(self):
|
|
||||||
"""Serializes a message to a string.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
string: A string representing a message containing parsed data.
|
|
||||||
"""
|
|
||||||
return Protobuf.mysqlxpb.serialize_message(self._msg)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def type(self):
|
|
||||||
"""string: Message type name."""
|
|
||||||
return self._msg["_mysqlxpb_type_name"] if not Protobuf.use_pure \
|
|
||||||
else self._msg.DESCRIPTOR.full_name
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def parse(msg_type_name, payload):
|
|
||||||
"""Creates a new message, initialized with parsed data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_type_name (string): Message type name.
|
|
||||||
payload (string): Serialized message data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: The dictionary representing a message containing parsed data.
|
|
||||||
"""
|
|
||||||
return Protobuf.mysqlxpb.parse_message(msg_type_name, payload)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def parse_from_server(msg_type, payload):
|
|
||||||
"""Creates a new server-side message, initialized with parsed data.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_type (int): Message type.
|
|
||||||
payload (string): Serialized message data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
dict: The dictionary representing a message containing parsed data.
|
|
||||||
"""
|
|
||||||
return Protobuf.mysqlxpb.parse_server_message(msg_type, payload)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_message(cls, msg_type_name, payload):
|
|
||||||
"""Creates a new message, initialized with parsed data and returns a
|
|
||||||
:class:`mysqlx.protobuf.Message` object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_type_name (string): Message type name.
|
|
||||||
payload (string): Serialized message data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.protobuf.Message: The Message representing a message
|
|
||||||
containing parsed data.
|
|
||||||
"""
|
|
||||||
msg = cls()
|
|
||||||
msg.set_message(Protobuf.mysqlxpb.parse_message(msg_type_name, payload))
|
|
||||||
return msg
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_server_message(cls, msg_type, payload):
|
|
||||||
"""Creates a new server-side message, initialized with parsed data and
|
|
||||||
returns a :class:`mysqlx.protobuf.Message` object.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_type (int): Message type.
|
|
||||||
payload (string): Serialized message data.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.protobuf.Message: The Message representing a message
|
|
||||||
containing parsed data.
|
|
||||||
"""
|
|
||||||
msg = cls()
|
|
||||||
msg.set_message(
|
|
||||||
Protobuf.mysqlxpb.parse_server_message(msg_type, payload))
|
|
||||||
return msg
|
|
||||||
|
|
||||||
|
|
||||||
def mysqlxpb_enum(name):
|
|
||||||
"""Returns the value of a MySQL X Protobuf enumerator.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
name (string): MySQL X Protobuf numerator name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
int: Value of the enumerator.
|
|
||||||
"""
|
|
||||||
return Protobuf.mysqlxpb.enum_value(name)
|
|
@ -1,219 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_connection.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
from mysqlx.protobuf import mysqlx_datatypes_pb2
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_connection.proto',
|
|
||||||
package='Mysqlx.Connection',
|
|
||||||
serialized_pb=_b('\n\x17mysqlx_connection.proto\x12\x11Mysqlx.Connection\x1a\x16mysqlx_datatypes.proto\"@\n\nCapability\x12\x0c\n\x04name\x18\x01 \x02(\t\x12$\n\x05value\x18\x02 \x02(\x0b\x32\x15.Mysqlx.Datatypes.Any\"C\n\x0c\x43\x61pabilities\x12\x33\n\x0c\x63\x61pabilities\x18\x01 \x03(\x0b\x32\x1d.Mysqlx.Connection.Capability\"\x11\n\x0f\x43\x61pabilitiesGet\"H\n\x0f\x43\x61pabilitiesSet\x12\x35\n\x0c\x63\x61pabilities\x18\x01 \x02(\x0b\x32\x1f.Mysqlx.Connection.Capabilities\"\x07\n\x05\x43loseB\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
,
|
|
||||||
dependencies=[mysqlx_datatypes_pb2.DESCRIPTOR,])
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_CAPABILITY = _descriptor.Descriptor(
|
|
||||||
name='Capability',
|
|
||||||
full_name='Mysqlx.Connection.Capability',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='name', full_name='Mysqlx.Connection.Capability.name', index=0,
|
|
||||||
number=1, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Connection.Capability.value', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=2,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=70,
|
|
||||||
serialized_end=134,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_CAPABILITIES = _descriptor.Descriptor(
|
|
||||||
name='Capabilities',
|
|
||||||
full_name='Mysqlx.Connection.Capabilities',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='capabilities', full_name='Mysqlx.Connection.Capabilities.capabilities', index=0,
|
|
||||||
number=1, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=136,
|
|
||||||
serialized_end=203,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_CAPABILITIESGET = _descriptor.Descriptor(
|
|
||||||
name='CapabilitiesGet',
|
|
||||||
full_name='Mysqlx.Connection.CapabilitiesGet',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=205,
|
|
||||||
serialized_end=222,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_CAPABILITIESSET = _descriptor.Descriptor(
|
|
||||||
name='CapabilitiesSet',
|
|
||||||
full_name='Mysqlx.Connection.CapabilitiesSet',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='capabilities', full_name='Mysqlx.Connection.CapabilitiesSet.capabilities', index=0,
|
|
||||||
number=1, type=11, cpp_type=10, label=2,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=224,
|
|
||||||
serialized_end=296,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_CLOSE = _descriptor.Descriptor(
|
|
||||||
name='Close',
|
|
||||||
full_name='Mysqlx.Connection.Close',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=298,
|
|
||||||
serialized_end=305,
|
|
||||||
)
|
|
||||||
|
|
||||||
_CAPABILITY.fields_by_name['value'].message_type = mysqlx_datatypes_pb2._ANY
|
|
||||||
_CAPABILITIES.fields_by_name['capabilities'].message_type = _CAPABILITY
|
|
||||||
_CAPABILITIESSET.fields_by_name['capabilities'].message_type = _CAPABILITIES
|
|
||||||
DESCRIPTOR.message_types_by_name['Capability'] = _CAPABILITY
|
|
||||||
DESCRIPTOR.message_types_by_name['Capabilities'] = _CAPABILITIES
|
|
||||||
DESCRIPTOR.message_types_by_name['CapabilitiesGet'] = _CAPABILITIESGET
|
|
||||||
DESCRIPTOR.message_types_by_name['CapabilitiesSet'] = _CAPABILITIESSET
|
|
||||||
DESCRIPTOR.message_types_by_name['Close'] = _CLOSE
|
|
||||||
|
|
||||||
Capability = _reflection.GeneratedProtocolMessageType('Capability', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _CAPABILITY,
|
|
||||||
__module__ = 'mysqlx_connection_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Connection.Capability)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Capability)
|
|
||||||
|
|
||||||
Capabilities = _reflection.GeneratedProtocolMessageType('Capabilities', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _CAPABILITIES,
|
|
||||||
__module__ = 'mysqlx_connection_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Connection.Capabilities)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Capabilities)
|
|
||||||
|
|
||||||
CapabilitiesGet = _reflection.GeneratedProtocolMessageType('CapabilitiesGet', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _CAPABILITIESGET,
|
|
||||||
__module__ = 'mysqlx_connection_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Connection.CapabilitiesGet)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(CapabilitiesGet)
|
|
||||||
|
|
||||||
CapabilitiesSet = _reflection.GeneratedProtocolMessageType('CapabilitiesSet', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _CAPABILITIESSET,
|
|
||||||
__module__ = 'mysqlx_connection_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Connection.CapabilitiesSet)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(CapabilitiesSet)
|
|
||||||
|
|
||||||
Close = _reflection.GeneratedProtocolMessageType('Close', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _CLOSE,
|
|
||||||
__module__ = 'mysqlx_connection_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Connection.Close)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Close)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
File diff suppressed because one or more lines are too long
@ -1,236 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_cursor.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
from mysqlx.protobuf import mysqlx_prepare_pb2
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_cursor.proto',
|
|
||||||
package='Mysqlx.Cursor',
|
|
||||||
serialized_pb=_b('\n\x13mysqlx_cursor.proto\x12\rMysqlx.Cursor\x1a\x14mysqlx_prepare.proto\"\xf2\x01\n\x04Open\x12\x11\n\tcursor_id\x18\x01 \x02(\r\x12.\n\x04stmt\x18\x04 \x02(\x0b\x32 .Mysqlx.Cursor.Open.OneOfMessage\x12\x12\n\nfetch_rows\x18\x05 \x01(\x04\x1a\x92\x01\n\x0cOneOfMessage\x12\x33\n\x04type\x18\x01 \x02(\x0e\x32%.Mysqlx.Cursor.Open.OneOfMessage.Type\x12\x30\n\x0fprepare_execute\x18\x02 \x01(\x0b\x32\x17.Mysqlx.Prepare.Execute\"\x1b\n\x04Type\x12\x13\n\x0fPREPARE_EXECUTE\x10\x00\".\n\x05\x46\x65tch\x12\x11\n\tcursor_id\x18\x01 \x02(\r\x12\x12\n\nfetch_rows\x18\x05 \x01(\x04\"\x1a\n\x05\x43lose\x12\x11\n\tcursor_id\x18\x01 \x02(\rB\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
,
|
|
||||||
dependencies=[mysqlx_prepare_pb2.DESCRIPTOR,])
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_OPEN_ONEOFMESSAGE_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.Cursor.Open.OneOfMessage.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='PREPARE_EXECUTE', index=0, number=0,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=276,
|
|
||||||
serialized_end=303,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_OPEN_ONEOFMESSAGE_TYPE)
|
|
||||||
|
|
||||||
|
|
||||||
_OPEN_ONEOFMESSAGE = _descriptor.Descriptor(
|
|
||||||
name='OneOfMessage',
|
|
||||||
full_name='Mysqlx.Cursor.Open.OneOfMessage',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='type', full_name='Mysqlx.Cursor.Open.OneOfMessage.type', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='prepare_execute', full_name='Mysqlx.Cursor.Open.OneOfMessage.prepare_execute', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_OPEN_ONEOFMESSAGE_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=157,
|
|
||||||
serialized_end=303,
|
|
||||||
)
|
|
||||||
|
|
||||||
_OPEN = _descriptor.Descriptor(
|
|
||||||
name='Open',
|
|
||||||
full_name='Mysqlx.Cursor.Open',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='cursor_id', full_name='Mysqlx.Cursor.Open.cursor_id', index=0,
|
|
||||||
number=1, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='stmt', full_name='Mysqlx.Cursor.Open.stmt', index=1,
|
|
||||||
number=4, type=11, cpp_type=10, label=2,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='fetch_rows', full_name='Mysqlx.Cursor.Open.fetch_rows', index=2,
|
|
||||||
number=5, type=4, cpp_type=4, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[_OPEN_ONEOFMESSAGE, ],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=61,
|
|
||||||
serialized_end=303,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_FETCH = _descriptor.Descriptor(
|
|
||||||
name='Fetch',
|
|
||||||
full_name='Mysqlx.Cursor.Fetch',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='cursor_id', full_name='Mysqlx.Cursor.Fetch.cursor_id', index=0,
|
|
||||||
number=1, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='fetch_rows', full_name='Mysqlx.Cursor.Fetch.fetch_rows', index=1,
|
|
||||||
number=5, type=4, cpp_type=4, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=305,
|
|
||||||
serialized_end=351,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_CLOSE = _descriptor.Descriptor(
|
|
||||||
name='Close',
|
|
||||||
full_name='Mysqlx.Cursor.Close',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='cursor_id', full_name='Mysqlx.Cursor.Close.cursor_id', index=0,
|
|
||||||
number=1, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=353,
|
|
||||||
serialized_end=379,
|
|
||||||
)
|
|
||||||
|
|
||||||
_OPEN_ONEOFMESSAGE.fields_by_name['type'].enum_type = _OPEN_ONEOFMESSAGE_TYPE
|
|
||||||
_OPEN_ONEOFMESSAGE.fields_by_name['prepare_execute'].message_type = mysqlx_prepare_pb2._EXECUTE
|
|
||||||
_OPEN_ONEOFMESSAGE.containing_type = _OPEN
|
|
||||||
_OPEN_ONEOFMESSAGE_TYPE.containing_type = _OPEN_ONEOFMESSAGE
|
|
||||||
_OPEN.fields_by_name['stmt'].message_type = _OPEN_ONEOFMESSAGE
|
|
||||||
DESCRIPTOR.message_types_by_name['Open'] = _OPEN
|
|
||||||
DESCRIPTOR.message_types_by_name['Fetch'] = _FETCH
|
|
||||||
DESCRIPTOR.message_types_by_name['Close'] = _CLOSE
|
|
||||||
|
|
||||||
Open = _reflection.GeneratedProtocolMessageType('Open', (_message.Message,), dict(
|
|
||||||
|
|
||||||
OneOfMessage = _reflection.GeneratedProtocolMessageType('OneOfMessage', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _OPEN_ONEOFMESSAGE,
|
|
||||||
__module__ = 'mysqlx_cursor_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Cursor.Open.OneOfMessage)
|
|
||||||
))
|
|
||||||
,
|
|
||||||
DESCRIPTOR = _OPEN,
|
|
||||||
__module__ = 'mysqlx_cursor_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Cursor.Open)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Open)
|
|
||||||
_sym_db.RegisterMessage(Open.OneOfMessage)
|
|
||||||
|
|
||||||
Fetch = _reflection.GeneratedProtocolMessageType('Fetch', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _FETCH,
|
|
||||||
__module__ = 'mysqlx_cursor_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Cursor.Fetch)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Fetch)
|
|
||||||
|
|
||||||
Close = _reflection.GeneratedProtocolMessageType('Close', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _CLOSE,
|
|
||||||
__module__ = 'mysqlx_cursor_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Cursor.Close)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Close)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,474 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_datatypes.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_datatypes.proto',
|
|
||||||
package='Mysqlx.Datatypes',
|
|
||||||
serialized_pb=_b('\n\x16mysqlx_datatypes.proto\x12\x10Mysqlx.Datatypes\"\xc6\x03\n\x06Scalar\x12+\n\x04type\x18\x01 \x02(\x0e\x32\x1d.Mysqlx.Datatypes.Scalar.Type\x12\x14\n\x0cv_signed_int\x18\x02 \x01(\x12\x12\x16\n\x0ev_unsigned_int\x18\x03 \x01(\x04\x12\x31\n\x08v_octets\x18\x05 \x01(\x0b\x32\x1f.Mysqlx.Datatypes.Scalar.Octets\x12\x10\n\x08v_double\x18\x06 \x01(\x01\x12\x0f\n\x07v_float\x18\x07 \x01(\x02\x12\x0e\n\x06v_bool\x18\x08 \x01(\x08\x12\x31\n\x08v_string\x18\t \x01(\x0b\x32\x1f.Mysqlx.Datatypes.Scalar.String\x1a*\n\x06String\x12\r\n\x05value\x18\x01 \x02(\x0c\x12\x11\n\tcollation\x18\x02 \x01(\x04\x1a-\n\x06Octets\x12\r\n\x05value\x18\x01 \x02(\x0c\x12\x14\n\x0c\x63ontent_type\x18\x02 \x01(\r\"m\n\x04Type\x12\n\n\x06V_SINT\x10\x01\x12\n\n\x06V_UINT\x10\x02\x12\n\n\x06V_NULL\x10\x03\x12\x0c\n\x08V_OCTETS\x10\x04\x12\x0c\n\x08V_DOUBLE\x10\x05\x12\x0b\n\x07V_FLOAT\x10\x06\x12\n\n\x06V_BOOL\x10\x07\x12\x0c\n\x08V_STRING\x10\x08\"}\n\x06Object\x12\x31\n\x03\x66ld\x18\x01 \x03(\x0b\x32$.Mysqlx.Datatypes.Object.ObjectField\x1a@\n\x0bObjectField\x12\x0b\n\x03key\x18\x01 \x02(\t\x12$\n\x05value\x18\x02 \x02(\x0b\x32\x15.Mysqlx.Datatypes.Any\"-\n\x05\x41rray\x12$\n\x05value\x18\x01 \x03(\x0b\x32\x15.Mysqlx.Datatypes.Any\"\xd3\x01\n\x03\x41ny\x12(\n\x04type\x18\x01 \x02(\x0e\x32\x1a.Mysqlx.Datatypes.Any.Type\x12(\n\x06scalar\x18\x02 \x01(\x0b\x32\x18.Mysqlx.Datatypes.Scalar\x12%\n\x03obj\x18\x03 \x01(\x0b\x32\x18.Mysqlx.Datatypes.Object\x12&\n\x05\x61rray\x18\x04 \x01(\x0b\x32\x17.Mysqlx.Datatypes.Array\")\n\x04Type\x12\n\n\x06SCALAR\x10\x01\x12\n\n\x06OBJECT\x10\x02\x12\t\n\x05\x41RRAY\x10\x03\x42\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
)
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_SCALAR_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.Datatypes.Scalar.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='V_SINT', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='V_UINT', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='V_NULL', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='V_OCTETS', index=3, number=4,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='V_DOUBLE', index=4, number=5,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='V_FLOAT', index=5, number=6,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='V_BOOL', index=6, number=7,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='V_STRING', index=7, number=8,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=390,
|
|
||||||
serialized_end=499,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_SCALAR_TYPE)
|
|
||||||
|
|
||||||
_ANY_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.Datatypes.Any.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SCALAR', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='OBJECT', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ARRAY', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=846,
|
|
||||||
serialized_end=887,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_ANY_TYPE)
|
|
||||||
|
|
||||||
|
|
||||||
_SCALAR_STRING = _descriptor.Descriptor(
|
|
||||||
name='String',
|
|
||||||
full_name='Mysqlx.Datatypes.Scalar.String',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Datatypes.Scalar.String.value', index=0,
|
|
||||||
number=1, type=12, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='collation', full_name='Mysqlx.Datatypes.Scalar.String.collation', index=1,
|
|
||||||
number=2, type=4, cpp_type=4, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=299,
|
|
||||||
serialized_end=341,
|
|
||||||
)
|
|
||||||
|
|
||||||
_SCALAR_OCTETS = _descriptor.Descriptor(
|
|
||||||
name='Octets',
|
|
||||||
full_name='Mysqlx.Datatypes.Scalar.Octets',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Datatypes.Scalar.Octets.value', index=0,
|
|
||||||
number=1, type=12, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='content_type', full_name='Mysqlx.Datatypes.Scalar.Octets.content_type', index=1,
|
|
||||||
number=2, type=13, cpp_type=3, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=343,
|
|
||||||
serialized_end=388,
|
|
||||||
)
|
|
||||||
|
|
||||||
_SCALAR = _descriptor.Descriptor(
|
|
||||||
name='Scalar',
|
|
||||||
full_name='Mysqlx.Datatypes.Scalar',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='type', full_name='Mysqlx.Datatypes.Scalar.type', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=2,
|
|
||||||
has_default_value=False, default_value=1,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='v_signed_int', full_name='Mysqlx.Datatypes.Scalar.v_signed_int', index=1,
|
|
||||||
number=2, type=18, cpp_type=2, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='v_unsigned_int', full_name='Mysqlx.Datatypes.Scalar.v_unsigned_int', index=2,
|
|
||||||
number=3, type=4, cpp_type=4, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='v_octets', full_name='Mysqlx.Datatypes.Scalar.v_octets', index=3,
|
|
||||||
number=5, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='v_double', full_name='Mysqlx.Datatypes.Scalar.v_double', index=4,
|
|
||||||
number=6, type=1, cpp_type=5, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='v_float', full_name='Mysqlx.Datatypes.Scalar.v_float', index=5,
|
|
||||||
number=7, type=2, cpp_type=6, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='v_bool', full_name='Mysqlx.Datatypes.Scalar.v_bool', index=6,
|
|
||||||
number=8, type=8, cpp_type=7, label=1,
|
|
||||||
has_default_value=False, default_value=False,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='v_string', full_name='Mysqlx.Datatypes.Scalar.v_string', index=7,
|
|
||||||
number=9, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[_SCALAR_STRING, _SCALAR_OCTETS, ],
|
|
||||||
enum_types=[
|
|
||||||
_SCALAR_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=45,
|
|
||||||
serialized_end=499,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_OBJECT_OBJECTFIELD = _descriptor.Descriptor(
|
|
||||||
name='ObjectField',
|
|
||||||
full_name='Mysqlx.Datatypes.Object.ObjectField',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='key', full_name='Mysqlx.Datatypes.Object.ObjectField.key', index=0,
|
|
||||||
number=1, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Datatypes.Object.ObjectField.value', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=2,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=562,
|
|
||||||
serialized_end=626,
|
|
||||||
)
|
|
||||||
|
|
||||||
_OBJECT = _descriptor.Descriptor(
|
|
||||||
name='Object',
|
|
||||||
full_name='Mysqlx.Datatypes.Object',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='fld', full_name='Mysqlx.Datatypes.Object.fld', index=0,
|
|
||||||
number=1, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[_OBJECT_OBJECTFIELD, ],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=501,
|
|
||||||
serialized_end=626,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_ARRAY = _descriptor.Descriptor(
|
|
||||||
name='Array',
|
|
||||||
full_name='Mysqlx.Datatypes.Array',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Datatypes.Array.value', index=0,
|
|
||||||
number=1, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=628,
|
|
||||||
serialized_end=673,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_ANY = _descriptor.Descriptor(
|
|
||||||
name='Any',
|
|
||||||
full_name='Mysqlx.Datatypes.Any',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='type', full_name='Mysqlx.Datatypes.Any.type', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=2,
|
|
||||||
has_default_value=False, default_value=1,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='scalar', full_name='Mysqlx.Datatypes.Any.scalar', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='obj', full_name='Mysqlx.Datatypes.Any.obj', index=2,
|
|
||||||
number=3, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='array', full_name='Mysqlx.Datatypes.Any.array', index=3,
|
|
||||||
number=4, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_ANY_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=676,
|
|
||||||
serialized_end=887,
|
|
||||||
)
|
|
||||||
|
|
||||||
_SCALAR_STRING.containing_type = _SCALAR
|
|
||||||
_SCALAR_OCTETS.containing_type = _SCALAR
|
|
||||||
_SCALAR.fields_by_name['type'].enum_type = _SCALAR_TYPE
|
|
||||||
_SCALAR.fields_by_name['v_octets'].message_type = _SCALAR_OCTETS
|
|
||||||
_SCALAR.fields_by_name['v_string'].message_type = _SCALAR_STRING
|
|
||||||
_SCALAR_TYPE.containing_type = _SCALAR
|
|
||||||
_OBJECT_OBJECTFIELD.fields_by_name['value'].message_type = _ANY
|
|
||||||
_OBJECT_OBJECTFIELD.containing_type = _OBJECT
|
|
||||||
_OBJECT.fields_by_name['fld'].message_type = _OBJECT_OBJECTFIELD
|
|
||||||
_ARRAY.fields_by_name['value'].message_type = _ANY
|
|
||||||
_ANY.fields_by_name['type'].enum_type = _ANY_TYPE
|
|
||||||
_ANY.fields_by_name['scalar'].message_type = _SCALAR
|
|
||||||
_ANY.fields_by_name['obj'].message_type = _OBJECT
|
|
||||||
_ANY.fields_by_name['array'].message_type = _ARRAY
|
|
||||||
_ANY_TYPE.containing_type = _ANY
|
|
||||||
DESCRIPTOR.message_types_by_name['Scalar'] = _SCALAR
|
|
||||||
DESCRIPTOR.message_types_by_name['Object'] = _OBJECT
|
|
||||||
DESCRIPTOR.message_types_by_name['Array'] = _ARRAY
|
|
||||||
DESCRIPTOR.message_types_by_name['Any'] = _ANY
|
|
||||||
|
|
||||||
Scalar = _reflection.GeneratedProtocolMessageType('Scalar', (_message.Message,), dict(
|
|
||||||
|
|
||||||
String = _reflection.GeneratedProtocolMessageType('String', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _SCALAR_STRING,
|
|
||||||
__module__ = 'mysqlx_datatypes_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Datatypes.Scalar.String)
|
|
||||||
))
|
|
||||||
,
|
|
||||||
|
|
||||||
Octets = _reflection.GeneratedProtocolMessageType('Octets', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _SCALAR_OCTETS,
|
|
||||||
__module__ = 'mysqlx_datatypes_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Datatypes.Scalar.Octets)
|
|
||||||
))
|
|
||||||
,
|
|
||||||
DESCRIPTOR = _SCALAR,
|
|
||||||
__module__ = 'mysqlx_datatypes_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Datatypes.Scalar)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Scalar)
|
|
||||||
_sym_db.RegisterMessage(Scalar.String)
|
|
||||||
_sym_db.RegisterMessage(Scalar.Octets)
|
|
||||||
|
|
||||||
Object = _reflection.GeneratedProtocolMessageType('Object', (_message.Message,), dict(
|
|
||||||
|
|
||||||
ObjectField = _reflection.GeneratedProtocolMessageType('ObjectField', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _OBJECT_OBJECTFIELD,
|
|
||||||
__module__ = 'mysqlx_datatypes_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Datatypes.Object.ObjectField)
|
|
||||||
))
|
|
||||||
,
|
|
||||||
DESCRIPTOR = _OBJECT,
|
|
||||||
__module__ = 'mysqlx_datatypes_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Datatypes.Object)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Object)
|
|
||||||
_sym_db.RegisterMessage(Object.ObjectField)
|
|
||||||
|
|
||||||
Array = _reflection.GeneratedProtocolMessageType('Array', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _ARRAY,
|
|
||||||
__module__ = 'mysqlx_datatypes_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Datatypes.Array)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Array)
|
|
||||||
|
|
||||||
Any = _reflection.GeneratedProtocolMessageType('Any', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _ANY,
|
|
||||||
__module__ = 'mysqlx_datatypes_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Datatypes.Any)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Any)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,238 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_expect.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_expect.proto',
|
|
||||||
package='Mysqlx.Expect',
|
|
||||||
serialized_pb=_b('\n\x13mysqlx_expect.proto\x12\rMysqlx.Expect\"\xd0\x03\n\x04Open\x12\x42\n\x02op\x18\x01 \x01(\x0e\x32 .Mysqlx.Expect.Open.CtxOperation:\x14\x45XPECT_CTX_COPY_PREV\x12+\n\x04\x63ond\x18\x02 \x03(\x0b\x32\x1d.Mysqlx.Expect.Open.Condition\x1a\x96\x02\n\tCondition\x12\x15\n\rcondition_key\x18\x01 \x02(\r\x12\x17\n\x0f\x63ondition_value\x18\x02 \x01(\x0c\x12K\n\x02op\x18\x03 \x01(\x0e\x32\x30.Mysqlx.Expect.Open.Condition.ConditionOperation:\rEXPECT_OP_SET\"N\n\x03Key\x12\x13\n\x0f\x45XPECT_NO_ERROR\x10\x01\x12\x16\n\x12\x45XPECT_FIELD_EXIST\x10\x02\x12\x1a\n\x16\x45XPECT_DOCID_GENERATED\x10\x03\"<\n\x12\x43onditionOperation\x12\x11\n\rEXPECT_OP_SET\x10\x00\x12\x13\n\x0f\x45XPECT_OP_UNSET\x10\x01\">\n\x0c\x43txOperation\x12\x18\n\x14\x45XPECT_CTX_COPY_PREV\x10\x00\x12\x14\n\x10\x45XPECT_CTX_EMPTY\x10\x01\"\x07\n\x05\x43loseB\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
)
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_OPEN_CONDITION_KEY = _descriptor.EnumDescriptor(
|
|
||||||
name='Key',
|
|
||||||
full_name='Mysqlx.Expect.Open.Condition.Key',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='EXPECT_NO_ERROR', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='EXPECT_FIELD_EXIST', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='EXPECT_DOCID_GENERATED', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=299,
|
|
||||||
serialized_end=377,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_OPEN_CONDITION_KEY)
|
|
||||||
|
|
||||||
_OPEN_CONDITION_CONDITIONOPERATION = _descriptor.EnumDescriptor(
|
|
||||||
name='ConditionOperation',
|
|
||||||
full_name='Mysqlx.Expect.Open.Condition.ConditionOperation',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='EXPECT_OP_SET', index=0, number=0,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='EXPECT_OP_UNSET', index=1, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=379,
|
|
||||||
serialized_end=439,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_OPEN_CONDITION_CONDITIONOPERATION)
|
|
||||||
|
|
||||||
_OPEN_CTXOPERATION = _descriptor.EnumDescriptor(
|
|
||||||
name='CtxOperation',
|
|
||||||
full_name='Mysqlx.Expect.Open.CtxOperation',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='EXPECT_CTX_COPY_PREV', index=0, number=0,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='EXPECT_CTX_EMPTY', index=1, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=441,
|
|
||||||
serialized_end=503,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_OPEN_CTXOPERATION)
|
|
||||||
|
|
||||||
|
|
||||||
_OPEN_CONDITION = _descriptor.Descriptor(
|
|
||||||
name='Condition',
|
|
||||||
full_name='Mysqlx.Expect.Open.Condition',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='condition_key', full_name='Mysqlx.Expect.Open.Condition.condition_key', index=0,
|
|
||||||
number=1, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='condition_value', full_name='Mysqlx.Expect.Open.Condition.condition_value', index=1,
|
|
||||||
number=2, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='op', full_name='Mysqlx.Expect.Open.Condition.op', index=2,
|
|
||||||
number=3, type=14, cpp_type=8, label=1,
|
|
||||||
has_default_value=True, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_OPEN_CONDITION_KEY,
|
|
||||||
_OPEN_CONDITION_CONDITIONOPERATION,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=161,
|
|
||||||
serialized_end=439,
|
|
||||||
)
|
|
||||||
|
|
||||||
_OPEN = _descriptor.Descriptor(
|
|
||||||
name='Open',
|
|
||||||
full_name='Mysqlx.Expect.Open',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='op', full_name='Mysqlx.Expect.Open.op', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=1,
|
|
||||||
has_default_value=True, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='cond', full_name='Mysqlx.Expect.Open.cond', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[_OPEN_CONDITION, ],
|
|
||||||
enum_types=[
|
|
||||||
_OPEN_CTXOPERATION,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=39,
|
|
||||||
serialized_end=503,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_CLOSE = _descriptor.Descriptor(
|
|
||||||
name='Close',
|
|
||||||
full_name='Mysqlx.Expect.Close',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=505,
|
|
||||||
serialized_end=512,
|
|
||||||
)
|
|
||||||
|
|
||||||
_OPEN_CONDITION.fields_by_name['op'].enum_type = _OPEN_CONDITION_CONDITIONOPERATION
|
|
||||||
_OPEN_CONDITION.containing_type = _OPEN
|
|
||||||
_OPEN_CONDITION_KEY.containing_type = _OPEN_CONDITION
|
|
||||||
_OPEN_CONDITION_CONDITIONOPERATION.containing_type = _OPEN_CONDITION
|
|
||||||
_OPEN.fields_by_name['op'].enum_type = _OPEN_CTXOPERATION
|
|
||||||
_OPEN.fields_by_name['cond'].message_type = _OPEN_CONDITION
|
|
||||||
_OPEN_CTXOPERATION.containing_type = _OPEN
|
|
||||||
DESCRIPTOR.message_types_by_name['Open'] = _OPEN
|
|
||||||
DESCRIPTOR.message_types_by_name['Close'] = _CLOSE
|
|
||||||
|
|
||||||
Open = _reflection.GeneratedProtocolMessageType('Open', (_message.Message,), dict(
|
|
||||||
|
|
||||||
Condition = _reflection.GeneratedProtocolMessageType('Condition', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _OPEN_CONDITION,
|
|
||||||
__module__ = 'mysqlx_expect_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expect.Open.Condition)
|
|
||||||
))
|
|
||||||
,
|
|
||||||
DESCRIPTOR = _OPEN,
|
|
||||||
__module__ = 'mysqlx_expect_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expect.Open)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Open)
|
|
||||||
_sym_db.RegisterMessage(Open.Condition)
|
|
||||||
|
|
||||||
Close = _reflection.GeneratedProtocolMessageType('Close', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _CLOSE,
|
|
||||||
__module__ = 'mysqlx_expect_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expect.Close)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Close)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,593 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_expr.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
from mysqlx.protobuf import mysqlx_datatypes_pb2
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_expr.proto',
|
|
||||||
package='Mysqlx.Expr',
|
|
||||||
serialized_pb=_b('\n\x11mysqlx_expr.proto\x12\x0bMysqlx.Expr\x1a\x16mysqlx_datatypes.proto\"\xc4\x03\n\x04\x45xpr\x12$\n\x04type\x18\x01 \x02(\x0e\x32\x16.Mysqlx.Expr.Expr.Type\x12\x31\n\nidentifier\x18\x02 \x01(\x0b\x32\x1d.Mysqlx.Expr.ColumnIdentifier\x12\x10\n\x08variable\x18\x03 \x01(\t\x12)\n\x07literal\x18\x04 \x01(\x0b\x32\x18.Mysqlx.Datatypes.Scalar\x12\x30\n\rfunction_call\x18\x05 \x01(\x0b\x32\x19.Mysqlx.Expr.FunctionCall\x12\'\n\x08operator\x18\x06 \x01(\x0b\x32\x15.Mysqlx.Expr.Operator\x12\x10\n\x08position\x18\x07 \x01(\r\x12#\n\x06object\x18\x08 \x01(\x0b\x32\x13.Mysqlx.Expr.Object\x12!\n\x05\x61rray\x18\t \x01(\x0b\x32\x12.Mysqlx.Expr.Array\"q\n\x04Type\x12\t\n\x05IDENT\x10\x01\x12\x0b\n\x07LITERAL\x10\x02\x12\x0c\n\x08VARIABLE\x10\x03\x12\r\n\tFUNC_CALL\x10\x04\x12\x0c\n\x08OPERATOR\x10\x05\x12\x0f\n\x0bPLACEHOLDER\x10\x06\x12\n\n\x06OBJECT\x10\x07\x12\t\n\x05\x41RRAY\x10\x08\"/\n\nIdentifier\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\x13\n\x0bschema_name\x18\x02 \x01(\t\"\xcb\x01\n\x10\x44ocumentPathItem\x12\x30\n\x04type\x18\x01 \x02(\x0e\x32\".Mysqlx.Expr.DocumentPathItem.Type\x12\r\n\x05value\x18\x02 \x01(\t\x12\r\n\x05index\x18\x03 \x01(\r\"g\n\x04Type\x12\n\n\x06MEMBER\x10\x01\x12\x13\n\x0fMEMBER_ASTERISK\x10\x02\x12\x0f\n\x0b\x41RRAY_INDEX\x10\x03\x12\x18\n\x14\x41RRAY_INDEX_ASTERISK\x10\x04\x12\x13\n\x0f\x44OUBLE_ASTERISK\x10\x05\"\x7f\n\x10\x43olumnIdentifier\x12\x34\n\rdocument_path\x18\x01 \x03(\x0b\x32\x1d.Mysqlx.Expr.DocumentPathItem\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x12\n\ntable_name\x18\x03 \x01(\t\x12\x13\n\x0bschema_name\x18\x04 \x01(\t\"W\n\x0c\x46unctionCall\x12%\n\x04name\x18\x01 \x02(\x0b\x32\x17.Mysqlx.Expr.Identifier\x12 \n\x05param\x18\x02 \x03(\x0b\x32\x11.Mysqlx.Expr.Expr\":\n\x08Operator\x12\x0c\n\x04name\x18\x01 \x02(\t\x12 \n\x05param\x18\x02 \x03(\x0b\x32\x11.Mysqlx.Expr.Expr\"t\n\x06Object\x12,\n\x03\x66ld\x18\x01 \x03(\x0b\x32\x1f.Mysqlx.Expr.Object.ObjectField\x1a<\n\x0bObjectField\x12\x0b\n\x03key\x18\x01 \x02(\t\x12 \n\x05value\x18\x02 \x02(\x0b\x32\x11.Mysqlx.Expr.Expr\")\n\x05\x41rray\x12 \n\x05value\x18\x01 \x03(\x0b\x32\x11.Mysqlx.Expr.ExprB\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
,
|
|
||||||
dependencies=[mysqlx_datatypes_pb2.DESCRIPTOR,])
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_EXPR_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.Expr.Expr.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='IDENT', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='LITERAL', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='VARIABLE', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='FUNC_CALL', index=3, number=4,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='OPERATOR', index=4, number=5,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='PLACEHOLDER', index=5, number=6,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='OBJECT', index=6, number=7,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ARRAY', index=7, number=8,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=398,
|
|
||||||
serialized_end=511,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_EXPR_TYPE)
|
|
||||||
|
|
||||||
_DOCUMENTPATHITEM_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.Expr.DocumentPathItem.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='MEMBER', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='MEMBER_ASTERISK', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ARRAY_INDEX', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ARRAY_INDEX_ASTERISK', index=3, number=4,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='DOUBLE_ASTERISK', index=4, number=5,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=663,
|
|
||||||
serialized_end=766,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_DOCUMENTPATHITEM_TYPE)
|
|
||||||
|
|
||||||
|
|
||||||
_EXPR = _descriptor.Descriptor(
|
|
||||||
name='Expr',
|
|
||||||
full_name='Mysqlx.Expr.Expr',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='type', full_name='Mysqlx.Expr.Expr.type', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=2,
|
|
||||||
has_default_value=False, default_value=1,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='identifier', full_name='Mysqlx.Expr.Expr.identifier', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='variable', full_name='Mysqlx.Expr.Expr.variable', index=2,
|
|
||||||
number=3, type=9, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='literal', full_name='Mysqlx.Expr.Expr.literal', index=3,
|
|
||||||
number=4, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='function_call', full_name='Mysqlx.Expr.Expr.function_call', index=4,
|
|
||||||
number=5, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='operator', full_name='Mysqlx.Expr.Expr.operator', index=5,
|
|
||||||
number=6, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='position', full_name='Mysqlx.Expr.Expr.position', index=6,
|
|
||||||
number=7, type=13, cpp_type=3, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='object', full_name='Mysqlx.Expr.Expr.object', index=7,
|
|
||||||
number=8, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='array', full_name='Mysqlx.Expr.Expr.array', index=8,
|
|
||||||
number=9, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_EXPR_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=59,
|
|
||||||
serialized_end=511,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_IDENTIFIER = _descriptor.Descriptor(
|
|
||||||
name='Identifier',
|
|
||||||
full_name='Mysqlx.Expr.Identifier',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='name', full_name='Mysqlx.Expr.Identifier.name', index=0,
|
|
||||||
number=1, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='schema_name', full_name='Mysqlx.Expr.Identifier.schema_name', index=1,
|
|
||||||
number=2, type=9, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=513,
|
|
||||||
serialized_end=560,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_DOCUMENTPATHITEM = _descriptor.Descriptor(
|
|
||||||
name='DocumentPathItem',
|
|
||||||
full_name='Mysqlx.Expr.DocumentPathItem',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='type', full_name='Mysqlx.Expr.DocumentPathItem.type', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=2,
|
|
||||||
has_default_value=False, default_value=1,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Expr.DocumentPathItem.value', index=1,
|
|
||||||
number=2, type=9, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='index', full_name='Mysqlx.Expr.DocumentPathItem.index', index=2,
|
|
||||||
number=3, type=13, cpp_type=3, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_DOCUMENTPATHITEM_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=563,
|
|
||||||
serialized_end=766,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_COLUMNIDENTIFIER = _descriptor.Descriptor(
|
|
||||||
name='ColumnIdentifier',
|
|
||||||
full_name='Mysqlx.Expr.ColumnIdentifier',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='document_path', full_name='Mysqlx.Expr.ColumnIdentifier.document_path', index=0,
|
|
||||||
number=1, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='name', full_name='Mysqlx.Expr.ColumnIdentifier.name', index=1,
|
|
||||||
number=2, type=9, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='table_name', full_name='Mysqlx.Expr.ColumnIdentifier.table_name', index=2,
|
|
||||||
number=3, type=9, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='schema_name', full_name='Mysqlx.Expr.ColumnIdentifier.schema_name', index=3,
|
|
||||||
number=4, type=9, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=768,
|
|
||||||
serialized_end=895,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_FUNCTIONCALL = _descriptor.Descriptor(
|
|
||||||
name='FunctionCall',
|
|
||||||
full_name='Mysqlx.Expr.FunctionCall',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='name', full_name='Mysqlx.Expr.FunctionCall.name', index=0,
|
|
||||||
number=1, type=11, cpp_type=10, label=2,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='param', full_name='Mysqlx.Expr.FunctionCall.param', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=897,
|
|
||||||
serialized_end=984,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_OPERATOR = _descriptor.Descriptor(
|
|
||||||
name='Operator',
|
|
||||||
full_name='Mysqlx.Expr.Operator',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='name', full_name='Mysqlx.Expr.Operator.name', index=0,
|
|
||||||
number=1, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='param', full_name='Mysqlx.Expr.Operator.param', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=986,
|
|
||||||
serialized_end=1044,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_OBJECT_OBJECTFIELD = _descriptor.Descriptor(
|
|
||||||
name='ObjectField',
|
|
||||||
full_name='Mysqlx.Expr.Object.ObjectField',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='key', full_name='Mysqlx.Expr.Object.ObjectField.key', index=0,
|
|
||||||
number=1, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Expr.Object.ObjectField.value', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=2,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=1102,
|
|
||||||
serialized_end=1162,
|
|
||||||
)
|
|
||||||
|
|
||||||
_OBJECT = _descriptor.Descriptor(
|
|
||||||
name='Object',
|
|
||||||
full_name='Mysqlx.Expr.Object',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='fld', full_name='Mysqlx.Expr.Object.fld', index=0,
|
|
||||||
number=1, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[_OBJECT_OBJECTFIELD, ],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=1046,
|
|
||||||
serialized_end=1162,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_ARRAY = _descriptor.Descriptor(
|
|
||||||
name='Array',
|
|
||||||
full_name='Mysqlx.Expr.Array',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Expr.Array.value', index=0,
|
|
||||||
number=1, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=1164,
|
|
||||||
serialized_end=1205,
|
|
||||||
)
|
|
||||||
|
|
||||||
_EXPR.fields_by_name['type'].enum_type = _EXPR_TYPE
|
|
||||||
_EXPR.fields_by_name['identifier'].message_type = _COLUMNIDENTIFIER
|
|
||||||
_EXPR.fields_by_name['literal'].message_type = mysqlx_datatypes_pb2._SCALAR
|
|
||||||
_EXPR.fields_by_name['function_call'].message_type = _FUNCTIONCALL
|
|
||||||
_EXPR.fields_by_name['operator'].message_type = _OPERATOR
|
|
||||||
_EXPR.fields_by_name['object'].message_type = _OBJECT
|
|
||||||
_EXPR.fields_by_name['array'].message_type = _ARRAY
|
|
||||||
_EXPR_TYPE.containing_type = _EXPR
|
|
||||||
_DOCUMENTPATHITEM.fields_by_name['type'].enum_type = _DOCUMENTPATHITEM_TYPE
|
|
||||||
_DOCUMENTPATHITEM_TYPE.containing_type = _DOCUMENTPATHITEM
|
|
||||||
_COLUMNIDENTIFIER.fields_by_name['document_path'].message_type = _DOCUMENTPATHITEM
|
|
||||||
_FUNCTIONCALL.fields_by_name['name'].message_type = _IDENTIFIER
|
|
||||||
_FUNCTIONCALL.fields_by_name['param'].message_type = _EXPR
|
|
||||||
_OPERATOR.fields_by_name['param'].message_type = _EXPR
|
|
||||||
_OBJECT_OBJECTFIELD.fields_by_name['value'].message_type = _EXPR
|
|
||||||
_OBJECT_OBJECTFIELD.containing_type = _OBJECT
|
|
||||||
_OBJECT.fields_by_name['fld'].message_type = _OBJECT_OBJECTFIELD
|
|
||||||
_ARRAY.fields_by_name['value'].message_type = _EXPR
|
|
||||||
DESCRIPTOR.message_types_by_name['Expr'] = _EXPR
|
|
||||||
DESCRIPTOR.message_types_by_name['Identifier'] = _IDENTIFIER
|
|
||||||
DESCRIPTOR.message_types_by_name['DocumentPathItem'] = _DOCUMENTPATHITEM
|
|
||||||
DESCRIPTOR.message_types_by_name['ColumnIdentifier'] = _COLUMNIDENTIFIER
|
|
||||||
DESCRIPTOR.message_types_by_name['FunctionCall'] = _FUNCTIONCALL
|
|
||||||
DESCRIPTOR.message_types_by_name['Operator'] = _OPERATOR
|
|
||||||
DESCRIPTOR.message_types_by_name['Object'] = _OBJECT
|
|
||||||
DESCRIPTOR.message_types_by_name['Array'] = _ARRAY
|
|
||||||
|
|
||||||
Expr = _reflection.GeneratedProtocolMessageType('Expr', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _EXPR,
|
|
||||||
__module__ = 'mysqlx_expr_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expr.Expr)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Expr)
|
|
||||||
|
|
||||||
Identifier = _reflection.GeneratedProtocolMessageType('Identifier', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _IDENTIFIER,
|
|
||||||
__module__ = 'mysqlx_expr_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expr.Identifier)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Identifier)
|
|
||||||
|
|
||||||
DocumentPathItem = _reflection.GeneratedProtocolMessageType('DocumentPathItem', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _DOCUMENTPATHITEM,
|
|
||||||
__module__ = 'mysqlx_expr_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expr.DocumentPathItem)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(DocumentPathItem)
|
|
||||||
|
|
||||||
ColumnIdentifier = _reflection.GeneratedProtocolMessageType('ColumnIdentifier', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _COLUMNIDENTIFIER,
|
|
||||||
__module__ = 'mysqlx_expr_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expr.ColumnIdentifier)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(ColumnIdentifier)
|
|
||||||
|
|
||||||
FunctionCall = _reflection.GeneratedProtocolMessageType('FunctionCall', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _FUNCTIONCALL,
|
|
||||||
__module__ = 'mysqlx_expr_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expr.FunctionCall)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(FunctionCall)
|
|
||||||
|
|
||||||
Operator = _reflection.GeneratedProtocolMessageType('Operator', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _OPERATOR,
|
|
||||||
__module__ = 'mysqlx_expr_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expr.Operator)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Operator)
|
|
||||||
|
|
||||||
Object = _reflection.GeneratedProtocolMessageType('Object', (_message.Message,), dict(
|
|
||||||
|
|
||||||
ObjectField = _reflection.GeneratedProtocolMessageType('ObjectField', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _OBJECT_OBJECTFIELD,
|
|
||||||
__module__ = 'mysqlx_expr_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expr.Object.ObjectField)
|
|
||||||
))
|
|
||||||
,
|
|
||||||
DESCRIPTOR = _OBJECT,
|
|
||||||
__module__ = 'mysqlx_expr_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expr.Object)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Object)
|
|
||||||
_sym_db.RegisterMessage(Object.ObjectField)
|
|
||||||
|
|
||||||
Array = _reflection.GeneratedProtocolMessageType('Array', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _ARRAY,
|
|
||||||
__module__ = 'mysqlx_expr_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Expr.Array)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Array)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,453 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_notice.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
from mysqlx.protobuf import mysqlx_datatypes_pb2
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_notice.proto',
|
|
||||||
package='Mysqlx.Notice',
|
|
||||||
serialized_pb=_b('\n\x13mysqlx_notice.proto\x12\rMysqlx.Notice\x1a\x16mysqlx_datatypes.proto\"\xec\x01\n\x05\x46rame\x12\x0c\n\x04type\x18\x01 \x02(\r\x12\x31\n\x05scope\x18\x02 \x01(\x0e\x32\x1a.Mysqlx.Notice.Frame.Scope:\x06GLOBAL\x12\x0f\n\x07payload\x18\x03 \x01(\x0c\"\x1e\n\x05Scope\x12\n\n\x06GLOBAL\x10\x01\x12\t\n\x05LOCAL\x10\x02\"q\n\x04Type\x12\x0b\n\x07WARNING\x10\x01\x12\x1c\n\x18SESSION_VARIABLE_CHANGED\x10\x02\x12\x19\n\x15SESSION_STATE_CHANGED\x10\x03\x12#\n\x1fGROUP_REPLICATION_STATE_CHANGED\x10\x04\"\x85\x01\n\x07Warning\x12\x34\n\x05level\x18\x01 \x01(\x0e\x32\x1c.Mysqlx.Notice.Warning.Level:\x07WARNING\x12\x0c\n\x04\x63ode\x18\x02 \x02(\r\x12\x0b\n\x03msg\x18\x03 \x02(\t\")\n\x05Level\x12\x08\n\x04NOTE\x10\x01\x12\x0b\n\x07WARNING\x10\x02\x12\t\n\x05\x45RROR\x10\x03\"P\n\x16SessionVariableChanged\x12\r\n\x05param\x18\x01 \x02(\t\x12\'\n\x05value\x18\x02 \x01(\x0b\x32\x18.Mysqlx.Datatypes.Scalar\"\xf1\x02\n\x13SessionStateChanged\x12;\n\x05param\x18\x01 \x02(\x0e\x32,.Mysqlx.Notice.SessionStateChanged.Parameter\x12\'\n\x05value\x18\x02 \x03(\x0b\x32\x18.Mysqlx.Datatypes.Scalar\"\xf3\x01\n\tParameter\x12\x12\n\x0e\x43URRENT_SCHEMA\x10\x01\x12\x13\n\x0f\x41\x43\x43OUNT_EXPIRED\x10\x02\x12\x17\n\x13GENERATED_INSERT_ID\x10\x03\x12\x11\n\rROWS_AFFECTED\x10\x04\x12\x0e\n\nROWS_FOUND\x10\x05\x12\x10\n\x0cROWS_MATCHED\x10\x06\x12\x11\n\rTRX_COMMITTED\x10\x07\x12\x12\n\x0eTRX_ROLLEDBACK\x10\t\x12\x14\n\x10PRODUCED_MESSAGE\x10\n\x12\x16\n\x12\x43LIENT_ID_ASSIGNED\x10\x0b\x12\x1a\n\x16GENERATED_DOCUMENT_IDS\x10\x0c\"\xae\x01\n\x1cGroupReplicationStateChanged\x12\x0c\n\x04type\x18\x01 \x02(\r\x12\x0f\n\x07view_id\x18\x02 \x01(\t\"o\n\x04Type\x12\x1a\n\x16MEMBERSHIP_QUORUM_LOSS\x10\x01\x12\x1a\n\x16MEMBERSHIP_VIEW_CHANGE\x10\x02\x12\x16\n\x12MEMBER_ROLE_CHANGE\x10\x03\x12\x17\n\x13MEMBER_STATE_CHANGE\x10\x04\x42\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
,
|
|
||||||
dependencies=[mysqlx_datatypes_pb2.DESCRIPTOR,])
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_FRAME_SCOPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Scope',
|
|
||||||
full_name='Mysqlx.Notice.Frame.Scope',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='GLOBAL', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='LOCAL', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=154,
|
|
||||||
serialized_end=184,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_FRAME_SCOPE)
|
|
||||||
|
|
||||||
_FRAME_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.Notice.Frame.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='WARNING', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SESSION_VARIABLE_CHANGED', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SESSION_STATE_CHANGED', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='GROUP_REPLICATION_STATE_CHANGED', index=3, number=4,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=186,
|
|
||||||
serialized_end=299,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_FRAME_TYPE)
|
|
||||||
|
|
||||||
_WARNING_LEVEL = _descriptor.EnumDescriptor(
|
|
||||||
name='Level',
|
|
||||||
full_name='Mysqlx.Notice.Warning.Level',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='NOTE', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='WARNING', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ERROR', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=394,
|
|
||||||
serialized_end=435,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_WARNING_LEVEL)
|
|
||||||
|
|
||||||
_SESSIONSTATECHANGED_PARAMETER = _descriptor.EnumDescriptor(
|
|
||||||
name='Parameter',
|
|
||||||
full_name='Mysqlx.Notice.SessionStateChanged.Parameter',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CURRENT_SCHEMA', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ACCOUNT_EXPIRED', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='GENERATED_INSERT_ID', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ROWS_AFFECTED', index=3, number=4,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ROWS_FOUND', index=4, number=5,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ROWS_MATCHED', index=5, number=6,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='TRX_COMMITTED', index=6, number=7,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='TRX_ROLLEDBACK', index=7, number=9,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='PRODUCED_MESSAGE', index=8, number=10,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CLIENT_ID_ASSIGNED', index=9, number=11,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='GENERATED_DOCUMENT_IDS', index=10, number=12,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=646,
|
|
||||||
serialized_end=889,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_SESSIONSTATECHANGED_PARAMETER)
|
|
||||||
|
|
||||||
_GROUPREPLICATIONSTATECHANGED_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.Notice.GroupReplicationStateChanged.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='MEMBERSHIP_QUORUM_LOSS', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='MEMBERSHIP_VIEW_CHANGE', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='MEMBER_ROLE_CHANGE', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='MEMBER_STATE_CHANGE', index=3, number=4,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=955,
|
|
||||||
serialized_end=1066,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_GROUPREPLICATIONSTATECHANGED_TYPE)
|
|
||||||
|
|
||||||
|
|
||||||
_FRAME = _descriptor.Descriptor(
|
|
||||||
name='Frame',
|
|
||||||
full_name='Mysqlx.Notice.Frame',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='type', full_name='Mysqlx.Notice.Frame.type', index=0,
|
|
||||||
number=1, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='scope', full_name='Mysqlx.Notice.Frame.scope', index=1,
|
|
||||||
number=2, type=14, cpp_type=8, label=1,
|
|
||||||
has_default_value=True, default_value=1,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='payload', full_name='Mysqlx.Notice.Frame.payload', index=2,
|
|
||||||
number=3, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_FRAME_SCOPE,
|
|
||||||
_FRAME_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=63,
|
|
||||||
serialized_end=299,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_WARNING = _descriptor.Descriptor(
|
|
||||||
name='Warning',
|
|
||||||
full_name='Mysqlx.Notice.Warning',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='level', full_name='Mysqlx.Notice.Warning.level', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=1,
|
|
||||||
has_default_value=True, default_value=2,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='code', full_name='Mysqlx.Notice.Warning.code', index=1,
|
|
||||||
number=2, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='msg', full_name='Mysqlx.Notice.Warning.msg', index=2,
|
|
||||||
number=3, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_WARNING_LEVEL,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=302,
|
|
||||||
serialized_end=435,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_SESSIONVARIABLECHANGED = _descriptor.Descriptor(
|
|
||||||
name='SessionVariableChanged',
|
|
||||||
full_name='Mysqlx.Notice.SessionVariableChanged',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='param', full_name='Mysqlx.Notice.SessionVariableChanged.param', index=0,
|
|
||||||
number=1, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Notice.SessionVariableChanged.value', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=437,
|
|
||||||
serialized_end=517,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_SESSIONSTATECHANGED = _descriptor.Descriptor(
|
|
||||||
name='SessionStateChanged',
|
|
||||||
full_name='Mysqlx.Notice.SessionStateChanged',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='param', full_name='Mysqlx.Notice.SessionStateChanged.param', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=2,
|
|
||||||
has_default_value=False, default_value=1,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='value', full_name='Mysqlx.Notice.SessionStateChanged.value', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_SESSIONSTATECHANGED_PARAMETER,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=520,
|
|
||||||
serialized_end=889,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_GROUPREPLICATIONSTATECHANGED = _descriptor.Descriptor(
|
|
||||||
name='GroupReplicationStateChanged',
|
|
||||||
full_name='Mysqlx.Notice.GroupReplicationStateChanged',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='type', full_name='Mysqlx.Notice.GroupReplicationStateChanged.type', index=0,
|
|
||||||
number=1, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='view_id', full_name='Mysqlx.Notice.GroupReplicationStateChanged.view_id', index=1,
|
|
||||||
number=2, type=9, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_GROUPREPLICATIONSTATECHANGED_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=892,
|
|
||||||
serialized_end=1066,
|
|
||||||
)
|
|
||||||
|
|
||||||
_FRAME.fields_by_name['scope'].enum_type = _FRAME_SCOPE
|
|
||||||
_FRAME_SCOPE.containing_type = _FRAME
|
|
||||||
_FRAME_TYPE.containing_type = _FRAME
|
|
||||||
_WARNING.fields_by_name['level'].enum_type = _WARNING_LEVEL
|
|
||||||
_WARNING_LEVEL.containing_type = _WARNING
|
|
||||||
_SESSIONVARIABLECHANGED.fields_by_name['value'].message_type = mysqlx_datatypes_pb2._SCALAR
|
|
||||||
_SESSIONSTATECHANGED.fields_by_name['param'].enum_type = _SESSIONSTATECHANGED_PARAMETER
|
|
||||||
_SESSIONSTATECHANGED.fields_by_name['value'].message_type = mysqlx_datatypes_pb2._SCALAR
|
|
||||||
_SESSIONSTATECHANGED_PARAMETER.containing_type = _SESSIONSTATECHANGED
|
|
||||||
_GROUPREPLICATIONSTATECHANGED_TYPE.containing_type = _GROUPREPLICATIONSTATECHANGED
|
|
||||||
DESCRIPTOR.message_types_by_name['Frame'] = _FRAME
|
|
||||||
DESCRIPTOR.message_types_by_name['Warning'] = _WARNING
|
|
||||||
DESCRIPTOR.message_types_by_name['SessionVariableChanged'] = _SESSIONVARIABLECHANGED
|
|
||||||
DESCRIPTOR.message_types_by_name['SessionStateChanged'] = _SESSIONSTATECHANGED
|
|
||||||
DESCRIPTOR.message_types_by_name['GroupReplicationStateChanged'] = _GROUPREPLICATIONSTATECHANGED
|
|
||||||
|
|
||||||
Frame = _reflection.GeneratedProtocolMessageType('Frame', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _FRAME,
|
|
||||||
__module__ = 'mysqlx_notice_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Notice.Frame)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Frame)
|
|
||||||
|
|
||||||
Warning = _reflection.GeneratedProtocolMessageType('Warning', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _WARNING,
|
|
||||||
__module__ = 'mysqlx_notice_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Notice.Warning)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Warning)
|
|
||||||
|
|
||||||
SessionVariableChanged = _reflection.GeneratedProtocolMessageType('SessionVariableChanged', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _SESSIONVARIABLECHANGED,
|
|
||||||
__module__ = 'mysqlx_notice_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Notice.SessionVariableChanged)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(SessionVariableChanged)
|
|
||||||
|
|
||||||
SessionStateChanged = _reflection.GeneratedProtocolMessageType('SessionStateChanged', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _SESSIONSTATECHANGED,
|
|
||||||
__module__ = 'mysqlx_notice_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Notice.SessionStateChanged)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(SessionStateChanged)
|
|
||||||
|
|
||||||
GroupReplicationStateChanged = _reflection.GeneratedProtocolMessageType('GroupReplicationStateChanged', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _GROUPREPLICATIONSTATECHANGED,
|
|
||||||
__module__ = 'mysqlx_notice_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Notice.GroupReplicationStateChanged)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(GroupReplicationStateChanged)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,391 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx.proto',
|
|
||||||
package='Mysqlx',
|
|
||||||
serialized_pb=_b('\n\x0cmysqlx.proto\x12\x06Mysqlx\"\xeb\x03\n\x0e\x43lientMessages\"\xd8\x03\n\x04Type\x12\x18\n\x14\x43ON_CAPABILITIES_GET\x10\x01\x12\x18\n\x14\x43ON_CAPABILITIES_SET\x10\x02\x12\r\n\tCON_CLOSE\x10\x03\x12\x1b\n\x17SESS_AUTHENTICATE_START\x10\x04\x12\x1e\n\x1aSESS_AUTHENTICATE_CONTINUE\x10\x05\x12\x0e\n\nSESS_RESET\x10\x06\x12\x0e\n\nSESS_CLOSE\x10\x07\x12\x14\n\x10SQL_STMT_EXECUTE\x10\x0c\x12\r\n\tCRUD_FIND\x10\x11\x12\x0f\n\x0b\x43RUD_INSERT\x10\x12\x12\x0f\n\x0b\x43RUD_UPDATE\x10\x13\x12\x0f\n\x0b\x43RUD_DELETE\x10\x14\x12\x0f\n\x0b\x45XPECT_OPEN\x10\x18\x12\x10\n\x0c\x45XPECT_CLOSE\x10\x19\x12\x14\n\x10\x43RUD_CREATE_VIEW\x10\x1e\x12\x14\n\x10\x43RUD_MODIFY_VIEW\x10\x1f\x12\x12\n\x0e\x43RUD_DROP_VIEW\x10 \x12\x13\n\x0fPREPARE_PREPARE\x10(\x12\x13\n\x0fPREPARE_EXECUTE\x10)\x12\x16\n\x12PREPARE_DEALLOCATE\x10*\x12\x0f\n\x0b\x43URSOR_OPEN\x10+\x12\x10\n\x0c\x43URSOR_CLOSE\x10,\x12\x10\n\x0c\x43URSOR_FETCH\x10-\"\xe2\x02\n\x0eServerMessages\"\xcf\x02\n\x04Type\x12\x06\n\x02OK\x10\x00\x12\t\n\x05\x45RROR\x10\x01\x12\x15\n\x11\x43ONN_CAPABILITIES\x10\x02\x12\x1e\n\x1aSESS_AUTHENTICATE_CONTINUE\x10\x03\x12\x18\n\x14SESS_AUTHENTICATE_OK\x10\x04\x12\n\n\x06NOTICE\x10\x0b\x12\x1e\n\x1aRESULTSET_COLUMN_META_DATA\x10\x0c\x12\x11\n\rRESULTSET_ROW\x10\r\x12\x18\n\x14RESULTSET_FETCH_DONE\x10\x0e\x12\x1d\n\x19RESULTSET_FETCH_SUSPENDED\x10\x0f\x12(\n$RESULTSET_FETCH_DONE_MORE_RESULTSETS\x10\x10\x12\x17\n\x13SQL_STMT_EXECUTE_OK\x10\x11\x12(\n$RESULTSET_FETCH_DONE_MORE_OUT_PARAMS\x10\x12\"\x11\n\x02Ok\x12\x0b\n\x03msg\x18\x01 \x01(\t\"\x88\x01\n\x05\x45rror\x12/\n\x08severity\x18\x01 \x01(\x0e\x32\x16.Mysqlx.Error.Severity:\x05\x45RROR\x12\x0c\n\x04\x63ode\x18\x02 \x02(\r\x12\x11\n\tsql_state\x18\x04 \x02(\t\x12\x0b\n\x03msg\x18\x03 \x02(\t\" \n\x08Severity\x12\t\n\x05\x45RROR\x10\x00\x12\t\n\x05\x46\x41TAL\x10\x01\x42\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
)
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_CLIENTMESSAGES_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.ClientMessages.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CON_CAPABILITIES_GET', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CON_CAPABILITIES_SET', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CON_CLOSE', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SESS_AUTHENTICATE_START', index=3, number=4,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SESS_AUTHENTICATE_CONTINUE', index=4, number=5,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SESS_RESET', index=5, number=6,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SESS_CLOSE', index=6, number=7,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SQL_STMT_EXECUTE', index=7, number=12,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CRUD_FIND', index=8, number=17,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CRUD_INSERT', index=9, number=18,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CRUD_UPDATE', index=10, number=19,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CRUD_DELETE', index=11, number=20,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='EXPECT_OPEN', index=12, number=24,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='EXPECT_CLOSE', index=13, number=25,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CRUD_CREATE_VIEW', index=14, number=30,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CRUD_MODIFY_VIEW', index=15, number=31,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CRUD_DROP_VIEW', index=16, number=32,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='PREPARE_PREPARE', index=17, number=40,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='PREPARE_EXECUTE', index=18, number=41,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='PREPARE_DEALLOCATE', index=19, number=42,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CURSOR_OPEN', index=20, number=43,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CURSOR_CLOSE', index=21, number=44,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CURSOR_FETCH', index=22, number=45,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=44,
|
|
||||||
serialized_end=516,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_CLIENTMESSAGES_TYPE)
|
|
||||||
|
|
||||||
_SERVERMESSAGES_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.ServerMessages.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='OK', index=0, number=0,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ERROR', index=1, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='CONN_CAPABILITIES', index=2, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SESS_AUTHENTICATE_CONTINUE', index=3, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SESS_AUTHENTICATE_OK', index=4, number=4,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='NOTICE', index=5, number=11,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='RESULTSET_COLUMN_META_DATA', index=6, number=12,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='RESULTSET_ROW', index=7, number=13,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='RESULTSET_FETCH_DONE', index=8, number=14,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='RESULTSET_FETCH_SUSPENDED', index=9, number=15,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='RESULTSET_FETCH_DONE_MORE_RESULTSETS', index=10, number=16,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SQL_STMT_EXECUTE_OK', index=11, number=17,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='RESULTSET_FETCH_DONE_MORE_OUT_PARAMS', index=12, number=18,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=538,
|
|
||||||
serialized_end=873,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_SERVERMESSAGES_TYPE)
|
|
||||||
|
|
||||||
_ERROR_SEVERITY = _descriptor.EnumDescriptor(
|
|
||||||
name='Severity',
|
|
||||||
full_name='Mysqlx.Error.Severity',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ERROR', index=0, number=0,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='FATAL', index=1, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=999,
|
|
||||||
serialized_end=1031,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_ERROR_SEVERITY)
|
|
||||||
|
|
||||||
|
|
||||||
_CLIENTMESSAGES = _descriptor.Descriptor(
|
|
||||||
name='ClientMessages',
|
|
||||||
full_name='Mysqlx.ClientMessages',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_CLIENTMESSAGES_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=25,
|
|
||||||
serialized_end=516,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_SERVERMESSAGES = _descriptor.Descriptor(
|
|
||||||
name='ServerMessages',
|
|
||||||
full_name='Mysqlx.ServerMessages',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_SERVERMESSAGES_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=519,
|
|
||||||
serialized_end=873,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_OK = _descriptor.Descriptor(
|
|
||||||
name='Ok',
|
|
||||||
full_name='Mysqlx.Ok',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='msg', full_name='Mysqlx.Ok.msg', index=0,
|
|
||||||
number=1, type=9, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=875,
|
|
||||||
serialized_end=892,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_ERROR = _descriptor.Descriptor(
|
|
||||||
name='Error',
|
|
||||||
full_name='Mysqlx.Error',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='severity', full_name='Mysqlx.Error.severity', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=1,
|
|
||||||
has_default_value=True, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='code', full_name='Mysqlx.Error.code', index=1,
|
|
||||||
number=2, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='sql_state', full_name='Mysqlx.Error.sql_state', index=2,
|
|
||||||
number=4, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='msg', full_name='Mysqlx.Error.msg', index=3,
|
|
||||||
number=3, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_ERROR_SEVERITY,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=895,
|
|
||||||
serialized_end=1031,
|
|
||||||
)
|
|
||||||
|
|
||||||
_CLIENTMESSAGES_TYPE.containing_type = _CLIENTMESSAGES
|
|
||||||
_SERVERMESSAGES_TYPE.containing_type = _SERVERMESSAGES
|
|
||||||
_ERROR.fields_by_name['severity'].enum_type = _ERROR_SEVERITY
|
|
||||||
_ERROR_SEVERITY.containing_type = _ERROR
|
|
||||||
DESCRIPTOR.message_types_by_name['ClientMessages'] = _CLIENTMESSAGES
|
|
||||||
DESCRIPTOR.message_types_by_name['ServerMessages'] = _SERVERMESSAGES
|
|
||||||
DESCRIPTOR.message_types_by_name['Ok'] = _OK
|
|
||||||
DESCRIPTOR.message_types_by_name['Error'] = _ERROR
|
|
||||||
|
|
||||||
ClientMessages = _reflection.GeneratedProtocolMessageType('ClientMessages', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _CLIENTMESSAGES,
|
|
||||||
__module__ = 'mysqlx_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.ClientMessages)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(ClientMessages)
|
|
||||||
|
|
||||||
ServerMessages = _reflection.GeneratedProtocolMessageType('ServerMessages', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _SERVERMESSAGES,
|
|
||||||
__module__ = 'mysqlx_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.ServerMessages)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(ServerMessages)
|
|
||||||
|
|
||||||
Ok = _reflection.GeneratedProtocolMessageType('Ok', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _OK,
|
|
||||||
__module__ = 'mysqlx_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Ok)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Ok)
|
|
||||||
|
|
||||||
Error = _reflection.GeneratedProtocolMessageType('Error', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _ERROR,
|
|
||||||
__module__ = 'mysqlx_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Error)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Error)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,287 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_prepare.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
from mysqlx.protobuf import mysqlx_sql_pb2
|
|
||||||
from mysqlx.protobuf import mysqlx_crud_pb2
|
|
||||||
from mysqlx.protobuf import mysqlx_datatypes_pb2
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_prepare.proto',
|
|
||||||
package='Mysqlx.Prepare',
|
|
||||||
serialized_pb=_b('\n\x14mysqlx_prepare.proto\x12\x0eMysqlx.Prepare\x1a\x10mysqlx_sql.proto\x1a\x11mysqlx_crud.proto\x1a\x16mysqlx_datatypes.proto\"\x97\x03\n\x07Prepare\x12\x0f\n\x07stmt_id\x18\x01 \x02(\r\x12\x32\n\x04stmt\x18\x02 \x02(\x0b\x32$.Mysqlx.Prepare.Prepare.OneOfMessage\x1a\xc6\x02\n\x0cOneOfMessage\x12\x37\n\x04type\x18\x01 \x02(\x0e\x32).Mysqlx.Prepare.Prepare.OneOfMessage.Type\x12\x1f\n\x04\x66ind\x18\x02 \x01(\x0b\x32\x11.Mysqlx.Crud.Find\x12#\n\x06insert\x18\x03 \x01(\x0b\x32\x13.Mysqlx.Crud.Insert\x12#\n\x06update\x18\x04 \x01(\x0b\x32\x13.Mysqlx.Crud.Update\x12#\n\x06\x64\x65lete\x18\x05 \x01(\x0b\x32\x13.Mysqlx.Crud.Delete\x12-\n\x0cstmt_execute\x18\x06 \x01(\x0b\x32\x17.Mysqlx.Sql.StmtExecute\">\n\x04Type\x12\x08\n\x04\x46IND\x10\x00\x12\n\n\x06INSERT\x10\x01\x12\n\n\x06UPDATE\x10\x02\x12\n\n\x06\x44\x45LETE\x10\x04\x12\x08\n\x04STMT\x10\x05\"`\n\x07\x45xecute\x12\x0f\n\x07stmt_id\x18\x01 \x02(\r\x12#\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x15.Mysqlx.Datatypes.Any\x12\x1f\n\x10\x63ompact_metadata\x18\x03 \x01(\x08:\x05\x66\x61lse\"\x1d\n\nDeallocate\x12\x0f\n\x07stmt_id\x18\x01 \x02(\rB\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
,
|
|
||||||
dependencies=[mysqlx_sql_pb2.DESCRIPTOR,mysqlx_crud_pb2.DESCRIPTOR,mysqlx_datatypes_pb2.DESCRIPTOR,])
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_PREPARE_ONEOFMESSAGE_TYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='Type',
|
|
||||||
full_name='Mysqlx.Prepare.Prepare.OneOfMessage.Type',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='FIND', index=0, number=0,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='INSERT', index=1, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='UPDATE', index=2, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='DELETE', index=3, number=4,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='STMT', index=4, number=5,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=447,
|
|
||||||
serialized_end=509,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_PREPARE_ONEOFMESSAGE_TYPE)
|
|
||||||
|
|
||||||
|
|
||||||
_PREPARE_ONEOFMESSAGE = _descriptor.Descriptor(
|
|
||||||
name='OneOfMessage',
|
|
||||||
full_name='Mysqlx.Prepare.Prepare.OneOfMessage',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='type', full_name='Mysqlx.Prepare.Prepare.OneOfMessage.type', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='find', full_name='Mysqlx.Prepare.Prepare.OneOfMessage.find', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='insert', full_name='Mysqlx.Prepare.Prepare.OneOfMessage.insert', index=2,
|
|
||||||
number=3, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='update', full_name='Mysqlx.Prepare.Prepare.OneOfMessage.update', index=3,
|
|
||||||
number=4, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='delete', full_name='Mysqlx.Prepare.Prepare.OneOfMessage.delete', index=4,
|
|
||||||
number=5, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='stmt_execute', full_name='Mysqlx.Prepare.Prepare.OneOfMessage.stmt_execute', index=5,
|
|
||||||
number=6, type=11, cpp_type=10, label=1,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_PREPARE_ONEOFMESSAGE_TYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=183,
|
|
||||||
serialized_end=509,
|
|
||||||
)
|
|
||||||
|
|
||||||
_PREPARE = _descriptor.Descriptor(
|
|
||||||
name='Prepare',
|
|
||||||
full_name='Mysqlx.Prepare.Prepare',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='stmt_id', full_name='Mysqlx.Prepare.Prepare.stmt_id', index=0,
|
|
||||||
number=1, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='stmt', full_name='Mysqlx.Prepare.Prepare.stmt', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=2,
|
|
||||||
has_default_value=False, default_value=None,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[_PREPARE_ONEOFMESSAGE, ],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=102,
|
|
||||||
serialized_end=509,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_EXECUTE = _descriptor.Descriptor(
|
|
||||||
name='Execute',
|
|
||||||
full_name='Mysqlx.Prepare.Execute',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='stmt_id', full_name='Mysqlx.Prepare.Execute.stmt_id', index=0,
|
|
||||||
number=1, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='args', full_name='Mysqlx.Prepare.Execute.args', index=1,
|
|
||||||
number=2, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='compact_metadata', full_name='Mysqlx.Prepare.Execute.compact_metadata', index=2,
|
|
||||||
number=3, type=8, cpp_type=7, label=1,
|
|
||||||
has_default_value=True, default_value=False,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=511,
|
|
||||||
serialized_end=607,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_DEALLOCATE = _descriptor.Descriptor(
|
|
||||||
name='Deallocate',
|
|
||||||
full_name='Mysqlx.Prepare.Deallocate',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='stmt_id', full_name='Mysqlx.Prepare.Deallocate.stmt_id', index=0,
|
|
||||||
number=1, type=13, cpp_type=3, label=2,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=609,
|
|
||||||
serialized_end=638,
|
|
||||||
)
|
|
||||||
|
|
||||||
_PREPARE_ONEOFMESSAGE.fields_by_name['type'].enum_type = _PREPARE_ONEOFMESSAGE_TYPE
|
|
||||||
_PREPARE_ONEOFMESSAGE.fields_by_name['find'].message_type = mysqlx_crud_pb2._FIND
|
|
||||||
_PREPARE_ONEOFMESSAGE.fields_by_name['insert'].message_type = mysqlx_crud_pb2._INSERT
|
|
||||||
_PREPARE_ONEOFMESSAGE.fields_by_name['update'].message_type = mysqlx_crud_pb2._UPDATE
|
|
||||||
_PREPARE_ONEOFMESSAGE.fields_by_name['delete'].message_type = mysqlx_crud_pb2._DELETE
|
|
||||||
_PREPARE_ONEOFMESSAGE.fields_by_name['stmt_execute'].message_type = mysqlx_sql_pb2._STMTEXECUTE
|
|
||||||
_PREPARE_ONEOFMESSAGE.containing_type = _PREPARE
|
|
||||||
_PREPARE_ONEOFMESSAGE_TYPE.containing_type = _PREPARE_ONEOFMESSAGE
|
|
||||||
_PREPARE.fields_by_name['stmt'].message_type = _PREPARE_ONEOFMESSAGE
|
|
||||||
_EXECUTE.fields_by_name['args'].message_type = mysqlx_datatypes_pb2._ANY
|
|
||||||
DESCRIPTOR.message_types_by_name['Prepare'] = _PREPARE
|
|
||||||
DESCRIPTOR.message_types_by_name['Execute'] = _EXECUTE
|
|
||||||
DESCRIPTOR.message_types_by_name['Deallocate'] = _DEALLOCATE
|
|
||||||
|
|
||||||
Prepare = _reflection.GeneratedProtocolMessageType('Prepare', (_message.Message,), dict(
|
|
||||||
|
|
||||||
OneOfMessage = _reflection.GeneratedProtocolMessageType('OneOfMessage', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _PREPARE_ONEOFMESSAGE,
|
|
||||||
__module__ = 'mysqlx_prepare_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Prepare.Prepare.OneOfMessage)
|
|
||||||
))
|
|
||||||
,
|
|
||||||
DESCRIPTOR = _PREPARE,
|
|
||||||
__module__ = 'mysqlx_prepare_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Prepare.Prepare)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Prepare)
|
|
||||||
_sym_db.RegisterMessage(Prepare.OneOfMessage)
|
|
||||||
|
|
||||||
Execute = _reflection.GeneratedProtocolMessageType('Execute', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _EXECUTE,
|
|
||||||
__module__ = 'mysqlx_prepare_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Prepare.Execute)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Execute)
|
|
||||||
|
|
||||||
Deallocate = _reflection.GeneratedProtocolMessageType('Deallocate', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _DEALLOCATE,
|
|
||||||
__module__ = 'mysqlx_prepare_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Prepare.Deallocate)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Deallocate)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,427 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_resultset.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf.internal import enum_type_wrapper
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_resultset.proto',
|
|
||||||
package='Mysqlx.Resultset',
|
|
||||||
serialized_pb=_b('\n\x16mysqlx_resultset.proto\x12\x10Mysqlx.Resultset\"\x18\n\x16\x46\x65tchDoneMoreOutParams\"\x19\n\x17\x46\x65tchDoneMoreResultsets\"\x0b\n\tFetchDone\"\x10\n\x0e\x46\x65tchSuspended\"\x9f\x03\n\x0e\x43olumnMetaData\x12\x38\n\x04type\x18\x01 \x02(\x0e\x32*.Mysqlx.Resultset.ColumnMetaData.FieldType\x12\x0c\n\x04name\x18\x02 \x01(\x0c\x12\x15\n\roriginal_name\x18\x03 \x01(\x0c\x12\r\n\x05table\x18\x04 \x01(\x0c\x12\x16\n\x0eoriginal_table\x18\x05 \x01(\x0c\x12\x0e\n\x06schema\x18\x06 \x01(\x0c\x12\x0f\n\x07\x63\x61talog\x18\x07 \x01(\x0c\x12\x11\n\tcollation\x18\x08 \x01(\x04\x12\x19\n\x11\x66ractional_digits\x18\t \x01(\r\x12\x0e\n\x06length\x18\n \x01(\r\x12\r\n\x05\x66lags\x18\x0b \x01(\r\x12\x14\n\x0c\x63ontent_type\x18\x0c \x01(\r\"\x82\x01\n\tFieldType\x12\x08\n\x04SINT\x10\x01\x12\x08\n\x04UINT\x10\x02\x12\n\n\x06\x44OUBLE\x10\x05\x12\t\n\x05\x46LOAT\x10\x06\x12\t\n\x05\x42YTES\x10\x07\x12\x08\n\x04TIME\x10\n\x12\x0c\n\x08\x44\x41TETIME\x10\x0c\x12\x07\n\x03SET\x10\x0f\x12\x08\n\x04\x45NUM\x10\x10\x12\x07\n\x03\x42IT\x10\x11\x12\x0b\n\x07\x44\x45\x43IMAL\x10\x12\"\x14\n\x03Row\x12\r\n\x05\x66ield\x18\x01 \x03(\x0c*4\n\x11\x43ontentType_BYTES\x12\x0c\n\x08GEOMETRY\x10\x01\x12\x08\n\x04JSON\x10\x02\x12\x07\n\x03XML\x10\x03*.\n\x14\x43ontentType_DATETIME\x12\x08\n\x04\x44\x41TE\x10\x01\x12\x0c\n\x08\x44\x41TETIME\x10\x02\x42\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
)
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
_CONTENTTYPE_BYTES = _descriptor.EnumDescriptor(
|
|
||||||
name='ContentType_BYTES',
|
|
||||||
full_name='Mysqlx.Resultset.ContentType_BYTES',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='GEOMETRY', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='JSON', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='XML', index=2, number=3,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=568,
|
|
||||||
serialized_end=620,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_CONTENTTYPE_BYTES)
|
|
||||||
|
|
||||||
ContentType_BYTES = enum_type_wrapper.EnumTypeWrapper(_CONTENTTYPE_BYTES)
|
|
||||||
_CONTENTTYPE_DATETIME = _descriptor.EnumDescriptor(
|
|
||||||
name='ContentType_DATETIME',
|
|
||||||
full_name='Mysqlx.Resultset.ContentType_DATETIME',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='DATE', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='DATETIME', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=622,
|
|
||||||
serialized_end=668,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_CONTENTTYPE_DATETIME)
|
|
||||||
|
|
||||||
ContentType_DATETIME = enum_type_wrapper.EnumTypeWrapper(_CONTENTTYPE_DATETIME)
|
|
||||||
GEOMETRY = 1
|
|
||||||
JSON = 2
|
|
||||||
XML = 3
|
|
||||||
DATE = 1
|
|
||||||
DATETIME = 2
|
|
||||||
|
|
||||||
|
|
||||||
_COLUMNMETADATA_FIELDTYPE = _descriptor.EnumDescriptor(
|
|
||||||
name='FieldType',
|
|
||||||
full_name='Mysqlx.Resultset.ColumnMetaData.FieldType',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
values=[
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SINT', index=0, number=1,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='UINT', index=1, number=2,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='DOUBLE', index=2, number=5,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='FLOAT', index=3, number=6,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='BYTES', index=4, number=7,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='TIME', index=5, number=10,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='DATETIME', index=6, number=12,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='SET', index=7, number=15,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='ENUM', index=8, number=16,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='BIT', index=9, number=17,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
_descriptor.EnumValueDescriptor(
|
|
||||||
name='DECIMAL', index=10, number=18,
|
|
||||||
options=None,
|
|
||||||
type=None),
|
|
||||||
],
|
|
||||||
containing_type=None,
|
|
||||||
options=None,
|
|
||||||
serialized_start=414,
|
|
||||||
serialized_end=544,
|
|
||||||
)
|
|
||||||
_sym_db.RegisterEnumDescriptor(_COLUMNMETADATA_FIELDTYPE)
|
|
||||||
|
|
||||||
|
|
||||||
_FETCHDONEMOREOUTPARAMS = _descriptor.Descriptor(
|
|
||||||
name='FetchDoneMoreOutParams',
|
|
||||||
full_name='Mysqlx.Resultset.FetchDoneMoreOutParams',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=44,
|
|
||||||
serialized_end=68,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_FETCHDONEMORERESULTSETS = _descriptor.Descriptor(
|
|
||||||
name='FetchDoneMoreResultsets',
|
|
||||||
full_name='Mysqlx.Resultset.FetchDoneMoreResultsets',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=70,
|
|
||||||
serialized_end=95,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_FETCHDONE = _descriptor.Descriptor(
|
|
||||||
name='FetchDone',
|
|
||||||
full_name='Mysqlx.Resultset.FetchDone',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=97,
|
|
||||||
serialized_end=108,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_FETCHSUSPENDED = _descriptor.Descriptor(
|
|
||||||
name='FetchSuspended',
|
|
||||||
full_name='Mysqlx.Resultset.FetchSuspended',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=110,
|
|
||||||
serialized_end=126,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_COLUMNMETADATA = _descriptor.Descriptor(
|
|
||||||
name='ColumnMetaData',
|
|
||||||
full_name='Mysqlx.Resultset.ColumnMetaData',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='type', full_name='Mysqlx.Resultset.ColumnMetaData.type', index=0,
|
|
||||||
number=1, type=14, cpp_type=8, label=2,
|
|
||||||
has_default_value=False, default_value=1,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='name', full_name='Mysqlx.Resultset.ColumnMetaData.name', index=1,
|
|
||||||
number=2, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='original_name', full_name='Mysqlx.Resultset.ColumnMetaData.original_name', index=2,
|
|
||||||
number=3, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='table', full_name='Mysqlx.Resultset.ColumnMetaData.table', index=3,
|
|
||||||
number=4, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='original_table', full_name='Mysqlx.Resultset.ColumnMetaData.original_table', index=4,
|
|
||||||
number=5, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='schema', full_name='Mysqlx.Resultset.ColumnMetaData.schema', index=5,
|
|
||||||
number=6, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='catalog', full_name='Mysqlx.Resultset.ColumnMetaData.catalog', index=6,
|
|
||||||
number=7, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='collation', full_name='Mysqlx.Resultset.ColumnMetaData.collation', index=7,
|
|
||||||
number=8, type=4, cpp_type=4, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='fractional_digits', full_name='Mysqlx.Resultset.ColumnMetaData.fractional_digits', index=8,
|
|
||||||
number=9, type=13, cpp_type=3, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='length', full_name='Mysqlx.Resultset.ColumnMetaData.length', index=9,
|
|
||||||
number=10, type=13, cpp_type=3, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='flags', full_name='Mysqlx.Resultset.ColumnMetaData.flags', index=10,
|
|
||||||
number=11, type=13, cpp_type=3, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='content_type', full_name='Mysqlx.Resultset.ColumnMetaData.content_type', index=11,
|
|
||||||
number=12, type=13, cpp_type=3, label=1,
|
|
||||||
has_default_value=False, default_value=0,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
_COLUMNMETADATA_FIELDTYPE,
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=129,
|
|
||||||
serialized_end=544,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_ROW = _descriptor.Descriptor(
|
|
||||||
name='Row',
|
|
||||||
full_name='Mysqlx.Resultset.Row',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='field', full_name='Mysqlx.Resultset.Row.field', index=0,
|
|
||||||
number=1, type=12, cpp_type=9, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=546,
|
|
||||||
serialized_end=566,
|
|
||||||
)
|
|
||||||
|
|
||||||
_COLUMNMETADATA.fields_by_name['type'].enum_type = _COLUMNMETADATA_FIELDTYPE
|
|
||||||
_COLUMNMETADATA_FIELDTYPE.containing_type = _COLUMNMETADATA
|
|
||||||
DESCRIPTOR.message_types_by_name['FetchDoneMoreOutParams'] = _FETCHDONEMOREOUTPARAMS
|
|
||||||
DESCRIPTOR.message_types_by_name['FetchDoneMoreResultsets'] = _FETCHDONEMORERESULTSETS
|
|
||||||
DESCRIPTOR.message_types_by_name['FetchDone'] = _FETCHDONE
|
|
||||||
DESCRIPTOR.message_types_by_name['FetchSuspended'] = _FETCHSUSPENDED
|
|
||||||
DESCRIPTOR.message_types_by_name['ColumnMetaData'] = _COLUMNMETADATA
|
|
||||||
DESCRIPTOR.message_types_by_name['Row'] = _ROW
|
|
||||||
DESCRIPTOR.enum_types_by_name['ContentType_BYTES'] = _CONTENTTYPE_BYTES
|
|
||||||
DESCRIPTOR.enum_types_by_name['ContentType_DATETIME'] = _CONTENTTYPE_DATETIME
|
|
||||||
|
|
||||||
FetchDoneMoreOutParams = _reflection.GeneratedProtocolMessageType('FetchDoneMoreOutParams', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _FETCHDONEMOREOUTPARAMS,
|
|
||||||
__module__ = 'mysqlx_resultset_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Resultset.FetchDoneMoreOutParams)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(FetchDoneMoreOutParams)
|
|
||||||
|
|
||||||
FetchDoneMoreResultsets = _reflection.GeneratedProtocolMessageType('FetchDoneMoreResultsets', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _FETCHDONEMORERESULTSETS,
|
|
||||||
__module__ = 'mysqlx_resultset_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Resultset.FetchDoneMoreResultsets)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(FetchDoneMoreResultsets)
|
|
||||||
|
|
||||||
FetchDone = _reflection.GeneratedProtocolMessageType('FetchDone', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _FETCHDONE,
|
|
||||||
__module__ = 'mysqlx_resultset_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Resultset.FetchDone)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(FetchDone)
|
|
||||||
|
|
||||||
FetchSuspended = _reflection.GeneratedProtocolMessageType('FetchSuspended', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _FETCHSUSPENDED,
|
|
||||||
__module__ = 'mysqlx_resultset_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Resultset.FetchSuspended)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(FetchSuspended)
|
|
||||||
|
|
||||||
ColumnMetaData = _reflection.GeneratedProtocolMessageType('ColumnMetaData', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _COLUMNMETADATA,
|
|
||||||
__module__ = 'mysqlx_resultset_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Resultset.ColumnMetaData)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(ColumnMetaData)
|
|
||||||
|
|
||||||
Row = _reflection.GeneratedProtocolMessageType('Row', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _ROW,
|
|
||||||
__module__ = 'mysqlx_resultset_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Resultset.Row)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Row)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,228 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_session.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_session.proto',
|
|
||||||
package='Mysqlx.Session',
|
|
||||||
serialized_pb=_b('\n\x14mysqlx_session.proto\x12\x0eMysqlx.Session\"S\n\x11\x41uthenticateStart\x12\x11\n\tmech_name\x18\x01 \x02(\t\x12\x11\n\tauth_data\x18\x02 \x01(\x0c\x12\x18\n\x10initial_response\x18\x03 \x01(\x0c\")\n\x14\x41uthenticateContinue\x12\x11\n\tauth_data\x18\x01 \x02(\x0c\"#\n\x0e\x41uthenticateOk\x12\x11\n\tauth_data\x18\x01 \x01(\x0c\"!\n\x05Reset\x12\x18\n\tkeep_open\x18\x01 \x01(\x08:\x05\x66\x61lse\"\x07\n\x05\x43loseB\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
)
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_AUTHENTICATESTART = _descriptor.Descriptor(
|
|
||||||
name='AuthenticateStart',
|
|
||||||
full_name='Mysqlx.Session.AuthenticateStart',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='mech_name', full_name='Mysqlx.Session.AuthenticateStart.mech_name', index=0,
|
|
||||||
number=1, type=9, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='auth_data', full_name='Mysqlx.Session.AuthenticateStart.auth_data', index=1,
|
|
||||||
number=2, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='initial_response', full_name='Mysqlx.Session.AuthenticateStart.initial_response', index=2,
|
|
||||||
number=3, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=40,
|
|
||||||
serialized_end=123,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_AUTHENTICATECONTINUE = _descriptor.Descriptor(
|
|
||||||
name='AuthenticateContinue',
|
|
||||||
full_name='Mysqlx.Session.AuthenticateContinue',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='auth_data', full_name='Mysqlx.Session.AuthenticateContinue.auth_data', index=0,
|
|
||||||
number=1, type=12, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=125,
|
|
||||||
serialized_end=166,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_AUTHENTICATEOK = _descriptor.Descriptor(
|
|
||||||
name='AuthenticateOk',
|
|
||||||
full_name='Mysqlx.Session.AuthenticateOk',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='auth_data', full_name='Mysqlx.Session.AuthenticateOk.auth_data', index=0,
|
|
||||||
number=1, type=12, cpp_type=9, label=1,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=168,
|
|
||||||
serialized_end=203,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_RESET = _descriptor.Descriptor(
|
|
||||||
name='Reset',
|
|
||||||
full_name='Mysqlx.Session.Reset',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='keep_open', full_name='Mysqlx.Session.Reset.keep_open', index=0,
|
|
||||||
number=1, type=8, cpp_type=7, label=1,
|
|
||||||
has_default_value=True, default_value=False,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=205,
|
|
||||||
serialized_end=238,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_CLOSE = _descriptor.Descriptor(
|
|
||||||
name='Close',
|
|
||||||
full_name='Mysqlx.Session.Close',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=240,
|
|
||||||
serialized_end=247,
|
|
||||||
)
|
|
||||||
|
|
||||||
DESCRIPTOR.message_types_by_name['AuthenticateStart'] = _AUTHENTICATESTART
|
|
||||||
DESCRIPTOR.message_types_by_name['AuthenticateContinue'] = _AUTHENTICATECONTINUE
|
|
||||||
DESCRIPTOR.message_types_by_name['AuthenticateOk'] = _AUTHENTICATEOK
|
|
||||||
DESCRIPTOR.message_types_by_name['Reset'] = _RESET
|
|
||||||
DESCRIPTOR.message_types_by_name['Close'] = _CLOSE
|
|
||||||
|
|
||||||
AuthenticateStart = _reflection.GeneratedProtocolMessageType('AuthenticateStart', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _AUTHENTICATESTART,
|
|
||||||
__module__ = 'mysqlx_session_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Session.AuthenticateStart)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(AuthenticateStart)
|
|
||||||
|
|
||||||
AuthenticateContinue = _reflection.GeneratedProtocolMessageType('AuthenticateContinue', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _AUTHENTICATECONTINUE,
|
|
||||||
__module__ = 'mysqlx_session_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Session.AuthenticateContinue)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(AuthenticateContinue)
|
|
||||||
|
|
||||||
AuthenticateOk = _reflection.GeneratedProtocolMessageType('AuthenticateOk', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _AUTHENTICATEOK,
|
|
||||||
__module__ = 'mysqlx_session_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Session.AuthenticateOk)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(AuthenticateOk)
|
|
||||||
|
|
||||||
Reset = _reflection.GeneratedProtocolMessageType('Reset', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _RESET,
|
|
||||||
__module__ = 'mysqlx_session_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Session.Reset)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Reset)
|
|
||||||
|
|
||||||
Close = _reflection.GeneratedProtocolMessageType('Close', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _CLOSE,
|
|
||||||
__module__ = 'mysqlx_session_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Session.Close)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(Close)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,124 +0,0 @@
|
|||||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
|
||||||
# source: mysqlx_sql.proto
|
|
||||||
|
|
||||||
import sys
|
|
||||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
|
||||||
from google.protobuf import descriptor as _descriptor
|
|
||||||
from google.protobuf import message as _message
|
|
||||||
from google.protobuf import reflection as _reflection
|
|
||||||
from google.protobuf import symbol_database as _symbol_database
|
|
||||||
from google.protobuf import descriptor_pb2
|
|
||||||
# @@protoc_insertion_point(imports)
|
|
||||||
|
|
||||||
_sym_db = _symbol_database.Default()
|
|
||||||
|
|
||||||
|
|
||||||
from mysqlx.protobuf import mysqlx_datatypes_pb2
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR = _descriptor.FileDescriptor(
|
|
||||||
name='mysqlx_sql.proto',
|
|
||||||
package='Mysqlx.Sql',
|
|
||||||
serialized_pb=_b('\n\x10mysqlx_sql.proto\x12\nMysqlx.Sql\x1a\x16mysqlx_datatypes.proto\"y\n\x0bStmtExecute\x12\x16\n\tnamespace\x18\x03 \x01(\t:\x03sql\x12\x0c\n\x04stmt\x18\x01 \x02(\x0c\x12#\n\x04\x61rgs\x18\x02 \x03(\x0b\x32\x15.Mysqlx.Datatypes.Any\x12\x1f\n\x10\x63ompact_metadata\x18\x04 \x01(\x08:\x05\x66\x61lse\"\x0f\n\rStmtExecuteOkB\x1b\n\x17\x63om.mysql.cj.x.protobufH\x03')
|
|
||||||
,
|
|
||||||
dependencies=[mysqlx_datatypes_pb2.DESCRIPTOR,])
|
|
||||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_STMTEXECUTE = _descriptor.Descriptor(
|
|
||||||
name='StmtExecute',
|
|
||||||
full_name='Mysqlx.Sql.StmtExecute',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='namespace', full_name='Mysqlx.Sql.StmtExecute.namespace', index=0,
|
|
||||||
number=3, type=9, cpp_type=9, label=1,
|
|
||||||
has_default_value=True, default_value=_b("sql").decode('utf-8'),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='stmt', full_name='Mysqlx.Sql.StmtExecute.stmt', index=1,
|
|
||||||
number=1, type=12, cpp_type=9, label=2,
|
|
||||||
has_default_value=False, default_value=_b(""),
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='args', full_name='Mysqlx.Sql.StmtExecute.args', index=2,
|
|
||||||
number=2, type=11, cpp_type=10, label=3,
|
|
||||||
has_default_value=False, default_value=[],
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
_descriptor.FieldDescriptor(
|
|
||||||
name='compact_metadata', full_name='Mysqlx.Sql.StmtExecute.compact_metadata', index=3,
|
|
||||||
number=4, type=8, cpp_type=7, label=1,
|
|
||||||
has_default_value=True, default_value=False,
|
|
||||||
message_type=None, enum_type=None, containing_type=None,
|
|
||||||
is_extension=False, extension_scope=None,
|
|
||||||
options=None),
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=56,
|
|
||||||
serialized_end=177,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_STMTEXECUTEOK = _descriptor.Descriptor(
|
|
||||||
name='StmtExecuteOk',
|
|
||||||
full_name='Mysqlx.Sql.StmtExecuteOk',
|
|
||||||
filename=None,
|
|
||||||
file=DESCRIPTOR,
|
|
||||||
containing_type=None,
|
|
||||||
fields=[
|
|
||||||
],
|
|
||||||
extensions=[
|
|
||||||
],
|
|
||||||
nested_types=[],
|
|
||||||
enum_types=[
|
|
||||||
],
|
|
||||||
options=None,
|
|
||||||
is_extendable=False,
|
|
||||||
extension_ranges=[],
|
|
||||||
oneofs=[
|
|
||||||
],
|
|
||||||
serialized_start=179,
|
|
||||||
serialized_end=194,
|
|
||||||
)
|
|
||||||
|
|
||||||
_STMTEXECUTE.fields_by_name['args'].message_type = mysqlx_datatypes_pb2._ANY
|
|
||||||
DESCRIPTOR.message_types_by_name['StmtExecute'] = _STMTEXECUTE
|
|
||||||
DESCRIPTOR.message_types_by_name['StmtExecuteOk'] = _STMTEXECUTEOK
|
|
||||||
|
|
||||||
StmtExecute = _reflection.GeneratedProtocolMessageType('StmtExecute', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _STMTEXECUTE,
|
|
||||||
__module__ = 'mysqlx_sql_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Sql.StmtExecute)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(StmtExecute)
|
|
||||||
|
|
||||||
StmtExecuteOk = _reflection.GeneratedProtocolMessageType('StmtExecuteOk', (_message.Message,), dict(
|
|
||||||
DESCRIPTOR = _STMTEXECUTEOK,
|
|
||||||
__module__ = 'mysqlx_sql_pb2'
|
|
||||||
# @@protoc_insertion_point(class_scope:Mysqlx.Sql.StmtExecuteOk)
|
|
||||||
))
|
|
||||||
_sym_db.RegisterMessage(StmtExecuteOk)
|
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTOR.has_options = True
|
|
||||||
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\027com.mysql.cj.x.protobufH\003'))
|
|
||||||
# @@protoc_insertion_point(module_scope)
|
|
@ -1,877 +0,0 @@
|
|||||||
# Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify
|
|
||||||
# it under the terms of the GNU General Public License, version 2.0, as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is also distributed with certain software (including
|
|
||||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
|
||||||
# as designated in a particular file or component or in included license
|
|
||||||
# documentation. The authors of MySQL hereby grant you an
|
|
||||||
# additional permission to link the program and your derivative works
|
|
||||||
# with the separately licensed software that they have included with
|
|
||||||
# MySQL.
|
|
||||||
#
|
|
||||||
# Without limiting anything contained in the foregoing, this file,
|
|
||||||
# which is part of MySQL Connector/Python, is also subject to the
|
|
||||||
# Universal FOSS Exception, version 1.0, a copy of which can be found at
|
|
||||||
# http://oss.oracle.com/licenses/universal-foss-exception.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
# See the GNU General Public License, version 2.0, for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation, Inc.,
|
|
||||||
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
"""Implementation of the X protocol for MySQL servers."""
|
|
||||||
|
|
||||||
import struct
|
|
||||||
|
|
||||||
from .compat import STRING_TYPES, INT_TYPES
|
|
||||||
from .errors import (InterfaceError, NotSupportedError, OperationalError,
|
|
||||||
ProgrammingError)
|
|
||||||
from .expr import (ExprParser, build_expr, build_scalar, build_bool_scalar,
|
|
||||||
build_int_scalar, build_unsigned_int_scalar)
|
|
||||||
from .helpers import encode_to_bytes, get_item_or_attr
|
|
||||||
from .result import Column
|
|
||||||
from .protobuf import (CRUD_PREPARE_MAPPING, SERVER_MESSAGES,
|
|
||||||
PROTOBUF_REPEATED_TYPES, Message, mysqlxpb_enum)
|
|
||||||
|
|
||||||
|
|
||||||
class MessageReaderWriter(object):
|
|
||||||
"""Implements a Message Reader/Writer.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
socket_stream (mysqlx.connection.SocketStream): `SocketStream` object.
|
|
||||||
"""
|
|
||||||
def __init__(self, socket_stream):
|
|
||||||
self._stream = socket_stream
|
|
||||||
self._msg = None
|
|
||||||
|
|
||||||
def _read_message(self):
|
|
||||||
"""Read message.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.ProgrammingError`: If e connected server does not
|
|
||||||
have the MySQL X protocol plugin
|
|
||||||
enabled.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.protobuf.Message: MySQL X Protobuf Message.
|
|
||||||
"""
|
|
||||||
hdr = self._stream.read(5)
|
|
||||||
msg_len, msg_type = struct.unpack("<LB", hdr)
|
|
||||||
if msg_type == 10:
|
|
||||||
raise ProgrammingError("The connected server does not have the "
|
|
||||||
"MySQL X protocol plugin enabled or protocol"
|
|
||||||
"mismatch")
|
|
||||||
payload = self._stream.read(msg_len - 1)
|
|
||||||
msg_type_name = SERVER_MESSAGES.get(msg_type)
|
|
||||||
if not msg_type_name:
|
|
||||||
raise ValueError("Unknown msg_type: {0}".format(msg_type))
|
|
||||||
# Do not parse empty notices, Message requires a type in payload.
|
|
||||||
if msg_type == 11 and payload == b"":
|
|
||||||
return self._read_message()
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
msg = Message.from_server_message(msg_type, payload)
|
|
||||||
except RuntimeError:
|
|
||||||
return self._read_message()
|
|
||||||
return msg
|
|
||||||
|
|
||||||
def read_message(self):
|
|
||||||
"""Read message.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.protobuf.Message: MySQL X Protobuf Message.
|
|
||||||
"""
|
|
||||||
if self._msg is not None:
|
|
||||||
msg = self._msg
|
|
||||||
self._msg = None
|
|
||||||
return msg
|
|
||||||
return self._read_message()
|
|
||||||
|
|
||||||
def push_message(self, msg):
|
|
||||||
"""Push message.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.OperationalError`: If message push slot is full.
|
|
||||||
"""
|
|
||||||
if self._msg is not None:
|
|
||||||
raise OperationalError("Message push slot is full")
|
|
||||||
self._msg = msg
|
|
||||||
|
|
||||||
def write_message(self, msg_id, msg):
|
|
||||||
"""Write message.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_id (int): The message ID.
|
|
||||||
msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
|
|
||||||
"""
|
|
||||||
msg_str = encode_to_bytes(msg.serialize_to_string())
|
|
||||||
header = struct.pack("<LB", len(msg_str) + 1, msg_id)
|
|
||||||
self._stream.sendall(b"".join([header, msg_str]))
|
|
||||||
|
|
||||||
|
|
||||||
class Protocol(object):
|
|
||||||
"""Implements the MySQL X Protocol.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
read_writer (mysqlx.protocol.MessageReaderWriter): A Message \
|
|
||||||
Reader/Writer object.
|
|
||||||
"""
|
|
||||||
def __init__(self, reader_writer):
|
|
||||||
self._reader = reader_writer
|
|
||||||
self._writer = reader_writer
|
|
||||||
self._message = None
|
|
||||||
|
|
||||||
def _apply_filter(self, msg, stmt):
|
|
||||||
"""Apply filter.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg (mysqlx.protobuf.Message): The MySQL X Protobuf Message.
|
|
||||||
stmt (Statement): A `Statement` based type object.
|
|
||||||
"""
|
|
||||||
if stmt.has_where:
|
|
||||||
msg["criteria"] = stmt.get_where_expr()
|
|
||||||
if stmt.has_sort:
|
|
||||||
msg["order"].extend(stmt.get_sort_expr())
|
|
||||||
if stmt.has_group_by:
|
|
||||||
msg["grouping"].extend(stmt.get_grouping())
|
|
||||||
if stmt.has_having:
|
|
||||||
msg["grouping_criteria"] = stmt.get_having()
|
|
||||||
|
|
||||||
def _create_any(self, arg):
|
|
||||||
"""Create any.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
arg (object): Arbitrary object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.protobuf.Message: MySQL X Protobuf Message.
|
|
||||||
"""
|
|
||||||
if isinstance(arg, STRING_TYPES):
|
|
||||||
value = Message("Mysqlx.Datatypes.Scalar.String", value=arg)
|
|
||||||
scalar = Message("Mysqlx.Datatypes.Scalar", type=8, v_string=value)
|
|
||||||
return Message("Mysqlx.Datatypes.Any", type=1, scalar=scalar)
|
|
||||||
elif isinstance(arg, bool):
|
|
||||||
return Message("Mysqlx.Datatypes.Any", type=1,
|
|
||||||
scalar=build_bool_scalar(arg))
|
|
||||||
elif isinstance(arg, INT_TYPES):
|
|
||||||
if arg < 0:
|
|
||||||
return Message("Mysqlx.Datatypes.Any", type=1,
|
|
||||||
scalar=build_int_scalar(arg))
|
|
||||||
return Message("Mysqlx.Datatypes.Any", type=1,
|
|
||||||
scalar=build_unsigned_int_scalar(arg))
|
|
||||||
|
|
||||||
elif isinstance(arg, tuple) and len(arg) == 2:
|
|
||||||
arg_key, arg_value = arg
|
|
||||||
obj_fld = Message("Mysqlx.Datatypes.Object.ObjectField",
|
|
||||||
key=arg_key, value=self._create_any(arg_value))
|
|
||||||
obj = Message("Mysqlx.Datatypes.Object",
|
|
||||||
fld=[obj_fld.get_message()])
|
|
||||||
return Message("Mysqlx.Datatypes.Any", type=2, obj=obj)
|
|
||||||
|
|
||||||
elif isinstance(arg, dict) or (isinstance(arg, (list, tuple)) and
|
|
||||||
isinstance(arg[0], dict)):
|
|
||||||
array_values = []
|
|
||||||
for items in arg:
|
|
||||||
obj_flds = []
|
|
||||||
for key, value in items.items():
|
|
||||||
# Array can only handle Any types, Mysqlx.Datatypes.Any.obj
|
|
||||||
obj_fld = Message("Mysqlx.Datatypes.Object.ObjectField",
|
|
||||||
key=key, value=self._create_any(value))
|
|
||||||
obj_flds.append(obj_fld.get_message())
|
|
||||||
msg_obj = Message("Mysqlx.Datatypes.Object", fld=obj_flds)
|
|
||||||
msg_any = Message("Mysqlx.Datatypes.Any", type=2, obj=msg_obj)
|
|
||||||
array_values.append(msg_any.get_message())
|
|
||||||
|
|
||||||
msg = Message("Mysqlx.Datatypes.Array")
|
|
||||||
msg["value"] = array_values
|
|
||||||
return Message("Mysqlx.Datatypes.Any", type=3, array=msg)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _get_binding_args(self, stmt, is_scalar=True):
|
|
||||||
"""Returns the binding any/scalar.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
stmt (Statement): A `Statement` based type object.
|
|
||||||
is_scalar (bool): `True` to return scalar values.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.ProgrammingError`: If unable to find placeholder for
|
|
||||||
parameter.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list: A list of ``Any`` or ``Scalar`` objects.
|
|
||||||
"""
|
|
||||||
build_value = lambda value: build_scalar(value).get_message() \
|
|
||||||
if is_scalar else self._create_any(value).get_message()
|
|
||||||
bindings = stmt.get_bindings()
|
|
||||||
binding_map = stmt.get_binding_map()
|
|
||||||
|
|
||||||
# If binding_map is None it's a SqlStatement object
|
|
||||||
if binding_map is None:
|
|
||||||
return [build_value(value) for value in bindings]
|
|
||||||
|
|
||||||
count = len(binding_map)
|
|
||||||
args = count * [None]
|
|
||||||
if count != len(bindings):
|
|
||||||
raise ProgrammingError("The number of bind parameters and "
|
|
||||||
"placeholders do not match")
|
|
||||||
for name, value in bindings.items():
|
|
||||||
if name not in binding_map:
|
|
||||||
raise ProgrammingError("Unable to find placeholder for "
|
|
||||||
"parameter: {0}".format(name))
|
|
||||||
pos = binding_map[name]
|
|
||||||
args[pos] = build_value(value)
|
|
||||||
return args
|
|
||||||
|
|
||||||
def _process_frame(self, msg, result):
|
|
||||||
"""Process frame.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg (mysqlx.protobuf.Message): A MySQL X Protobuf Message.
|
|
||||||
result (Result): A `Result` based type object.
|
|
||||||
"""
|
|
||||||
if msg["type"] == 1:
|
|
||||||
warn_msg = Message.from_message("Mysqlx.Notice.Warning",
|
|
||||||
msg["payload"])
|
|
||||||
result.append_warning(warn_msg.level, warn_msg.code, warn_msg.msg)
|
|
||||||
elif msg["type"] == 2:
|
|
||||||
Message.from_message("Mysqlx.Notice.SessionVariableChanged",
|
|
||||||
msg["payload"])
|
|
||||||
elif msg["type"] == 3:
|
|
||||||
sess_state_msg = Message.from_message(
|
|
||||||
"Mysqlx.Notice.SessionStateChanged", msg["payload"])
|
|
||||||
if sess_state_msg["param"] == mysqlxpb_enum(
|
|
||||||
"Mysqlx.Notice.SessionStateChanged.Parameter."
|
|
||||||
"GENERATED_DOCUMENT_IDS"):
|
|
||||||
result.set_generated_ids(
|
|
||||||
[get_item_or_attr(
|
|
||||||
get_item_or_attr(value, 'v_octets'), 'value').decode()
|
|
||||||
for value in sess_state_msg["value"]])
|
|
||||||
else: # Following results are unitary and not a list
|
|
||||||
sess_state_value = sess_state_msg["value"][0] \
|
|
||||||
if isinstance(sess_state_msg["value"],
|
|
||||||
tuple(PROTOBUF_REPEATED_TYPES)) \
|
|
||||||
else sess_state_msg["value"]
|
|
||||||
if sess_state_msg["param"] == mysqlxpb_enum(
|
|
||||||
"Mysqlx.Notice.SessionStateChanged.Parameter."
|
|
||||||
"ROWS_AFFECTED"):
|
|
||||||
result.set_rows_affected(
|
|
||||||
get_item_or_attr(sess_state_value, "v_unsigned_int"))
|
|
||||||
elif sess_state_msg["param"] == mysqlxpb_enum(
|
|
||||||
"Mysqlx.Notice.SessionStateChanged.Parameter."
|
|
||||||
"GENERATED_INSERT_ID"):
|
|
||||||
result.set_generated_insert_id(get_item_or_attr(
|
|
||||||
sess_state_value, "v_unsigned_int"))
|
|
||||||
|
|
||||||
def _read_message(self, result):
|
|
||||||
"""Read message.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
result (Result): A `Result` based type object.
|
|
||||||
"""
|
|
||||||
while True:
|
|
||||||
msg = self._reader.read_message()
|
|
||||||
if msg.type == "Mysqlx.Error":
|
|
||||||
raise OperationalError(msg["msg"], msg["code"])
|
|
||||||
elif msg.type == "Mysqlx.Notice.Frame":
|
|
||||||
try:
|
|
||||||
self._process_frame(msg, result)
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
elif msg.type == "Mysqlx.Sql.StmtExecuteOk":
|
|
||||||
return None
|
|
||||||
elif msg.type == "Mysqlx.Resultset.FetchDone":
|
|
||||||
result.set_closed(True)
|
|
||||||
elif msg.type == "Mysqlx.Resultset.FetchDoneMoreResultsets":
|
|
||||||
result.set_has_more_results(True)
|
|
||||||
elif msg.type == "Mysqlx.Resultset.Row":
|
|
||||||
result.set_has_data(True)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
return msg
|
|
||||||
|
|
||||||
def get_capabilites(self):
|
|
||||||
"""Get capabilities.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.protobuf.Message: MySQL X Protobuf Message.
|
|
||||||
"""
|
|
||||||
msg = Message("Mysqlx.Connection.CapabilitiesGet")
|
|
||||||
self._writer.write_message(
|
|
||||||
mysqlxpb_enum("Mysqlx.ClientMessages.Type.CON_CAPABILITIES_GET"),
|
|
||||||
msg)
|
|
||||||
msg = self._reader.read_message()
|
|
||||||
while msg.type == "Mysqlx.Notice.Frame":
|
|
||||||
msg = self._reader.read_message()
|
|
||||||
return msg
|
|
||||||
|
|
||||||
def set_capabilities(self, **kwargs):
|
|
||||||
"""Set capabilities.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
**kwargs: Arbitrary keyword arguments.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.protobuf.Message: MySQL X Protobuf Message.
|
|
||||||
"""
|
|
||||||
capabilities = Message("Mysqlx.Connection.Capabilities")
|
|
||||||
for key, value in kwargs.items():
|
|
||||||
capability = Message("Mysqlx.Connection.Capability")
|
|
||||||
capability["name"] = key
|
|
||||||
if isinstance(value, dict):
|
|
||||||
items = value
|
|
||||||
obj_flds = []
|
|
||||||
for item in items:
|
|
||||||
obj_fld = Message("Mysqlx.Datatypes.Object.ObjectField",
|
|
||||||
key=item,
|
|
||||||
value=self._create_any(items[item]))
|
|
||||||
obj_flds.append(obj_fld.get_message())
|
|
||||||
msg_obj = Message("Mysqlx.Datatypes.Object", fld=obj_flds)
|
|
||||||
msg_any = Message("Mysqlx.Datatypes.Any", type=2, obj=msg_obj)
|
|
||||||
capability["value"] = msg_any.get_message()
|
|
||||||
else:
|
|
||||||
capability["value"] = self._create_any(value)
|
|
||||||
|
|
||||||
capabilities["capabilities"].extend([capability.get_message()])
|
|
||||||
msg = Message("Mysqlx.Connection.CapabilitiesSet")
|
|
||||||
msg["capabilities"] = capabilities
|
|
||||||
self._writer.write_message(
|
|
||||||
mysqlxpb_enum("Mysqlx.ClientMessages.Type.CON_CAPABILITIES_SET"),
|
|
||||||
msg)
|
|
||||||
|
|
||||||
try:
|
|
||||||
return self.read_ok()
|
|
||||||
except InterfaceError as err:
|
|
||||||
# Skip capability "session_connect_attrs" error since
|
|
||||||
# is only available on version >= 8.0.16
|
|
||||||
if err.errno != 5002:
|
|
||||||
raise
|
|
||||||
return None
|
|
||||||
|
|
||||||
def set_session_capabilities(self, **kwargs):
|
|
||||||
"""Set capabilities.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
**kwargs: Arbitrary keyword arguments.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
mysqlx.protobuf.Message: MySQL X Protobuf Message.
|
|
||||||
"""
|
|
||||||
capabilities = Message("Mysqlx.Connection.Capabilities")
|
|
||||||
for key, value in kwargs.items():
|
|
||||||
capability = Message("Mysqlx.Connection.Capability")
|
|
||||||
capability["name"] = key
|
|
||||||
capability["value"] = self._create_any(value)
|
|
||||||
capabilities["capabilities"].extend([capability.get_message()])
|
|
||||||
msg = Message("Mysqlx.Connection.CapabilitiesSet")
|
|
||||||
msg["session_connect_attrs"] = capabilities
|
|
||||||
self._writer.write_message(
|
|
||||||
mysqlxpb_enum("Mysqlx.ClientMessages.Type.CON_CAPABILITIES_SET"),
|
|
||||||
msg)
|
|
||||||
return self.read_ok()
|
|
||||||
|
|
||||||
def send_auth_start(self, method, auth_data=None, initial_response=None):
|
|
||||||
"""Send authenticate start.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
method (str): Message method.
|
|
||||||
auth_data (Optional[str]): Authentication data.
|
|
||||||
initial_response (Optional[str]): Initial response.
|
|
||||||
"""
|
|
||||||
msg = Message("Mysqlx.Session.AuthenticateStart")
|
|
||||||
msg["mech_name"] = method
|
|
||||||
if auth_data is not None:
|
|
||||||
msg["auth_data"] = auth_data
|
|
||||||
if initial_response is not None:
|
|
||||||
msg["initial_response"] = initial_response
|
|
||||||
self._writer.write_message(mysqlxpb_enum(
|
|
||||||
"Mysqlx.ClientMessages.Type.SESS_AUTHENTICATE_START"), msg)
|
|
||||||
|
|
||||||
def read_auth_continue(self):
|
|
||||||
"""Read authenticate continue.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`InterfaceError`: If the message type is not
|
|
||||||
`Mysqlx.Session.AuthenticateContinue`
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: The authentication data.
|
|
||||||
"""
|
|
||||||
msg = self._reader.read_message()
|
|
||||||
while msg.type == "Mysqlx.Notice.Frame":
|
|
||||||
msg = self._reader.read_message()
|
|
||||||
if msg.type != "Mysqlx.Session.AuthenticateContinue":
|
|
||||||
raise InterfaceError("Unexpected message encountered during "
|
|
||||||
"authentication handshake")
|
|
||||||
return msg["auth_data"]
|
|
||||||
|
|
||||||
def send_auth_continue(self, auth_data):
|
|
||||||
"""Send authenticate continue.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
auth_data (str): Authentication data.
|
|
||||||
"""
|
|
||||||
msg = Message("Mysqlx.Session.AuthenticateContinue",
|
|
||||||
auth_data=auth_data)
|
|
||||||
self._writer.write_message(mysqlxpb_enum(
|
|
||||||
"Mysqlx.ClientMessages.Type.SESS_AUTHENTICATE_CONTINUE"), msg)
|
|
||||||
|
|
||||||
def read_auth_ok(self):
|
|
||||||
"""Read authenticate OK.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.InterfaceError`: If message type is `Mysqlx.Error`.
|
|
||||||
"""
|
|
||||||
while True:
|
|
||||||
msg = self._reader.read_message()
|
|
||||||
if msg.type == "Mysqlx.Session.AuthenticateOk":
|
|
||||||
break
|
|
||||||
if msg.type == "Mysqlx.Error":
|
|
||||||
raise InterfaceError(msg.msg)
|
|
||||||
|
|
||||||
def send_prepare_prepare(self, msg_type, msg, stmt):
|
|
||||||
"""
|
|
||||||
Send prepare statement.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_type (str): Message ID string.
|
|
||||||
msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
|
|
||||||
stmt (Statement): A `Statement` based type object.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.NotSupportedError`: If prepared statements are not
|
|
||||||
supported.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
if stmt.has_limit and msg.type != "Mysqlx.Crud.Insert":
|
|
||||||
# Remove 'limit' from message by building a new one
|
|
||||||
if msg.type == "Mysqlx.Crud.Find":
|
|
||||||
_, msg = self.build_find(stmt)
|
|
||||||
elif msg.type == "Mysqlx.Crud.Update":
|
|
||||||
_, msg = self.build_update(stmt)
|
|
||||||
elif msg.type == "Mysqlx.Crud.Delete":
|
|
||||||
_, msg = self.build_delete(stmt)
|
|
||||||
else:
|
|
||||||
raise ValueError("Invalid message type: {}".format(msg_type))
|
|
||||||
# Build 'limit_expr' message
|
|
||||||
position = len(stmt.get_bindings())
|
|
||||||
placeholder = mysqlxpb_enum("Mysqlx.Expr.Expr.Type.PLACEHOLDER")
|
|
||||||
msg_limit_expr = Message("Mysqlx.Crud.LimitExpr")
|
|
||||||
msg_limit_expr["row_count"] = Message("Mysqlx.Expr.Expr",
|
|
||||||
type=placeholder,
|
|
||||||
position=position)
|
|
||||||
if msg.type == "Mysqlx.Crud.Find":
|
|
||||||
msg_limit_expr["offset"] = Message("Mysqlx.Expr.Expr",
|
|
||||||
type=placeholder,
|
|
||||||
position=position + 1)
|
|
||||||
msg["limit_expr"] = msg_limit_expr
|
|
||||||
|
|
||||||
oneof_type, oneof_op = CRUD_PREPARE_MAPPING[msg_type]
|
|
||||||
msg_oneof = Message("Mysqlx.Prepare.Prepare.OneOfMessage")
|
|
||||||
msg_oneof["type"] = mysqlxpb_enum(oneof_type)
|
|
||||||
msg_oneof[oneof_op] = msg
|
|
||||||
msg_prepare = Message("Mysqlx.Prepare.Prepare")
|
|
||||||
msg_prepare["stmt_id"] = stmt.stmt_id
|
|
||||||
msg_prepare["stmt"] = msg_oneof
|
|
||||||
|
|
||||||
self._writer.write_message(
|
|
||||||
mysqlxpb_enum("Mysqlx.ClientMessages.Type.PREPARE_PREPARE"),
|
|
||||||
msg_prepare)
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.read_ok()
|
|
||||||
except InterfaceError:
|
|
||||||
raise NotSupportedError
|
|
||||||
|
|
||||||
def send_prepare_execute(self, msg_type, msg, stmt):
|
|
||||||
"""
|
|
||||||
Send execute statement.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_type (str): Message ID string.
|
|
||||||
msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
|
|
||||||
stmt (Statement): A `Statement` based type object.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
oneof_type, oneof_op = CRUD_PREPARE_MAPPING[msg_type]
|
|
||||||
msg_oneof = Message("Mysqlx.Prepare.Prepare.OneOfMessage")
|
|
||||||
msg_oneof["type"] = mysqlxpb_enum(oneof_type)
|
|
||||||
msg_oneof[oneof_op] = msg
|
|
||||||
msg_execute = Message("Mysqlx.Prepare.Execute")
|
|
||||||
msg_execute["stmt_id"] = stmt.stmt_id
|
|
||||||
|
|
||||||
args = self._get_binding_args(stmt, is_scalar=False)
|
|
||||||
if args:
|
|
||||||
msg_execute["args"].extend(args)
|
|
||||||
|
|
||||||
if stmt.has_limit:
|
|
||||||
msg_execute["args"].extend([
|
|
||||||
self._create_any(stmt.get_limit_row_count()).get_message(),
|
|
||||||
self._create_any(stmt.get_limit_offset()).get_message()
|
|
||||||
])
|
|
||||||
|
|
||||||
self._writer.write_message(
|
|
||||||
mysqlxpb_enum("Mysqlx.ClientMessages.Type.PREPARE_EXECUTE"),
|
|
||||||
msg_execute)
|
|
||||||
|
|
||||||
def send_prepare_deallocate(self, stmt_id):
|
|
||||||
"""
|
|
||||||
Send prepare deallocate statement.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
stmt_id (int): Statement ID.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
msg_dealloc = Message("Mysqlx.Prepare.Deallocate")
|
|
||||||
msg_dealloc["stmt_id"] = stmt_id
|
|
||||||
self._writer.write_message(
|
|
||||||
mysqlxpb_enum("Mysqlx.ClientMessages.Type.PREPARE_DEALLOCATE"),
|
|
||||||
msg_dealloc)
|
|
||||||
self.read_ok()
|
|
||||||
|
|
||||||
def send_msg_without_ps(self, msg_type, msg, stmt):
|
|
||||||
"""
|
|
||||||
Send a message without prepared statements support.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_type (str): Message ID string.
|
|
||||||
msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
|
|
||||||
stmt (Statement): A `Statement` based type object.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
if stmt.has_limit:
|
|
||||||
msg_limit = Message("Mysqlx.Crud.Limit")
|
|
||||||
msg_limit["row_count"] = stmt.get_limit_row_count()
|
|
||||||
if msg.type == "Mysqlx.Crud.Find":
|
|
||||||
msg_limit["offset"] = stmt.get_limit_offset()
|
|
||||||
msg["limit"] = msg_limit
|
|
||||||
is_scalar = False \
|
|
||||||
if msg_type == "Mysqlx.ClientMessages.Type.SQL_STMT_EXECUTE" \
|
|
||||||
else True
|
|
||||||
args = self._get_binding_args(stmt, is_scalar=is_scalar)
|
|
||||||
if args:
|
|
||||||
msg["args"].extend(args)
|
|
||||||
self.send_msg(msg_type, msg)
|
|
||||||
|
|
||||||
def send_msg(self, msg_type, msg):
|
|
||||||
"""
|
|
||||||
Send a message.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
msg_type (str): Message ID string.
|
|
||||||
msg (mysqlx.protobuf.Message): MySQL X Protobuf Message.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
self._writer.write_message(mysqlxpb_enum(msg_type), msg)
|
|
||||||
|
|
||||||
def build_find(self, stmt):
|
|
||||||
"""Build find/read message.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
stmt (Statement): A :class:`mysqlx.ReadStatement` or
|
|
||||||
:class:`mysqlx.FindStatement` object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(tuple): Tuple containing:
|
|
||||||
|
|
||||||
* `str`: Message ID string.
|
|
||||||
* :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
data_model = mysqlxpb_enum("Mysqlx.Crud.DataModel.DOCUMENT"
|
|
||||||
if stmt.is_doc_based() else
|
|
||||||
"Mysqlx.Crud.DataModel.TABLE")
|
|
||||||
collection = Message("Mysqlx.Crud.Collection",
|
|
||||||
name=stmt.target.name,
|
|
||||||
schema=stmt.schema.name)
|
|
||||||
msg = Message("Mysqlx.Crud.Find", data_model=data_model,
|
|
||||||
collection=collection)
|
|
||||||
if stmt.has_projection:
|
|
||||||
msg["projection"] = stmt.get_projection_expr()
|
|
||||||
self._apply_filter(msg, stmt)
|
|
||||||
|
|
||||||
if stmt.is_lock_exclusive():
|
|
||||||
msg["locking"] = \
|
|
||||||
mysqlxpb_enum("Mysqlx.Crud.Find.RowLock.EXCLUSIVE_LOCK")
|
|
||||||
elif stmt.is_lock_shared():
|
|
||||||
msg["locking"] = \
|
|
||||||
mysqlxpb_enum("Mysqlx.Crud.Find.RowLock.SHARED_LOCK")
|
|
||||||
|
|
||||||
if stmt.lock_contention > 0:
|
|
||||||
msg["locking_options"] = stmt.lock_contention
|
|
||||||
|
|
||||||
return "Mysqlx.ClientMessages.Type.CRUD_FIND", msg
|
|
||||||
|
|
||||||
def build_update(self, stmt):
|
|
||||||
"""Build update message.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
stmt (Statement): A :class:`mysqlx.ModifyStatement` or
|
|
||||||
:class:`mysqlx.UpdateStatement` object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(tuple): Tuple containing:
|
|
||||||
|
|
||||||
* `str`: Message ID string.
|
|
||||||
* :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
data_model = mysqlxpb_enum("Mysqlx.Crud.DataModel.DOCUMENT"
|
|
||||||
if stmt.is_doc_based() else
|
|
||||||
"Mysqlx.Crud.DataModel.TABLE")
|
|
||||||
collection = Message("Mysqlx.Crud.Collection",
|
|
||||||
name=stmt.target.name,
|
|
||||||
schema=stmt.schema.name)
|
|
||||||
msg = Message("Mysqlx.Crud.Update", data_model=data_model,
|
|
||||||
collection=collection)
|
|
||||||
self._apply_filter(msg, stmt)
|
|
||||||
for _, update_op in stmt.get_update_ops().items():
|
|
||||||
operation = Message("Mysqlx.Crud.UpdateOperation")
|
|
||||||
operation["operation"] = update_op.update_type
|
|
||||||
operation["source"] = update_op.source
|
|
||||||
if update_op.value is not None:
|
|
||||||
operation["value"] = build_expr(update_op.value)
|
|
||||||
msg["operation"].extend([operation.get_message()])
|
|
||||||
|
|
||||||
return "Mysqlx.ClientMessages.Type.CRUD_UPDATE", msg
|
|
||||||
|
|
||||||
def build_delete(self, stmt):
|
|
||||||
"""Build delete message.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
stmt (Statement): A :class:`mysqlx.DeleteStatement` or
|
|
||||||
:class:`mysqlx.RemoveStatement` object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(tuple): Tuple containing:
|
|
||||||
|
|
||||||
* `str`: Message ID string.
|
|
||||||
* :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
data_model = mysqlxpb_enum("Mysqlx.Crud.DataModel.DOCUMENT"
|
|
||||||
if stmt.is_doc_based() else
|
|
||||||
"Mysqlx.Crud.DataModel.TABLE")
|
|
||||||
collection = Message("Mysqlx.Crud.Collection", name=stmt.target.name,
|
|
||||||
schema=stmt.schema.name)
|
|
||||||
msg = Message("Mysqlx.Crud.Delete", data_model=data_model,
|
|
||||||
collection=collection)
|
|
||||||
self._apply_filter(msg, stmt)
|
|
||||||
return "Mysqlx.ClientMessages.Type.CRUD_DELETE", msg
|
|
||||||
|
|
||||||
def build_execute_statement(self, namespace, stmt, fields=None):
|
|
||||||
"""Build execute statement.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
namespace (str): The namespace.
|
|
||||||
stmt (Statement): A `Statement` based type object.
|
|
||||||
fields (Optional[dict]): The message fields.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(tuple): Tuple containing:
|
|
||||||
|
|
||||||
* `str`: Message ID string.
|
|
||||||
* :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
msg = Message("Mysqlx.Sql.StmtExecute", namespace=namespace, stmt=stmt,
|
|
||||||
compact_metadata=False)
|
|
||||||
|
|
||||||
if fields:
|
|
||||||
obj_flds = []
|
|
||||||
for key, value in fields.items():
|
|
||||||
obj_fld = Message("Mysqlx.Datatypes.Object.ObjectField",
|
|
||||||
key=key, value=self._create_any(value))
|
|
||||||
obj_flds.append(obj_fld.get_message())
|
|
||||||
msg_obj = Message("Mysqlx.Datatypes.Object", fld=obj_flds)
|
|
||||||
msg_any = Message("Mysqlx.Datatypes.Any", type=2, obj=msg_obj)
|
|
||||||
msg["args"] = [msg_any.get_message()]
|
|
||||||
|
|
||||||
return "Mysqlx.ClientMessages.Type.SQL_STMT_EXECUTE", msg
|
|
||||||
|
|
||||||
def build_insert(self, stmt):
|
|
||||||
"""Build insert statement.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
stmt (Statement): A :class:`mysqlx.AddStatement` or
|
|
||||||
:class:`mysqlx.InsertStatement` object.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
(tuple): Tuple containing:
|
|
||||||
|
|
||||||
* `str`: Message ID string.
|
|
||||||
* :class:`mysqlx.protobuf.Message`: MySQL X Protobuf Message.
|
|
||||||
|
|
||||||
.. versionadded:: 8.0.16
|
|
||||||
"""
|
|
||||||
data_model = mysqlxpb_enum("Mysqlx.Crud.DataModel.DOCUMENT"
|
|
||||||
if stmt.is_doc_based() else
|
|
||||||
"Mysqlx.Crud.DataModel.TABLE")
|
|
||||||
collection = Message("Mysqlx.Crud.Collection",
|
|
||||||
name=stmt.target.name,
|
|
||||||
schema=stmt.schema.name)
|
|
||||||
msg = Message("Mysqlx.Crud.Insert", data_model=data_model,
|
|
||||||
collection=collection)
|
|
||||||
|
|
||||||
if hasattr(stmt, "_fields"):
|
|
||||||
for field in stmt._fields:
|
|
||||||
expr = ExprParser(field, not stmt.is_doc_based()) \
|
|
||||||
.parse_table_insert_field()
|
|
||||||
msg["projection"].extend([expr.get_message()])
|
|
||||||
|
|
||||||
for value in stmt.get_values():
|
|
||||||
row = Message("Mysqlx.Crud.Insert.TypedRow")
|
|
||||||
if isinstance(value, list):
|
|
||||||
for val in value:
|
|
||||||
row["field"].extend([build_expr(val).get_message()])
|
|
||||||
else:
|
|
||||||
row["field"].extend([build_expr(value).get_message()])
|
|
||||||
msg["row"].extend([row.get_message()])
|
|
||||||
|
|
||||||
if hasattr(stmt, "is_upsert"):
|
|
||||||
msg["upsert"] = stmt.is_upsert()
|
|
||||||
|
|
||||||
return "Mysqlx.ClientMessages.Type.CRUD_INSERT", msg
|
|
||||||
|
|
||||||
def close_result(self, result):
|
|
||||||
"""Close the result.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
result (Result): A `Result` based type object.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.OperationalError`: If message read is None.
|
|
||||||
"""
|
|
||||||
msg = self._read_message(result)
|
|
||||||
if msg is not None:
|
|
||||||
raise OperationalError("Expected to close the result")
|
|
||||||
|
|
||||||
def read_row(self, result):
|
|
||||||
"""Read row.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
result (Result): A `Result` based type object.
|
|
||||||
"""
|
|
||||||
msg = self._read_message(result)
|
|
||||||
if msg is None:
|
|
||||||
return None
|
|
||||||
if msg.type == "Mysqlx.Resultset.Row":
|
|
||||||
return msg
|
|
||||||
self._reader.push_message(msg)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_column_metadata(self, result):
|
|
||||||
"""Returns column metadata.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
result (Result): A `Result` based type object.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.InterfaceError`: If unexpected message.
|
|
||||||
"""
|
|
||||||
columns = []
|
|
||||||
while True:
|
|
||||||
msg = self._read_message(result)
|
|
||||||
if msg is None:
|
|
||||||
break
|
|
||||||
if msg.type == "Mysqlx.Resultset.Row":
|
|
||||||
self._reader.push_message(msg)
|
|
||||||
break
|
|
||||||
if msg.type != "Mysqlx.Resultset.ColumnMetaData":
|
|
||||||
raise InterfaceError("Unexpected msg type")
|
|
||||||
col = Column(msg["type"], msg["catalog"], msg["schema"],
|
|
||||||
msg["table"], msg["original_table"],
|
|
||||||
msg["name"], msg["original_name"],
|
|
||||||
msg.get("length", 21),
|
|
||||||
msg.get("collation", 0),
|
|
||||||
msg.get("fractional_digits", 0),
|
|
||||||
msg.get("flags", 16),
|
|
||||||
msg.get("content_type"))
|
|
||||||
columns.append(col)
|
|
||||||
return columns
|
|
||||||
|
|
||||||
def read_ok(self):
|
|
||||||
"""Read OK.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
:class:`mysqlx.InterfaceError`: If unexpected message.
|
|
||||||
"""
|
|
||||||
msg = self._reader.read_message()
|
|
||||||
if msg.type == "Mysqlx.Error":
|
|
||||||
raise InterfaceError("Mysqlx.Error: {}".format(msg["msg"]),
|
|
||||||
errno=msg["code"])
|
|
||||||
if msg.type != "Mysqlx.Ok":
|
|
||||||
raise InterfaceError("Unexpected message encountered")
|
|
||||||
|
|
||||||
def send_connection_close(self):
|
|
||||||
"""Send connection close."""
|
|
||||||
msg = Message("Mysqlx.Connection.Close")
|
|
||||||
self._writer.write_message(mysqlxpb_enum(
|
|
||||||
"Mysqlx.ClientMessages.Type.CON_CLOSE"), msg)
|
|
||||||
|
|
||||||
def send_close(self):
|
|
||||||
"""Send close."""
|
|
||||||
msg = Message("Mysqlx.Session.Close")
|
|
||||||
self._writer.write_message(mysqlxpb_enum(
|
|
||||||
"Mysqlx.ClientMessages.Type.SESS_CLOSE"), msg)
|
|
||||||
|
|
||||||
def send_expect_open(self):
|
|
||||||
"""Send expectation."""
|
|
||||||
cond_key = mysqlxpb_enum(
|
|
||||||
"Mysqlx.Expect.Open.Condition.Key.EXPECT_FIELD_EXIST")
|
|
||||||
msg_oc = Message("Mysqlx.Expect.Open.Condition")
|
|
||||||
msg_oc["condition_key"] = cond_key
|
|
||||||
msg_oc["condition_value"] = "6.1"
|
|
||||||
|
|
||||||
msg_eo = Message("Mysqlx.Expect.Open")
|
|
||||||
msg_eo['cond'] = [msg_oc.get_message()]
|
|
||||||
|
|
||||||
self._writer.write_message(mysqlxpb_enum(
|
|
||||||
"Mysqlx.ClientMessages.Type.EXPECT_OPEN"), msg_eo)
|
|
||||||
|
|
||||||
def send_reset(self, keep_open=None):
|
|
||||||
"""Send reset session message.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
boolean: ``True`` if the server will keep the session open,
|
|
||||||
otherwise ``False``.
|
|
||||||
"""
|
|
||||||
msg = Message("Mysqlx.Session.Reset")
|
|
||||||
if keep_open is None:
|
|
||||||
try:
|
|
||||||
# Send expectation: keep connection open
|
|
||||||
self.send_expect_open()
|
|
||||||
self.read_ok()
|
|
||||||
keep_open = True
|
|
||||||
except InterfaceError:
|
|
||||||
# Expectation is unkown by this version of the server
|
|
||||||
keep_open = False
|
|
||||||
if keep_open:
|
|
||||||
msg["keep_open"] = True
|
|
||||||
self._writer.write_message(mysqlxpb_enum(
|
|
||||||
"Mysqlx.ClientMessages.Type.SESS_RESET"), msg)
|
|
||||||
self.read_ok()
|
|
||||||
if keep_open:
|
|
||||||
return True
|
|
||||||
return False
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue