예제 #1
0
 def _get_field(self, field):
     from psycopg2cffi._impl.adapters import bytes_to_ascii
     if self._exc and self._exc._pgres:
         b = libpq.PQresultErrorField(self._exc._pgres, field)
         if b:
             b = ffi.string(b)
             if six.PY3: # py2 tests insist on str here
                 b = bytes_to_ascii(b)
             return b
예제 #2
0
    def _create_exception(self, pgres=None, msg=None, cursor=None):
        """Return the appropriate exception instance for the current status.

        IMPORTANT: the new exception takes ownership of pgres: if pgres is
        passed as parameter, the callee must delete its pointer (e.g. it may
        be set to null). If there is a pgres in the cursor it is "stolen": the
        cursor will have it set to Null.

        """
        assert pgres is None or cursor is None, \
            "cannot specify pgres and cursor together"

        if cursor and cursor._pgres:
            pgres, cursor._pgres = cursor._pgres, ffi.NULL

        exc_type = exceptions.OperationalError
        code = pgmsg = None

        # If no custom message is passed then get the message from postgres.
        # If pgres is available then we first try to get the message for the
        # last command, and then the error message for the connection
        if pgres:
            pgmsg = libpq.PQresultErrorMessage(pgres)
            pgmsg = bytes_to_ascii(ffi.string(pgmsg)) if pgmsg else None

            # Get the correct exception class based on the error code
            code = libpq.PQresultErrorField(pgres, libpq.PG_DIAG_SQLSTATE)
            if code != ffi.NULL:
                code = bytes_to_ascii(ffi.string(code))
                exc_type = util.get_exception_for_sqlstate(code)
            else:
                code = None
                exc_type = exceptions.DatabaseError

        if not pgmsg:
            pgmsg = libpq.PQerrorMessage(self._pgconn)
            pgmsg = bytes_to_ascii(ffi.string(pgmsg)) if pgmsg else None

        if msg is None and pgmsg:
            msg = pgmsg
            for prefix in ("ERROR:  ", "FATAL:  ", "PANIC:  "):
                if msg.startswith(prefix):
                    msg = msg[len(prefix):]
                    break

        # Clear the connection if the status is CONNECTION_BAD (fatal error)
        if self._pgconn and libpq.PQstatus(
                self._pgconn) == libpq.CONNECTION_BAD:
            self._closed = 2

        exc = exc_type(msg)
        exc.pgcode = code
        exc.pgerror = pgmsg
        exc.cursor = cursor
        exc._pgres = pgres

        return exc
예제 #3
0
 def _get_field(self, field):
     if self._exc and self._exc._pgres:
         b = libpq.PQresultErrorField(self._exc._pgres, field)
         if b:
             return ffi.string(b)