int db_postgres_store_result(const db_con_t* _con, db_res_t** _r) { ExecStatusType pqresult; int rc = 0; *_r = db_new_result(); if (*_r==NULL) { LM_ERR("failed to init new result\n"); rc = -1; goto done; } pqresult = PQresultStatus(CON_RESULT(_con)); LM_DBG("%p PQresultStatus(%s) PQgetResult(%p)\n", _con, PQresStatus(pqresult), CON_RESULT(_con)); switch(pqresult) { case PGRES_COMMAND_OK: /* Successful completion of a command returning no data * (such as INSERT or UPDATE). */ rc = 0; break; case PGRES_TUPLES_OK: /* Successful completion of a command returning data * (such as a SELECT or SHOW). */ if (db_postgres_convert_result(_con, *_r) < 0) { LM_ERR("%p Error returned from convert_result()\n", _con); db_free_result(*_r); *_r = 0; rc = -4; break; } rc = 0; break; /* query failed */ case PGRES_FATAL_ERROR: LM_ERR("%p - invalid query, execution aborted\n", _con); LM_ERR("%p: %s\n", _con, PQresStatus(pqresult)); LM_ERR("%p: %s\n", _con, PQresultErrorMessage(CON_RESULT(_con))); db_free_result(*_r); *_r = 0; rc = -3; break; case PGRES_EMPTY_QUERY: /* notice or warning */ case PGRES_NONFATAL_ERROR: /* status for COPY command, not used */ case PGRES_COPY_OUT: case PGRES_COPY_IN: /* unexpected response */ case PGRES_BAD_RESPONSE: default: LM_ERR("%p Probable invalid query\n", _con); LM_ERR("%p: %s\n", _con, PQresStatus(pqresult)); LM_ERR("%p: %s\n", _con, PQresultErrorMessage(CON_RESULT(_con))); db_free_result(*_r); *_r = 0; rc = -4; break; } done: free_query(_con); return (rc); }
/*! * \brief Retrieve result set * \param _con structure representing the database connection * \param _r pointer to a structure represending the result set * \return 0 If the status of the last command produced a result set and, * If the result set contains data or the convert_result() routine * completed successfully. Negative if the status of the last command was * not handled or if the convert_result() returned an error. * \note A new result structure is allocated on every call to this routine. * If this routine returns 0, it is the callers responsbility to free the * result structure. If this routine returns < 0, then the result structure * is freed before returning to the caller. */ int db_postgres_store_result(const db1_con_t* _con, db1_res_t** _r) { PGresult *res = NULL; ExecStatusType pqresult; int rc = 0; *_r = db_new_result(); if (*_r==NULL) { LM_ERR("failed to init new result\n"); rc = -1; goto done; } while (1) { if ((res = PQgetResult(CON_CONNECTION(_con)))) { CON_RESULT(_con) = res; } else { break; } } pqresult = PQresultStatus(CON_RESULT(_con)); LM_DBG("%p PQresultStatus(%s) PQgetResult(%p)\n", _con, PQresStatus(pqresult), CON_RESULT(_con)); CON_AFFECTED(_con) = 0; switch(pqresult) { case PGRES_COMMAND_OK: /* Successful completion of a command returning no data * (such as INSERT or UPDATE). */ rc = 0; CON_AFFECTED(_con) = atoi(PQcmdTuples(CON_RESULT(_con))); break; case PGRES_TUPLES_OK: /* Successful completion of a command returning data * (such as a SELECT or SHOW). */ if (db_postgres_convert_result(_con, *_r) < 0) { LM_ERR("error while converting result\n"); LM_DBG("freeing result set at %p\n", _r); pkg_free(*_r); *_r = 0; rc = -4; break; } rc = 0; CON_AFFECTED(_con) = atoi(PQcmdTuples(CON_RESULT(_con))); break; /* query failed */ case PGRES_FATAL_ERROR: LM_ERR("invalid query, execution aborted\n"); LM_ERR("driver error: %s, %s\n", PQresStatus(pqresult), PQresultErrorMessage(CON_RESULT(_con))); db_free_result(*_r); *_r = 0; rc = -3; break; case PGRES_EMPTY_QUERY: /* notice or warning */ case PGRES_NONFATAL_ERROR: /* status for COPY command, not used */ case PGRES_COPY_OUT: case PGRES_COPY_IN: /* unexpected response */ case PGRES_BAD_RESPONSE: default: LM_ERR("probable invalid query, execution aborted\n"); LM_ERR("driver message: %s, %s\n", PQresStatus(pqresult), PQresultErrorMessage(CON_RESULT(_con))); db_free_result(*_r); *_r = 0; rc = -4; break; } done: db_postgres_free_query(_con); return (rc); }