SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const char* file, const char* func, int line, switch_pgsql_handle_t *handle) { #ifdef SWITCH_HAVE_PGSQL switch_pgsql_result_t *res = NULL; switch_pgsql_status_t final_status = SWITCH_PGSQL_SUCCESS; int done = 0; do { switch_pgsql_next_result(handle, &res); if (res && res->err && !switch_stristr("already exists", res->err) && !switch_stristr("duplicate key name", res->err)) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Error executing query:\n%s\n", res->err); final_status = SWITCH_PGSQL_FAIL; } if (!res) { done = 1; } else if (res->result) { char *affected_rows = PQcmdTuples(res->result); if (!zstr(affected_rows)) { handle->affected_rows = atoi(affected_rows); } } switch_pgsql_free_result(&res); } while (!done); return final_status; #else return SWITCH_PGSQL_FAIL; #endif }
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string_detailed(const char *file, const char *func, int line, switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err) { #ifdef SWITCH_HAVE_PGSQL switch_pgsql_status_t sstatus = SWITCH_PGSQL_SUCCESS; char *val = NULL; switch_pgsql_result_t *result = NULL; handle->affected_rows = 0; if (switch_pgsql_handle_exec_base_detailed(file, func, line, handle, sql, err) == SWITCH_PGSQL_FAIL) { goto error; } if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) { goto error; } if (result) { switch (result->status) { #if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 2 case PGRES_SINGLE_TUPLE: /* Added in PostgreSQL 9.2 */ #endif case PGRES_COMMAND_OK: case PGRES_TUPLES_OK: break; default: sstatus = SWITCH_PGSQL_FAIL; goto done; } } if (handle->affected_rows <= 0) { goto done; } val = PQgetvalue(result->result, 0, 0); strncpy(resbuf, val, len); done: switch_pgsql_free_result(&result); if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) { sstatus = SWITCH_PGSQL_FAIL; } return sstatus; error: return SWITCH_PGSQL_FAIL; #else return SWITCH_PGSQL_FAIL; #endif }
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_exec_string(switch_pgsql_handle_t *handle, const char *sql, char *resbuf, size_t len, char **err) { #ifdef SWITCH_HAVE_PGSQL switch_pgsql_status_t sstatus = SWITCH_PGSQL_SUCCESS; char *val = NULL; switch_pgsql_result_t *result = NULL; handle->affected_rows = 0; if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) { goto error; } if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) { goto error; } if (!result || result->status != PGRES_COMMAND_OK) { sstatus = SWITCH_PGSQL_FAIL; goto done; } if (handle->affected_rows <= 0) { goto done; } val = PQgetvalue(result->result, 0, 0); strncpy(resbuf, val, len); done: switch_pgsql_free_result(&result); if (switch_pgsql_finish_results(handle) != SWITCH_PGSQL_SUCCESS) { sstatus = SWITCH_PGSQL_FAIL; } return sstatus; error: return SWITCH_PGSQL_FAIL; #else return SWITCH_PGSQL_FAIL; #endif }
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_finish_results_real(const char* file, const char* func, int line, switch_pgsql_handle_t *handle) { #ifdef SWITCH_HAVE_PGSQL switch_pgsql_result_t *res = NULL; switch_pgsql_status_t final_status = SWITCH_PGSQL_SUCCESS; int done = 0; do { switch_pgsql_next_result(handle, &res); if (res && res->err) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Error executing query:\n%s\n", res->err); final_status = SWITCH_PGSQL_FAIL; } if (!res) done = 1; switch_pgsql_free_result(&res); } while (!done); return final_status; #else return SWITCH_PGSQL_FAIL; #endif }
SWITCH_DECLARE(switch_pgsql_status_t) switch_pgsql_handle_callback_exec_detailed(const char *file, const char *func, int line, switch_pgsql_handle_t *handle, const char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err) { #ifdef SWITCH_HAVE_PGSQL char *err_str = NULL; int row = 0, col = 0, err_cnt = 0; switch_pgsql_result_t *result = NULL; handle->affected_rows = 0; switch_assert(callback != NULL); if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) { goto error; } if (switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) { err_cnt++; err_str = switch_pgsql_handle_get_error(handle); if (result && !zstr(result->err)) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(result->err)); } if (!zstr(err_str)) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str)); } switch_safe_free(err_str); err_str = NULL; } while (result != NULL) { /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Processing result with %d rows and %d columns.\n", result->rows, result->cols);*/ for (row = 0; row < result->rows; ++row) { char **names; char **vals; names = calloc(result->cols, sizeof(*names)); vals = calloc(result->cols, sizeof(*vals)); switch_assert(names && vals); for (col = 0; col < result->cols; ++col) { char * tmp; int len; tmp = PQfname(result->result, col); if (tmp) { len = strlen(tmp); names[col] = malloc(len+1); names[col][len] = '\0'; strncpy(names[col], tmp, len); len = PQgetlength(result->result, row, col); vals[col] = malloc(len+1); vals[col][len] = '\0'; tmp = PQgetvalue(result->result, row, col); strncpy(vals[col], tmp, len); /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Processing result row %d, col %d: %s => %s\n", row, col, names[col], vals[col]);*/ } else { /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Processing result row %d, col %d.\n", row, col);*/ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: Column number %d out of range\n", col); } } /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Executing callback for row %d...\n", row);*/ if (callback(pdata, result->cols, vals, names)) { switch_pgsql_finish_results(handle); /* Makes sure next call to switch_pgsql_next_result will return NULL */ row = result->rows; /* Makes us exit the for loop */ } for (col = 0; col < result->cols; ++col) { free(names[col]); free(vals[col]); } free(names); free(vals); } switch_pgsql_free_result(&result); if (switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) { err_cnt++; err_str = switch_pgsql_handle_get_error(handle); if (result && !zstr(result->err)) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(result->err)); } if (!zstr(err_str)) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str)); } switch_safe_free(err_str); err_str = NULL; } } if (err_cnt) { goto error; } return SWITCH_PGSQL_SUCCESS; error: #endif return SWITCH_PGSQL_FAIL; }