int evpg_connect(struct evpg_cfg *config, const char *connstr) { int pgsock; int status; struct evpg_db_node *dbnode; void **usrdata; if (!(dbnode = calloc(sizeof(struct evpg_db_node), 1))) return -1; dbnode->dbconn = PQconnectStart(connstr); pgsock = PQsocket(dbnode->dbconn); /* set this dbnode into an active state since it is not ready to be used by the calling application */ evpg_set_active(config, dbnode); /* we want to pass both our config, and our node */ usrdata = malloc(sizeof(void *) * 2); usrdata[0] = config; usrdata[1] = dbnode; /* start the non-blocking connect event */ event_set(&dbnode->event, pgsock, EV_WRITE, (void *)evpg_connect_check, usrdata); event_add(&dbnode->event, 0); }
bool DoConnect() { sql = PQconnectStart(GetDSN().c_str()); if (!sql) return false; if(PQstatus(sql) == CONNECTION_BAD) return false; if(PQsetnonblocking(sql, 1) == -1) return false; /* OK, we've initalised the connection, now to get it hooked into the socket engine * and then start polling it. */ this->fd = PQsocket(sql); if(this->fd <= -1) return false; if (!ServerInstance->SE->AddFd(this, FD_WANT_NO_WRITE | FD_WANT_NO_READ)) { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "BUG: Couldn't add pgsql socket to socket engine"); return false; } /* Socket all hooked into the engine, now to tell PgSQL to start connecting */ return DoPoll(); }
static int _conn_async_connect(connectionObject *self) { PGconn *pgconn; self->pgconn = pgconn = PQconnectStart(self->dsn); Dprintf("conn_connect: new postgresql connection at %p", pgconn); if (pgconn == NULL) { Dprintf("conn_connect: PQconnectStart(%s) FAILED", self->dsn); PyErr_SetString(OperationalError, "PQconnectStart() failed"); return -1; } else if (PQstatus(pgconn) == CONNECTION_BAD) { Dprintf("conn_connect: PQconnectdb(%s) returned BAD", self->dsn); PyErr_SetString(OperationalError, PQerrorMessage(pgconn)); return -1; } PQsetNoticeProcessor(pgconn, conn_notice_callback, (void*)self); /* The connection will be completed banging on poll(): * First with _conn_poll_connecting() that will finish connection, * then with _conn_poll_setup_async() that will do the same job * of setup_async(). */ return 0; }
CAMLprim value PQconnectdb_stub(value v_conn_info, value v_startonly) { PGconn *conn; value v_conn; PGcancel *cancel; if (Bool_val(v_startonly)) { conn = PQconnectStart(String_val(v_conn_info)); cancel = PQgetCancel(conn); } else { size_t len = caml_string_length(v_conn_info) + 1; char *conn_info = caml_stat_alloc(len); memcpy(conn_info, String_val(v_conn_info), len); caml_enter_blocking_section(); conn = PQconnectdb(conn_info); cancel = PQgetCancel(conn); free(conn_info); caml_leave_blocking_section(); } /* One may raise this 30 to 500 for instance if the program takes responsibility of closing connections */ v_conn = caml_alloc_small(3, Abstract_tag); set_conn(v_conn, conn); set_conn_cb(v_conn, NULL); set_cancel_obj(v_conn, cancel); return v_conn; }
static int _conn_sync_connect(connectionObject *self) { PGconn *pgconn; int green; /* store this value to prevent inconsistencies due to a change * in the middle of the function. */ green = psyco_green(); if (!green) { Py_BEGIN_ALLOW_THREADS; self->pgconn = pgconn = PQconnectdb(self->dsn); Py_END_ALLOW_THREADS; Dprintf("conn_connect: new postgresql connection at %p", pgconn); } else { Py_BEGIN_ALLOW_THREADS; self->pgconn = pgconn = PQconnectStart(self->dsn); Py_END_ALLOW_THREADS; Dprintf("conn_connect: new green postgresql connection at %p", pgconn); } if (pgconn == NULL) { Dprintf("conn_connect: PQconnectdb(%s) FAILED", self->dsn); PyErr_SetString(OperationalError, "PQconnectdb() failed"); return -1; } else if (PQstatus(pgconn) == CONNECTION_BAD) { Dprintf("conn_connect: PQconnectdb(%s) returned BAD", self->dsn); PyErr_SetString(OperationalError, PQerrorMessage(pgconn)); return -1; } PQsetNoticeProcessor(pgconn, conn_notice_callback, (void*)self); /* if the connection is green, wait to finish connection */ if (green) { if (0 > pq_set_non_blocking(self, 1)) { return -1; } if (0 != psyco_wait(self)) { return -1; } } /* From here the connection is considered ready: with the new status, * poll() will use PQisBusy instead of PQconnectPoll. */ self->status = CONN_STATUS_READY; if (conn_setup(self, self->pgconn) == -1) { return -1; } return 0; }
/* * MultiClientConnectStart asynchronously tries to establish a connection. If it * succeeds, it returns the connection id. Otherwise, it reports connection * error and returns INVALID_CONNECTION_ID. */ int32 MultiClientConnectStart(const char *nodeName, uint32 nodePort, const char *nodeDatabase) { PGconn *connection = NULL; char connInfoString[STRING_BUFFER_SIZE]; ConnStatusType connStatusType = CONNECTION_BAD; char *userName = CurrentUserName(); int32 connectionId = AllocateConnectionId(); if (connectionId == INVALID_CONNECTION_ID) { ereport(WARNING, (errmsg("could not allocate connection in connection pool"))); return connectionId; } if (XactModificationLevel > XACT_MODIFICATION_NONE) { ereport(ERROR, (errcode(ERRCODE_ACTIVE_SQL_TRANSACTION), errmsg("cannot open new connections after the first modification " "command within a transaction"))); } /* transcribe connection paremeters to string */ snprintf(connInfoString, STRING_BUFFER_SIZE, CONN_INFO_TEMPLATE, nodeName, nodePort, nodeDatabase, userName, CLIENT_CONNECT_TIMEOUT); /* prepare asynchronous request for worker node connection */ connection = PQconnectStart(connInfoString); connStatusType = PQstatus(connection); /* * If prepared, we save the connection, and set its initial polling status * to PGRES_POLLING_WRITING as specified in "Database Connection Control * Functions" section of the PostgreSQL documentation. */ if (connStatusType != CONNECTION_BAD) { ClientConnectionArray[connectionId] = connection; ClientPollingStatusArray[connectionId] = PGRES_POLLING_WRITING; } else { WarnRemoteError(connection, NULL); PQfinish(connection); connectionId = INVALID_CONNECTION_ID; } return connectionId; }
static int esql_postgresql_connect(Esql *e) { e->backend.db = PQconnectStart(e->backend.conn_str); free(e->backend.conn_str); e->backend.conn_str = NULL; e->backend.conn_str_len = 0; EINA_SAFETY_ON_NULL_RETURN_VAL(e->backend.db, ECORE_FD_ERROR); if (PQstatus(e->backend.db) == CONNECTION_BAD) { ERR("%s", esql_postgresql_error_get(e)); return ECORE_FD_ERROR; } return ECORE_FD_READ | ECORE_FD_WRITE; }
ngx_int_t ngx_postgres_upstream_get_peer(ngx_peer_connection_t *pc, void *data) { ngx_postgres_upstream_peer_data_t *pgdt = data; ngx_postgres_upstream_srv_conf_t *pgscf; #if defined(nginx_version) && (nginx_version < 8017) ngx_postgres_ctx_t *pgctx; #endif ngx_postgres_upstream_peers_t *peers; ngx_postgres_upstream_peer_t *peer; ngx_connection_t *pgxc = NULL; int fd; ngx_event_t *rev, *wev; ngx_int_t rc; u_char *connstring, *last; size_t len; dd("entering"); #if defined(nginx_version) && (nginx_version < 8017) if (data == NULL) { goto failed; } pgctx = ngx_http_get_module_ctx(pgdt->request, ngx_postgres_module); #endif pgscf = pgdt->srv_conf; pgdt->failed = 0; if (pgscf->max_cached && pgscf->single) { rc = ngx_postgres_keepalive_get_peer_single(pc, pgdt, pgscf); if (rc != NGX_DECLINED) { /* re-use keepalive peer */ dd("re-using keepalive peer (single)"); pgdt->state = state_db_send_query; ngx_postgres_process_events(pgdt->request); dd("returning NGX_AGAIN"); return NGX_AGAIN; } } peers = pgscf->peers; if (pgscf->current > peers->number - 1) { pgscf->current = 0; } peer = &peers->peer[pgscf->current++]; pgdt->name.len = peer->name.len; pgdt->name.data = peer->name.data; pgdt->sockaddr = *peer->sockaddr; pc->name = &pgdt->name; pc->sockaddr = &pgdt->sockaddr; pc->socklen = peer->socklen; pc->cached = 0; if ((pgscf->max_cached) && (!pgscf->single)) { rc = ngx_postgres_keepalive_get_peer_multi(pc, pgdt, pgscf); if (rc != NGX_DECLINED) { /* re-use keepalive peer */ dd("re-using keepalive peer (multi)"); pgdt->state = state_db_send_query; ngx_postgres_process_events(pgdt->request); dd("returning NGX_AGAIN"); return NGX_AGAIN; } } if ((pgscf->reject) && (pgscf->active_conns >= pgscf->max_cached)) { ngx_log_error(NGX_LOG_INFO, pc->log, 0, "postgres: keepalive connection pool is full," " rejecting request to upstream \"%V\"", &peer->name); /* a bit hack-ish way to return error response (setup part) */ pc->connection = ngx_get_connection(0, pc->log); #if defined(nginx_version) && (nginx_version < 8017) pgctx->status = NGX_HTTP_SERVICE_UNAVAILABLE; #endif dd("returning NGX_AGAIN (NGX_HTTP_SERVICE_UNAVAILABLE)"); return NGX_AGAIN; } /* sizeof("...") - 1 + 1 (for spaces and '\0' omitted */ len = sizeof("hostaddr=") + peer->host.len + sizeof("port=") + sizeof("65535") - 1 + sizeof("dbname=") + peer->dbname.len + sizeof("user="******"password="******"sslmode=disable"); connstring = ngx_pnalloc(pgdt->request->pool, len); if (connstring == NULL) { #if defined(nginx_version) && (nginx_version >= 8017) dd("returning NGX_ERROR"); return NGX_ERROR; #else goto failed; #endif } /* TODO add unix sockets */ last = ngx_snprintf(connstring, len - 1, "hostaddr=%V port=%d dbname=%V user=%V password=%V" " sslmode=disable", &peer->host, peer->port, &peer->dbname, &peer->user, &peer->password); *last = '\0'; dd("PostgreSQL connection string: %s", connstring); /* * internal checks in PQsetnonblocking are taking care of any * PQconnectStart failures, so we don't need to check them here. */ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pc->log, 0, "postgres: connecting"); pgdt->pgconn = PQconnectStart((const char *)connstring); if (PQsetnonblocking(pgdt->pgconn, 1) == -1) { ngx_log_error(NGX_LOG_ERR, pc->log, 0, "postgres: connection failed: %s in upstream \"%V\"", PQerrorMessage(pgdt->pgconn), &peer->name); PQfinish(pgdt->pgconn); pgdt->pgconn = NULL; #if defined(nginx_version) && (nginx_version >= 8017) dd("returning NGX_DECLINED"); return NGX_DECLINED; #else pgctx->status = NGX_HTTP_BAD_GATEWAY; goto failed; #endif } #if defined(DDEBUG) && (DDEBUG > 1) PQtrace(pgdt->pgconn, stderr); #endif dd("connection status:%d", (int) PQstatus(pgdt->pgconn)); /* take spot in keepalive connection pool */ pgscf->active_conns++; /* add the file descriptor (fd) into an nginx connection structure */ fd = PQsocket(pgdt->pgconn); if (fd == -1) { ngx_log_error(NGX_LOG_ERR, pc->log, 0, "postgres: failed to get connection fd"); goto invalid; } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "postgres: connection fd:%d", fd); pgxc = pc->connection = ngx_get_connection(fd, pc->log); if (pgxc == NULL) { ngx_log_error(NGX_LOG_ERR, pc->log, 0, "postgres: failed to get a free nginx connection"); goto invalid; } pgxc->log = pc->log; pgxc->log_error = pc->log_error; pgxc->number = ngx_atomic_fetch_add(ngx_connection_counter, 1); rev = pgxc->read; wev = pgxc->write; rev->log = pc->log; wev->log = pc->log; /* register the connection with postgres connection fd into the * nginx event model */ if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { dd("NGX_USE_RTSIG_EVENT"); if (ngx_add_conn(pgxc) != NGX_OK) { goto bad_add; } } else if (ngx_event_flags & NGX_USE_CLEAR_EVENT) { dd("NGX_USE_CLEAR_EVENT"); if (ngx_add_event(rev, NGX_READ_EVENT, NGX_CLEAR_EVENT) != NGX_OK) { goto bad_add; } if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_CLEAR_EVENT) != NGX_OK) { goto bad_add; } } else { dd("NGX_USE_LEVEL_EVENT"); if (ngx_add_event(rev, NGX_READ_EVENT, NGX_LEVEL_EVENT) != NGX_OK) { goto bad_add; } if (ngx_add_event(wev, NGX_WRITE_EVENT, NGX_LEVEL_EVENT) != NGX_OK) { goto bad_add; } } pgxc->log->action = "connecting to PostgreSQL database"; pgdt->state = state_db_connect; dd("returning NGX_AGAIN"); return NGX_AGAIN; bad_add: ngx_log_error(NGX_LOG_ERR, pc->log, 0, "postgres: failed to add nginx connection"); invalid: ngx_postgres_upstream_free_connection(pc->log, pc->connection, pgdt->pgconn, pgscf); #if defined(nginx_version) && (nginx_version >= 8017) dd("returning NGX_ERROR"); return NGX_ERROR; #else failed: /* a bit hack-ish way to return error response (setup part) */ pc->connection = ngx_get_connection(0, pc->log); dd("returning NGX_AGAIN (NGX_ERROR)"); return NGX_AGAIN; #endif }