# MySQL Connector/Python - MySQL driver written in Python. # Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. # MySQL Connector/Python is licensed under the terms of the GPLv2 # , like most # MySQL Connectors. There are special exceptions to the terms and # conditions of the GPLv2 as it is applied to this software, see the # FOSS License Exception # . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation. # # 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 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 .protobuf import mysqlx_pb2 as MySQLx from .protobuf import mysqlx_session_pb2 as MySQLxSession from .protobuf import mysqlx_sql_pb2 as MySQLxSQL from .protobuf import mysqlx_notice_pb2 as MySQLxNotice from .protobuf import mysqlx_datatypes_pb2 as MySQLxDatatypes from .protobuf import mysqlx_resultset_pb2 as MySQLxResultset from .protobuf import mysqlx_crud_pb2 as MySQLxCrud from .protobuf import mysqlx_expr_pb2 as MySQLxExpr from .protobuf import mysqlx_connection_pb2 as MySQLxConnection from .result import ColumnMetaData from .compat import STRING_TYPES, INT_TYPES from .dbdoc import DbDoc from .errors import InterfaceError, OperationalError, ProgrammingError from .expr import (ExprParser, build_null_scalar, build_string_scalar, build_bool_scalar, build_double_scalar, build_int_scalar) _SERVER_MESSAGES = [ (MySQLx.ServerMessages.SESS_AUTHENTICATE_CONTINUE, MySQLxSession.AuthenticateContinue), (MySQLx.ServerMessages.SESS_AUTHENTICATE_OK, MySQLxSession.AuthenticateOk), (MySQLx.ServerMessages.SQL_STMT_EXECUTE_OK, MySQLxSQL.StmtExecuteOk), (MySQLx.ServerMessages.ERROR, MySQLx.Error), (MySQLx.ServerMessages.NOTICE, MySQLxNotice.Frame), (MySQLx.ServerMessages.RESULTSET_COLUMN_META_DATA, MySQLxResultset.ColumnMetaData), (MySQLx.ServerMessages.RESULTSET_ROW, MySQLxResultset.Row), (MySQLx.ServerMessages.RESULTSET_FETCH_DONE, MySQLxResultset.FetchDone), (MySQLx.ServerMessages.RESULTSET_FETCH_DONE_MORE_RESULTSETS, MySQLxResultset.FetchDoneMoreResultsets), (MySQLx.ServerMessages.OK, MySQLx.Ok), (MySQLx.ServerMessages.CONN_CAPABILITIES, MySQLxConnection.Capabilities), ] def encode_to_bytes(value, encoding="utf-8"): return value if isinstance(value, bytes) else value.encode(encoding) class MessageReaderWriter(object): def __init__(self, socket_stream): self._stream = socket_stream self._msg = None def push_message(self, msg): if self._msg is not None: raise OperationalError("Message push slot is full") self._msg = msg def read_message(self): if self._msg is not None: m = self._msg self._msg = None return m return self._read_message() def _read_message(self): hdr = self._stream.read(5) msg_len, msg_type = struct.unpack("