# 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("