Exemplo n.º 1
0
    def _poll_setup_async(self):
        """Advance to the next state during an async connection setup

        If the connection is green, this is performed by the regular sync
        code so the queries are sent by conn_setup() while in
        CONN_STATUS_READY state.

        """
        if self.status == consts.STATUS_CONNECTING:
            util.pq_set_non_blocking(self._pgconn, 1, True)

            self._equote = self._get_equote()
            self._get_encoding()
            self._cancel = libpq.PQgetCancel(self._pgconn)
            if self._cancel is None:
                raise exceptions.OperationalError("can't get cancellation key")

            self._autocommit = True

            # If the current datestyle is not compatible (not ISO) then
            # force it to ISO
            datestyle = libpq.PQparameterStatus(self._pgconn, 'DateStyle')
            if not datestyle or not datestyle.startswith('ISO'):
                self.status = consts.STATUS_DATESTYLE

                if libpq.PQsendQuery(self._pgconn, "SET DATESTYLE TO 'ISO'"):
                    self._async_status = consts.ASYNC_WRITE
                    return consts.POLL_WRITE
                else:
                    raise self._create_exception()

            self.status = consts.STATUS_READY
            return consts.POLL_OK

        if self.status == consts.STATUS_DATESTYLE:
            res = self._poll_query()
            if res != consts.POLL_OK:
                return res

            pgres = util.pq_get_last_result(self._pgconn)
            if not pgres or \
                libpq.PQresultStatus(pgres) != libpq.PGRES_COMMAND_OK:
                raise exceptions.OperationalError("can't set datetyle to ISO")
            libpq.PQclear(pgres)

            self.status = consts.STATUS_READY
            return consts.POLL_OK

        return consts.POLL_ERROR
Exemplo n.º 2
0
 def _is_busy(self):
     with self._lock:
         if libpq.PQconsumeInput(self._pgconn) == 0:
             raise exceptions.OperationalError(
                 libpq.PQerrorMessage(self._pgconn))
         res = libpq.PQisBusy(self._pgconn)
         self._process_notifies()
         return res
Exemplo n.º 3
0
    def _connect_sync(self):
        self._pgconn = libpq.PQconnectdb(self.dsn)
        if not self._pgconn:
            raise exceptions.OperationalError('PQconnectdb() failed')
        elif libpq.PQstatus(self._pgconn) == libpq.CONNECTION_BAD:
            raise self._create_exception()

        # Register notice processor
        libpq.PQsetNoticeProcessor(self._pgconn, self._notice_callback, None)

        self.status = consts.STATUS_READY
        self._setup()
Exemplo n.º 4
0
    def _get_guc(self, name):
        """Return the value of a configuration parameter."""
        with self._lock:
            query = 'SHOW %s' % name

            if _green_callback:
                pgres = self._execute_green(query)
            else:
                pgres = libpq.PQexec(self._pgconn, query)

            if not pgres or libpq.PQresultStatus(
                    pgres) != libpq.PGRES_TUPLES_OK:
                raise exceptions.OperationalError("can't fetch %s" % name)
            rv = libpq.PQgetvalue(pgres, 0, 0)
            libpq.PQclear(pgres)
            return rv
Exemplo n.º 5
0
    def _connect_async(self):
        """Create an async connection.

        The connection will be completed banging on poll():
        First with self._conn_poll_connecting() that will finish connection,
        then with self._poll_setup_async() that will do the same job
        of self._setup().

        """
        self._pgconn = libpq.PQconnectStart(self.dsn)
        if not self._pgconn:
            raise exceptions.OperationalError('PQconnectStart() failed')
        elif libpq.PQstatus(self._pgconn) == libpq.CONNECTION_BAD:
            raise self._create_exception()

        libpq.PQsetNoticeProcessor(self._pgconn, self._notice_callback, None)
Exemplo n.º 6
0
    def _setup(self):
        self._equote = self._get_equote()
        self._get_encoding()

        self._cancel = libpq.PQgetCancel(self._pgconn)
        if self._cancel is None:
            raise exceptions.OperationalError("can't get cancellation key")

        with self._lock:
            # If the current datestyle is not compatible (not ISO) then
            # force it to ISO
            datestyle = libpq.PQparameterStatus(self._pgconn, 'DateStyle')
            if not datestyle or not datestyle.startswith('ISO'):
                self.status = consts.STATUS_DATESTYLE
                self._set_guc('datestyle', 'ISO')

            self._closed = False
Exemplo n.º 7
0
    def _create_exception(self, pgres=None, msg=None):
        """Return the exception to be raise'd"""
        if not pgres:
            if not msg:
                msg = libpq.PQerrorMessage(self._pgconn)
            return exceptions.OperationalError(msg)

        if msg is None:
            msg = libpq.PQresultErrorMessage(pgres)

        exc_type = None
        if msg is not None:
            code = libpq.PQresultErrorField(pgres, libpq.PG_DIAG_SQLSTATE)
            if code is not None:
                exc_type = util.get_exception_for_sqlstate(code)
        else:
            msg = libpq.PQerrorMessage(self._pgconn)

        if not exc_type:
            exc_type = exceptions.OperationalError
        return exc_type(msg)
Exemplo n.º 8
0
def pq_set_non_blocking(pgconn, arg, raise_exception=False):
    ret = libpq.PQsetnonblocking(pgconn, arg)
    if ret != 0 and raise_exception:
        raise exceptions.OperationalError('PQsetnonblocking() failed')
    return ret