def _have_cancel_key(self): if self._cancel != ffi.NULL: tmp, self._cancel = self._cancel, ffi.NULL libpq.PQfreeCancel(tmp) self._cancel = libpq.PQgetCancel(self._pgconn) if self._cancel == ffi.NULL: raise exceptions.OperationalError("can't get cancellation key")
def _is_busy(self): with self._lock: if libpq.PQconsumeInput(self._pgconn) == 0: raise exceptions.OperationalError( ffi.string(libpq.PQerrorMessage(self._pgconn))) res = libpq.PQisBusy(self._pgconn) self._process_notifies() return res
def _connect_sync(self): self._pgconn = libpq.PQconnectdb(self.dsn.encode('utf-8')) 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, ffi.NULL) self.status = consts.STATUS_READY self._setup()
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 = ffi.string(libpq.PQgetvalue(pgres, 0, 0)) libpq.PQclear(pgres) return rv
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._have_cancel_key() self._autocommit = True # If the current datestyle is not compatible (not ISO) then # force it to ISO if not self._iso_compatible_datestyle(): self.status = consts.STATUS_DATESTYLE if libpq.PQsendQuery(self._pgconn, b"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
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(ascii_to_bytes(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, ffi.NULL)
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
def cancel(self): err_length = 256 errbuf = ffi.new('char[]', err_length) if libpq.PQcancel(self._cancel, errbuf, err_length) == 0: raise exceptions.OperationalError(ffi.string(errbuf))