Exemple #1
0
	void DoEvent()
	{
		if((status == CREAD) || (status == CWRITE))
		{
			DoPoll();
		}
		else if((status == RREAD) || (status == RWRITE))
		{
			DoResetPoll();
		}
		else
		{
			DoConnectedPoll();
		}
	}
Exemple #2
0
	bool DoEvent()
	{
		bool ret;

		if((status == CREAD) || (status == CWRITE))
		{
			ret = DoPoll();
		}
		else if((status == RREAD) || (status == RWRITE))
		{
			ret = DoResetPoll();
		}
		else
		{
			ret = DoConnectedPoll();
		}
		return ret;
	}
Exemple #3
0
	bool DoResetPoll()
	{
		switch(PQresetPoll(sql))
		{
			case PGRES_POLLING_WRITING:
				ServerInstance->SE->WantWrite(this);
				status = CWRITE;
				return DoPoll();
			case PGRES_POLLING_READING:
				status = CREAD;
				return true;
			case PGRES_POLLING_FAILED:
				return false;
			case PGRES_POLLING_OK:
				status = WWRITE;
				return DoConnectedPoll();
			default:
				return true;
		}
	}
Exemple #4
0
	bool DoResetPoll()
	{
		switch(PQresetPoll(sql))
		{
			case PGRES_POLLING_WRITING:
				ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ);
				status = CWRITE;
				return DoPoll();
			case PGRES_POLLING_READING:
				ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
				status = CREAD;
				return true;
			case PGRES_POLLING_FAILED:
				return false;
			case PGRES_POLLING_OK:
				ServerInstance->SE->ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
				status = WWRITE;
				DoConnectedPoll();
			default:
				return true;
		}
	}
Exemple #5
0
	bool DoPoll()
	{
		switch(PQconnectPoll(sql))
		{
			case PGRES_POLLING_WRITING:
				SocketEngine::ChangeEventMask(this, FD_WANT_POLL_WRITE | FD_WANT_NO_READ);
				status = CWRITE;
				return true;
			case PGRES_POLLING_READING:
				SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
				status = CREAD;
				return true;
			case PGRES_POLLING_FAILED:
				return false;
			case PGRES_POLLING_OK:
				SocketEngine::ChangeEventMask(this, FD_WANT_POLL_READ | FD_WANT_NO_WRITE);
				status = WWRITE;
				DoConnectedPoll();
			default:
				return true;
		}
	}
Exemple #6
0
	bool DoConnectedPoll()
	{
		if(!qinprog && queue.totalsize())
		{
			/* There's no query currently in progress, and there's queries in the queue. */
			SQLrequest& query = queue.front();
			DoQuery(query);
		}

		if(PQconsumeInput(sql))
		{
			/* We just read stuff from the server, that counts as it being alive
			 * so update the idle-since time :p
			 */
			idle = this->ServerInstance->Time();

			if (PQisBusy(sql))
			{
				/* Nothing happens here */
			}
			else if (qinprog)
			{
				/* Grab the request we're processing */
				SQLrequest& query = queue.front();

				/* Get a pointer to the module we're about to return the result to */
				Module* to = query.GetSource();

				/* Fetch the result.. */
				PGresult* result = PQgetResult(sql);

				/* PgSQL would allow a query string to be sent which has multiple
				 * queries in it, this isn't portable across database backends and
				 * we don't want modules doing it. But just in case we make sure we
				 * drain any results there are and just use the last one.
				 * If the module devs are behaving there will only be one result.
				 */
				while (PGresult* temp = PQgetResult(sql))
				{
					PQclear(result);
					result = temp;
				}

				if(to)
				{
					/* ..and the result */
					PgSQLresult reply(us, to, query.id, result);

					/* Fix by brain, make sure the original query gets sent back in the reply */
					reply.query = query.query.q;

					switch(PQresultStatus(result))
					{
						case PGRES_EMPTY_QUERY:
						case PGRES_BAD_RESPONSE:
						case PGRES_FATAL_ERROR:
							reply.error.Id(SQL_QREPLY_FAIL);
							reply.error.Str(PQresultErrorMessage(result));
						default:
							;
							/* No action, other values are not errors */
					}

					reply.Send();

					/* PgSQLresult's destructor will free the PGresult */
				}
				else
				{
					/* If the client module is unloaded partway through a query then the provider will set
					 * the pointer to NULL. We cannot just cancel the query as the result will still come
					 * through at some point...and it could get messy if we play with invalid pointers...
					 */
					PQclear(result);
				}
				qinprog = false;
				queue.pop();
				DoConnectedPoll();
			}
			return true;
		}
		else
		{
			/* I think we'll assume this means the server died...it might not,
			 * but I think that any error serious enough we actually get here
			 * deserves to reconnect [/excuse]
			 * Returning true so the core doesn't try and close the connection.
			 */
			DelayReconnect();
			return true;
		}
	}