Exemple #1
0
/*************************************************************************
 *
 *	Function: sql_query
 *
 *	Purpose: Issue a query to the database
 *
 *************************************************************************/
static int sql_query(SQLSOCK * sqlsocket, SQL_CONFIG *config, char *querystr) {

	rlm_sql_postgres_sock *pg_sock = sqlsocket->conn;

	if (config->sqltrace)
		radlog(L_DBG,"rlm_sql_postgresql: query:\n%s", querystr);

	if (pg_sock->conn == NULL) {
		radlog(L_ERR, "rlm_sql_postgresql: Socket not connected");
		return SQL_DOWN;
	}

	pg_sock->result = PQexec(pg_sock->conn, querystr);
		/* Returns a result pointer or possibly a NULL pointer.
		 * A non-NULL pointer will generally be returned except in
		 * out-of-memory conditions or serious errors such as inability
		 * to send the command to the backend. If a NULL is returned,
		 *  it should be treated like a PGRES_FATAL_ERROR result.
		 * Use PQerrorMessage to get more information about the error.
		 */
	if (!pg_sock->result)
	{
		radlog(L_ERR, "rlm_sql_postgresql: PostgreSQL Query failed Error: %s",
				PQerrorMessage(pg_sock->conn));
		return  SQL_DOWN;
	} else {
		ExecStatusType status = PQresultStatus(pg_sock->result);

		radlog(L_DBG, "rlm_sql_postgresql: Status: %s", PQresStatus(status));

		radlog(L_DBG, "rlm_sql_postgresql: affected rows = %s",
				PQcmdTuples(pg_sock->result));

		if (!status_is_ok(status))
			return sql_check_error(status);

		if (strncasecmp("select", querystr, 6) != 0) {
			/* store the number of affected rows because the sql module
			 * calls finish_query before it retrieves the number of affected
			 * rows from the driver */
			pg_sock->affected_rows = affected_rows(pg_sock->result);
			return 0;
		} else {
			if ((sql_store_result(sqlsocket, config) == 0)
					&& (sql_num_fields(sqlsocket, config) >= 0))
				return 0;
			else
				return -1;
		}
	}
}
// 执行删除操作
void ConnectorMySQL::exec_delete(const std::string &command, ErrorCode &error_code, std::vector<char> &result)
{
    affected_rows(command, error_code, result);
}
/*************************************************************************
 *
 *	Function: sql_query
 *
 *	Purpose: Issue a query to the database
 *
 *************************************************************************/
static sql_rcode_t sql_query(rlm_sql_handle_t * handle, UNUSED rlm_sql_config_t *config, char const *query)
{
	rlm_sql_postgres_conn_t *conn = handle->conn;
	int numfields = 0;
	char *errorcode;
	char *errormsg;

	if (!conn->db) {
		ERROR("rlm_sql_postgresql: Socket not connected");
		return RLM_SQL_RECONNECT;
	}

	conn->result = PQexec(conn->db, query);
		/*
		 * Returns a PGresult pointer or possibly a null pointer.
		 * A non-null pointer will generally be returned except in
		 * out-of-memory conditions or serious errors such as inability
		 * to send the command to the server. If a null pointer is
		 * returned, it should be treated like a PGRES_FATAL_ERROR
		 * result.
		 */
	if (!conn->result)
	{
		ERROR("rlm_sql_postgresql: PostgreSQL Query failed Error: %s",
				PQerrorMessage(conn->db));
		/* As this error COULD be a connection error OR an out-of-memory
		 * condition return value WILL be wrong SOME of the time regardless!
		 * Pick your poison....
		 */
		return  RLM_SQL_RECONNECT;
	} else {
		ExecStatusType status = PQresultStatus(conn->result);
		DEBUG("rlm_sql_postgresql: Status: %s", PQresStatus(status));

		switch (status){

			case PGRES_COMMAND_OK:
				/*Successful completion of a command returning no data.*/

				/*affected_rows function only returns
				the number of affected rows of a command
				returning no data...
				*/
				conn->affected_rows	= affected_rows(conn->result);
				DEBUG("rlm_sql_postgresql: query affected rows = %i", conn->affected_rows);
				return 0;

			break;

			case PGRES_TUPLES_OK:
				/*Successful completion of a command returning data (such as a SELECT or SHOW).*/

				conn->cur_row = 0;
 				conn->affected_rows = PQntuples(conn->result);
				numfields = PQnfields(conn->result); /*Check row storing functions..*/
				DEBUG("rlm_sql_postgresql: query affected rows = %i , fields = %i", conn->affected_rows, numfields);
				return 0;

			break;

			case PGRES_BAD_RESPONSE:
				/*The server's response was not understood.*/
				DEBUG("rlm_sql_postgresql: Bad Response From Server!!");
				return -1;

			break;

			case PGRES_NONFATAL_ERROR:
				/*A nonfatal error (a notice or warning) occurred. Possibly never returns*/

				return -1;

			break;

			case PGRES_FATAL_ERROR:
#if defined(PG_DIAG_SQLSTATE) && defined(PG_DIAG_MESSAGE_PRIMARY)
				/*A fatal error occurred.*/

				errorcode = PQresultErrorField(conn->result, PG_DIAG_SQLSTATE);
				errormsg  = PQresultErrorField(conn->result, PG_DIAG_MESSAGE_PRIMARY);
				DEBUG("rlm_sql_postgresql: Error %s", errormsg);
				return check_fatal_error(errorcode);
#endif

			break;

			default:
				/* FIXME: An unhandled error occurred.*/

				/* PGRES_EMPTY_QUERY PGRES_COPY_OUT PGRES_COPY_IN */

				return -1;

			break;


		}

		/*
			Note to self ... sql_store_result returns 0 anyway
			after setting the handle->affected_rows..
			sql_num_fields returns 0 at worst case which means the check below
			has a really small chance to return false..
			lets remove it then .. yuck!!
		*/
		/*
		} else {
			if ((sql_store_result(handle, config) == 0)
					&& (sql_num_fields(handle, config) >= 0))
				return 0;
			else
				return -1;
		}
		*/
	}
	return -1;
}