lol
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -37,6 +37,8 @@ from ...util.concurrency import await_only
|
||||
|
||||
|
||||
class AsyncAdapt_aiomysql_cursor:
|
||||
# TODO: base on connectors/asyncio.py
|
||||
# see #10415
|
||||
server_side = False
|
||||
__slots__ = (
|
||||
"_adapt_connection",
|
||||
@@ -139,6 +141,8 @@ class AsyncAdapt_aiomysql_cursor:
|
||||
|
||||
|
||||
class AsyncAdapt_aiomysql_ss_cursor(AsyncAdapt_aiomysql_cursor):
|
||||
# TODO: base on connectors/asyncio.py
|
||||
# see #10415
|
||||
__slots__ = ()
|
||||
server_side = True
|
||||
|
||||
@@ -167,6 +171,8 @@ class AsyncAdapt_aiomysql_ss_cursor(AsyncAdapt_aiomysql_cursor):
|
||||
|
||||
|
||||
class AsyncAdapt_aiomysql_connection(AdaptedConnection):
|
||||
# TODO: base on connectors/asyncio.py
|
||||
# see #10415
|
||||
await_ = staticmethod(await_only)
|
||||
__slots__ = ("dbapi", "_execute_mutex")
|
||||
|
||||
@@ -202,6 +208,8 @@ class AsyncAdapt_aiomysql_connection(AdaptedConnection):
|
||||
|
||||
|
||||
class AsyncAdaptFallback_aiomysql_connection(AsyncAdapt_aiomysql_connection):
|
||||
# TODO: base on connectors/asyncio.py
|
||||
# see #10415
|
||||
__slots__ = ()
|
||||
|
||||
await_ = staticmethod(await_fallback)
|
||||
|
||||
@@ -37,6 +37,8 @@ from ...util.concurrency import await_only
|
||||
|
||||
|
||||
class AsyncAdapt_asyncmy_cursor:
|
||||
# TODO: base on connectors/asyncio.py
|
||||
# see #10415
|
||||
server_side = False
|
||||
__slots__ = (
|
||||
"_adapt_connection",
|
||||
@@ -141,6 +143,8 @@ class AsyncAdapt_asyncmy_cursor:
|
||||
|
||||
|
||||
class AsyncAdapt_asyncmy_ss_cursor(AsyncAdapt_asyncmy_cursor):
|
||||
# TODO: base on connectors/asyncio.py
|
||||
# see #10415
|
||||
__slots__ = ()
|
||||
server_side = True
|
||||
|
||||
@@ -171,6 +175,8 @@ class AsyncAdapt_asyncmy_ss_cursor(AsyncAdapt_asyncmy_cursor):
|
||||
|
||||
|
||||
class AsyncAdapt_asyncmy_connection(AdaptedConnection):
|
||||
# TODO: base on connectors/asyncio.py
|
||||
# see #10415
|
||||
await_ = staticmethod(await_only)
|
||||
__slots__ = ("dbapi", "_execute_mutex")
|
||||
|
||||
|
||||
@@ -999,14 +999,14 @@ output::
|
||||
)
|
||||
|
||||
""" # noqa
|
||||
from __future__ import annotations
|
||||
|
||||
from array import array as _array
|
||||
from collections import defaultdict
|
||||
from itertools import compress
|
||||
import re
|
||||
from typing import cast
|
||||
|
||||
from sqlalchemy import literal_column
|
||||
from sqlalchemy.sql import visitors
|
||||
from . import reflection as _reflection
|
||||
from .enumerated import ENUM
|
||||
from .enumerated import SET
|
||||
@@ -1047,10 +1047,12 @@ from .types import TINYTEXT
|
||||
from .types import VARCHAR
|
||||
from .types import YEAR
|
||||
from ... import exc
|
||||
from ... import literal_column
|
||||
from ... import log
|
||||
from ... import schema as sa_schema
|
||||
from ... import sql
|
||||
from ... import util
|
||||
from ...engine import cursor as _cursor
|
||||
from ...engine import default
|
||||
from ...engine import reflection
|
||||
from ...engine.reflection import ReflectionDefaults
|
||||
@@ -1062,7 +1064,10 @@ from ...sql import operators
|
||||
from ...sql import roles
|
||||
from ...sql import sqltypes
|
||||
from ...sql import util as sql_util
|
||||
from ...sql import visitors
|
||||
from ...sql.compiler import InsertmanyvaluesSentinelOpts
|
||||
from ...sql.compiler import SQLCompiler
|
||||
from ...sql.schema import SchemaConst
|
||||
from ...types import BINARY
|
||||
from ...types import BLOB
|
||||
from ...types import BOOLEAN
|
||||
@@ -1071,6 +1076,7 @@ from ...types import UUID
|
||||
from ...types import VARBINARY
|
||||
from ...util import topological
|
||||
|
||||
|
||||
SET_RE = re.compile(
|
||||
r"\s*SET\s+(?:(?:GLOBAL|SESSION)\s+)?\w", re.I | re.UNICODE
|
||||
)
|
||||
@@ -1164,6 +1170,32 @@ ischema_names = {
|
||||
|
||||
|
||||
class MySQLExecutionContext(default.DefaultExecutionContext):
|
||||
def post_exec(self):
|
||||
if (
|
||||
self.isdelete
|
||||
and cast(SQLCompiler, self.compiled).effective_returning
|
||||
and not self.cursor.description
|
||||
):
|
||||
# All MySQL/mariadb drivers appear to not include
|
||||
# cursor.description for DELETE..RETURNING with no rows if the
|
||||
# WHERE criteria is a straight "false" condition such as our EMPTY
|
||||
# IN condition. manufacture an empty result in this case (issue
|
||||
# #10505)
|
||||
#
|
||||
# taken from cx_Oracle implementation
|
||||
self.cursor_fetch_strategy = (
|
||||
_cursor.FullyBufferedCursorFetchStrategy(
|
||||
self.cursor,
|
||||
[
|
||||
(entry.keyname, None)
|
||||
for entry in cast(
|
||||
SQLCompiler, self.compiled
|
||||
)._result_columns
|
||||
],
|
||||
[],
|
||||
)
|
||||
)
|
||||
|
||||
def create_server_side_cursor(self):
|
||||
if self.dialect.supports_server_side_cursors:
|
||||
return self._dbapi_connection.cursor(self.dialect._sscursor)
|
||||
@@ -1208,6 +1240,12 @@ class MySQLCompiler(compiler.SQLCompiler):
|
||||
)
|
||||
return f"{clause} WITH ROLLUP"
|
||||
|
||||
def visit_aggregate_strings_func(self, fn, **kw):
|
||||
expr, delimeter = (
|
||||
elem._compiler_dispatch(self, **kw) for elem in fn.clauses
|
||||
)
|
||||
return f"group_concat({expr} SEPARATOR {delimeter})"
|
||||
|
||||
def visit_sequence(self, seq, **kw):
|
||||
return "nextval(%s)" % self.preparer.format_sequence(seq)
|
||||
|
||||
@@ -1760,7 +1798,12 @@ class MySQLCompiler(compiler.SQLCompiler):
|
||||
class MySQLDDLCompiler(compiler.DDLCompiler):
|
||||
def get_column_specification(self, column, **kw):
|
||||
"""Builds column DDL."""
|
||||
|
||||
if (
|
||||
self.dialect.is_mariadb is True
|
||||
and column.computed is not None
|
||||
and column._user_defined_nullable is SchemaConst.NULL_UNSPECIFIED
|
||||
):
|
||||
column.nullable = True
|
||||
colspec = [
|
||||
self.preparer.format_column(column),
|
||||
self.dialect.type_compiler_instance.process(
|
||||
|
||||
@@ -30,16 +30,46 @@ be ``mysqldb``. ``mariadb+mariadbconnector://`` is required to use this driver.
|
||||
|
||||
""" # noqa
|
||||
import re
|
||||
from uuid import UUID as _python_UUID
|
||||
|
||||
from .base import MySQLCompiler
|
||||
from .base import MySQLDialect
|
||||
from .base import MySQLExecutionContext
|
||||
from ... import sql
|
||||
from ... import util
|
||||
from ...sql import sqltypes
|
||||
|
||||
|
||||
mariadb_cpy_minimum_version = (1, 0, 1)
|
||||
|
||||
|
||||
class _MariaDBUUID(sqltypes.UUID[sqltypes._UUID_RETURN]):
|
||||
# work around JIRA issue
|
||||
# https://jira.mariadb.org/browse/CONPY-270. When that issue is fixed,
|
||||
# this type can be removed.
|
||||
def result_processor(self, dialect, coltype):
|
||||
if self.as_uuid:
|
||||
|
||||
def process(value):
|
||||
if value is not None:
|
||||
if hasattr(value, "decode"):
|
||||
value = value.decode("ascii")
|
||||
value = _python_UUID(value)
|
||||
return value
|
||||
|
||||
return process
|
||||
else:
|
||||
|
||||
def process(value):
|
||||
if value is not None:
|
||||
if hasattr(value, "decode"):
|
||||
value = value.decode("ascii")
|
||||
value = str(_python_UUID(value))
|
||||
return value
|
||||
|
||||
return process
|
||||
|
||||
|
||||
class MySQLExecutionContext_mariadbconnector(MySQLExecutionContext):
|
||||
_lastrowid = None
|
||||
|
||||
@@ -50,9 +80,20 @@ class MySQLExecutionContext_mariadbconnector(MySQLExecutionContext):
|
||||
return self._dbapi_connection.cursor(buffered=True)
|
||||
|
||||
def post_exec(self):
|
||||
super().post_exec()
|
||||
|
||||
self._rowcount = self.cursor.rowcount
|
||||
|
||||
if self.isinsert and self.compiled.postfetch_lastrowid:
|
||||
self._lastrowid = self.cursor.lastrowid
|
||||
|
||||
@property
|
||||
def rowcount(self):
|
||||
if self._rowcount is not None:
|
||||
return self._rowcount
|
||||
else:
|
||||
return self.cursor.rowcount
|
||||
|
||||
def get_lastrowid(self):
|
||||
return self._lastrowid
|
||||
|
||||
@@ -87,6 +128,10 @@ class MySQLDialect_mariadbconnector(MySQLDialect):
|
||||
|
||||
supports_server_side_cursors = True
|
||||
|
||||
colspecs = util.update_copy(
|
||||
MySQLDialect.colspecs, {sqltypes.Uuid: _MariaDBUUID}
|
||||
)
|
||||
|
||||
@util.memoized_property
|
||||
def _dbapi_version(self):
|
||||
if self.dbapi and hasattr(self.dbapi, "__version__"):
|
||||
|
||||
@@ -168,7 +168,7 @@ class MySQLDialect_mysqldb(MySQLDialect):
|
||||
return on_connect
|
||||
|
||||
def do_ping(self, dbapi_connection):
|
||||
dbapi_connection.ping(False)
|
||||
dbapi_connection.ping()
|
||||
return True
|
||||
|
||||
def do_executemany(self, cursor, statement, parameters, context=None):
|
||||
|
||||
@@ -74,6 +74,40 @@ class MySQLDialect_pymysql(MySQLDialect_mysqldb):
|
||||
def import_dbapi(cls):
|
||||
return __import__("pymysql")
|
||||
|
||||
@langhelpers.memoized_property
|
||||
def _send_false_to_ping(self):
|
||||
"""determine if pymysql has deprecated, changed the default of,
|
||||
or removed the 'reconnect' argument of connection.ping().
|
||||
|
||||
See #10492 and
|
||||
https://github.com/PyMySQL/mysqlclient/discussions/651#discussioncomment-7308971
|
||||
for background.
|
||||
|
||||
""" # noqa: E501
|
||||
|
||||
try:
|
||||
Connection = __import__("pymysql.connections").Connection
|
||||
except (ImportError, AttributeError):
|
||||
return True
|
||||
else:
|
||||
insp = langhelpers.get_callable_argspec(Connection.ping)
|
||||
try:
|
||||
reconnect_arg = insp.args[1]
|
||||
except IndexError:
|
||||
return False
|
||||
else:
|
||||
return reconnect_arg == "reconnect" and (
|
||||
not insp.defaults or insp.defaults[0] is not False
|
||||
)
|
||||
|
||||
def do_ping(self, dbapi_connection):
|
||||
if self._send_false_to_ping:
|
||||
dbapi_connection.ping(False)
|
||||
else:
|
||||
dbapi_connection.ping()
|
||||
|
||||
return True
|
||||
|
||||
def create_connect_args(self, url, _translate_args=None):
|
||||
if _translate_args is None:
|
||||
_translate_args = dict(username="user")
|
||||
|
||||
@@ -509,7 +509,7 @@ class MySQLTableDefinitionParser:
|
||||
r"\((?P<local>[^\)]+?)\) REFERENCES +"
|
||||
r"(?P<table>%(iq)s[^%(fq)s]+%(fq)s"
|
||||
r"(?:\.%(iq)s[^%(fq)s]+%(fq)s)?) +"
|
||||
r"\((?P<foreign>[^\)]+?)\)"
|
||||
r"\((?P<foreign>(?:%(iq)s[^%(fq)s]+%(fq)s(?: *, *)?)+)\)"
|
||||
r"(?: +(?P<match>MATCH \w+))?"
|
||||
r"(?: +ON DELETE (?P<ondelete>%(on)s))?"
|
||||
r"(?: +ON UPDATE (?P<onupdate>%(on)s))?" % kw
|
||||
|
||||
Reference in New Issue
Block a user