FreeSWITCH API Documentation  1.7.0
Functions
switch_pgsql.c File Reference
#include <switch.h>
#include <switch_private.h>
+ Include dependency graph for switch_pgsql.c:

Go to the source code of this file.

Functions

switch_pgsql_handle_tswitch_pgsql_handle_new (const char *dsn)
 Create a new handle for the PGSQL connection. More...
 
void switch_pgsql_set_num_retries (switch_pgsql_handle_t *handle, int num_retries)
 Sets the number of retries if the PGSQL connection fails. More...
 
switch_pgsql_status_t switch_pgsql_handle_disconnect (switch_pgsql_handle_t *handle)
 Disconnects a PGSQL connection from the database. More...
 
switch_pgsql_status_t switch_pgsql_send_query (switch_pgsql_handle_t *handle, const char *sql)
 
switch_pgsql_status_t switch_pgsql_cancel_real (const char *file, const char *func, int line, switch_pgsql_handle_t *handle)
 
switch_pgsql_status_t switch_pgsql_next_result_timed (switch_pgsql_handle_t *handle, switch_pgsql_result_t **result_out, int msec)
 
void switch_pgsql_free_result (switch_pgsql_result_t **result)
 
switch_pgsql_status_t switch_pgsql_finish_results_real (const char *file, const char *func, int line, switch_pgsql_handle_t *handle)
 
switch_pgsql_status_t switch_pgsql_handle_connect (switch_pgsql_handle_t *handle)
 Connect to the database specified by the DSN passed to the switch_pgsql_handle_new() call which initialized this handle. More...
 
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)
 
switch_pgsql_status_t switch_pgsql_handle_exec_base_detailed (const char *file, const char *func, int line, switch_pgsql_handle_t *handle, const char *sql, char **err)
 
switch_pgsql_status_t switch_pgsql_handle_exec_detailed (const char *file, const char *func, int line, switch_pgsql_handle_t *handle, const char *sql, char **err)
 
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)
 Execute the sql query and issue a callback for each row returned. More...
 
void switch_pgsql_handle_destroy (switch_pgsql_handle_t **handlep)
 
switch_pgsql_state_t switch_pgsql_handle_get_state (switch_pgsql_handle_t *handle)
 
char * switch_pgsql_handle_get_error (switch_pgsql_handle_t *handle)
 
int switch_pgsql_handle_affected_rows (switch_pgsql_handle_t *handle)
 
switch_bool_t switch_pgsql_available (void)
 
switch_pgsql_status_t switch_pgsql_SQLSetAutoCommitAttr (switch_pgsql_handle_t *handle, switch_bool_t on)
 
switch_pgsql_status_t switch_pgsql_flush (switch_pgsql_handle_t *handle)
 
switch_pgsql_status_t switch_pgsql_SQLEndTran (switch_pgsql_handle_t *handle, switch_bool_t commit)
 

Function Documentation

switch_bool_t switch_pgsql_available ( void  )

Definition at line 819 of file switch_pgsql.c.

References SWITCH_FALSE, and SWITCH_TRUE.

Referenced by _switch_cache_db_get_db_handle(), and switch_load_core_config().

820 {
821 #ifdef SWITCH_HAVE_PGSQL
822  return SWITCH_TRUE;
823 #else
824  return SWITCH_FALSE;
825 #endif
826 }
switch_pgsql_status_t switch_pgsql_cancel_real ( const char *  file,
const char *  func,
int  line,
switch_pgsql_handle_t handle 
)

Definition at line 266 of file switch_pgsql.c.

References memset(), SWITCH_CHANNEL_ID_LOG, SWITCH_LOG_CRIT, switch_log_printf(), SWITCH_PGSQL_FAIL, switch_pgsql_flush(), and SWITCH_PGSQL_SUCCESS.

267 {
269 #ifdef SWITCH_HAVE_PGSQL
270  char err_buf[256];
271  PGcancel *cancel = NULL;
272 
273  memset(err_buf, 0, 256);
274  cancel = PQgetCancel(handle->con);
275  if(!PQcancel(cancel, err_buf, 256)) {
276  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_CRIT, "Failed to cancel long-running query (%s): %s\n", handle->sql, err_buf);
277  ret = SWITCH_PGSQL_FAIL;
278  }
279  PQfreeCancel(cancel);
280  switch_pgsql_flush(handle);
281 
282 #endif
283  return ret;
284 }
switch_pgsql_status_t
Definition: switch_pgsql.h:53
switch_pgsql_status_t switch_pgsql_flush(switch_pgsql_handle_t *handle)
Definition: switch_pgsql.c:842
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
memset(buf, 0, buflen)
switch_pgsql_status_t switch_pgsql_finish_results_real ( const char *  file,
const char *  func,
int  line,
switch_pgsql_handle_t handle 
)

Definition at line 457 of file switch_pgsql.c.

References SWITCH_CHANNEL_ID_LOG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_PGSQL_FAIL, switch_pgsql_free_result(), switch_pgsql_next_result, SWITCH_PGSQL_SUCCESS, switch_stristr(), and zstr.

458 {
459 #ifdef SWITCH_HAVE_PGSQL
460  switch_pgsql_result_t *res = NULL;
462  int done = 0;
463  do {
464  switch_pgsql_next_result(handle, &res);
465  if (res && res->err && !switch_stristr("already exists", res->err) && !switch_stristr("duplicate key name", res->err)) {
466  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Error executing query:\n%s\n", res->err);
467  final_status = SWITCH_PGSQL_FAIL;
468  }
469 
470  if (!res) {
471  done = 1;
472  } else if (res->result) {
473  char *affected_rows = PQcmdTuples(res->result);
474 
475  if (!zstr(affected_rows)) {
476  handle->affected_rows = atoi(affected_rows);
477  }
478  }
479 
481  } while (!done);
482  return final_status;
483 #else
484  return SWITCH_PGSQL_FAIL;
485 #endif
486 }
switch_pgsql_status_t
Definition: switch_pgsql.h:53
void switch_pgsql_free_result(switch_pgsql_result_t **result)
Definition: switch_pgsql.c:439
#define zstr(x)
Definition: switch_utils.h:281
struct switch_pgsql_result switch_pgsql_result_t
#define switch_pgsql_next_result(h, r)
Definition: switch_pgsql.h:102
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char * switch_stristr(const char *instr, const char *str)
switch_pgsql_status_t switch_pgsql_flush ( switch_pgsql_handle_t handle)

Definition at line 842 of file switch_pgsql.c.

References SWITCH_CHANNEL_LOG, SWITCH_FALSE, SWITCH_LOG_DEBUG10, switch_log_printf(), and SWITCH_PGSQL_SUCCESS.

Referenced by switch_cache_db_release_db_handle(), switch_pgsql_cancel_real(), switch_pgsql_handle_exec_base_detailed(), and switch_pgsql_next_result_timed().

843 {
844 #ifdef SWITCH_HAVE_PGSQL
845 
846  PGresult *tmp = NULL;
847  int x = 0;
848 
849  /* Make sure the query is fully cleared */
850  while ((tmp = PQgetResult(handle->con)) != NULL) {
851  PQclear(tmp);
852  x++;
853  }
854 
855  if (x) {
856  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Flushing %d results\n", x);
857  }
858 
859  return SWITCH_PGSQL_SUCCESS;
860 #else
862 #endif
863 }
switch_pgsql_status_t
Definition: switch_pgsql.h:53
#define SWITCH_CHANNEL_LOG
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_pgsql_free_result ( switch_pgsql_result_t **  result)

Definition at line 439 of file switch_pgsql.c.

Referenced by switch_pgsql_finish_results_real(), switch_pgsql_handle_callback_exec_detailed(), and switch_pgsql_handle_exec_string_detailed().

440 {
441 #ifdef SWITCH_HAVE_PGSQL
442 
443  if (!*result) {
444  return;
445  }
446 
447  if ((*result)->result) {
448  PQclear((*result)->result);
449  }
450  free(*result);
451  *result = NULL;
452 #else
453  return;
454 #endif
455 }
int switch_pgsql_handle_affected_rows ( switch_pgsql_handle_t handle)

Definition at line 810 of file switch_pgsql.c.

Referenced by switch_cache_db_affected_rows().

811 {
812 #ifdef SWITCH_HAVE_PGSQL
813  return handle->affected_rows;
814 #else
815  return 0;
816 #endif
817 }
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 
)

Execute the sql query and issue a callback for each row returned.

Parameters
filethe file from which this function is called
functhe function from which this function is called
linethe line from which this function is called
handlethe PGSQL handle
sqlthe sql string to execute
callbackthe callback function to execute
pdatathe state data passed on each callback invocation
Returns
SWITCH_STATUS_SUCCESS if the operation was successful
Note
none

Definition at line 662 of file switch_pgsql.c.

References switch_assert, SWITCH_CHANNEL_ID_LOG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_PGSQL_FAIL, switch_pgsql_finish_results, switch_pgsql_free_result(), switch_pgsql_handle_exec_base, switch_pgsql_handle_get_error(), switch_pgsql_next_result, SWITCH_PGSQL_SUCCESS, switch_safe_free, switch_str_nil, and zstr.

666 {
667 #ifdef SWITCH_HAVE_PGSQL
668  char *err_str = NULL;
669  int row = 0, col = 0, err_cnt = 0;
670  switch_pgsql_result_t *result = NULL;
671 
672  handle->affected_rows = 0;
673 
674  switch_assert(callback != NULL);
675 
676  if (switch_pgsql_handle_exec_base(handle, sql, err) == SWITCH_PGSQL_FAIL) {
677  goto error;
678  }
679 
680  if (switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) {
681  err_cnt++;
682  err_str = switch_pgsql_handle_get_error(handle);
683  if (result && !zstr(result->err)) {
684  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));
685  }
686  if (!zstr(err_str)) {
687  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));
688  }
689  switch_safe_free(err_str);
690  err_str = NULL;
691  }
692 
693  while (result != NULL) {
694  /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Processing result with %d rows and %d columns.\n", result->rows, result->cols);*/
695  for (row = 0; row < result->rows; ++row) {
696  char **names;
697  char **vals;
698 
699  names = calloc(result->cols, sizeof(*names));
700  vals = calloc(result->cols, sizeof(*vals));
701 
702  switch_assert(names && vals);
703 
704  for (col = 0; col < result->cols; ++col) {
705  char * tmp;
706  int len;
707 
708  tmp = PQfname(result->result, col);
709  if (tmp) {
710  len = strlen(tmp);
711  names[col] = malloc(len+1);
712  names[col][len] = '\0';
713  strncpy(names[col], tmp, len);
714 
715  len = PQgetlength(result->result, row, col);
716  vals[col] = malloc(len+1);
717  vals[col][len] = '\0';
718  tmp = PQgetvalue(result->result, row, col);
719  strncpy(vals[col], tmp, len);
720  /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Processing result row %d, col %d: %s => %s\n", row, col, names[col], vals[col]);*/
721  } else {
722  /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Processing result row %d, col %d.\n", row, col);*/
723  switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "ERR: Column number %d out of range\n", col);
724  }
725  }
726 
727  /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Executing callback for row %d...\n", row);*/
728  if (callback(pdata, result->cols, vals, names)) {
729  switch_pgsql_finish_results(handle); /* Makes sure next call to switch_pgsql_next_result will return NULL */
730  row = result->rows; /* Makes us exit the for loop */
731  }
732 
733  for (col = 0; col < result->cols; ++col) {
734  free(names[col]);
735  free(vals[col]);
736  }
737  free(names);
738  free(vals);
739  }
740  switch_pgsql_free_result(&result);
741  if (switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) {
742  err_cnt++;
743  err_str = switch_pgsql_handle_get_error(handle);
744  if (result && !zstr(result->err)) {
745  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));
746  }
747  if (!zstr(err_str)) {
748  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));
749  }
750  switch_safe_free(err_str);
751  err_str = NULL;
752  }
753  }
754  if (err_cnt) {
755  goto error;
756  }
757 
758  return SWITCH_PGSQL_SUCCESS;
759  error:
760 #endif
761  return SWITCH_PGSQL_FAIL;
762 }
void switch_pgsql_free_result(switch_pgsql_result_t **result)
Definition: switch_pgsql.c:439
#define zstr(x)
Definition: switch_utils.h:281
struct switch_pgsql_result switch_pgsql_result_t
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
#define switch_pgsql_finish_results(handle)
Definition: switch_pgsql.h:107
#define switch_pgsql_next_result(h, r)
Definition: switch_pgsql.h:102
#define switch_pgsql_handle_exec_base(handle, sql, err)
Definition: switch_pgsql.h:111
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
char * switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle)
Definition: switch_pgsql.c:796
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_assert(expr)
switch_pgsql_status_t switch_pgsql_handle_connect ( switch_pgsql_handle_t handle)

Connect to the database specified by the DSN passed to the switch_pgsql_handle_new() call which initialized this handle.

Parameters
Thedatabase handle to connect to the database.
Returns
Returns SWITCH_PGSQL_SUCCESS or SWITCH_PGSQL_FAIL.

Definition at line 489 of file switch_pgsql.c.

References SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_PGSQL_FAIL, switch_pgsql_handle_disconnect(), switch_pgsql_handle_get_error(), SWITCH_PGSQL_STATE_CONNECTED, SWITCH_PGSQL_SUCCESS, and switch_safe_free.

Referenced by _switch_cache_db_get_db_handle().

490 {
491 #ifdef SWITCH_HAVE_PGSQL
492  if (handle->state == SWITCH_PGSQL_STATE_CONNECTED) {
494  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Re-connecting %s\n", handle->dsn);
495  }
496 
497  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Connecting %s\n", handle->dsn);
498 
499  handle->con = PQconnectdb(handle->dsn);
500  if (PQstatus(handle->con) != CONNECTION_OK) {
501  char *err_str;
502  if ((err_str = switch_pgsql_handle_get_error(handle))) {
504  switch_safe_free(err_str);
505  } else {
506  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to connect to the database [%s]\n", handle->dsn);
508  }
509  return SWITCH_PGSQL_FAIL;
510  }
511 
512  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Connected to [%s]\n", handle->dsn);
513  handle->state = SWITCH_PGSQL_STATE_CONNECTED;
514  handle->sock = PQsocket(handle->con);
515  return SWITCH_PGSQL_SUCCESS;
516 #else
517  return SWITCH_PGSQL_FAIL;
518 #endif
519 }
#define SWITCH_CHANNEL_LOG
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_pgsql_status_t switch_pgsql_handle_disconnect(switch_pgsql_handle_t *handle)
Disconnects a PGSQL connection from the database.
Definition: switch_pgsql.c:225
char * switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle)
Definition: switch_pgsql.c:796
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_pgsql_handle_destroy ( switch_pgsql_handle_t **  handlep)

Definition at line 764 of file switch_pgsql.c.

References switch_pgsql_handle_disconnect(), and switch_safe_free.

Referenced by _switch_cache_db_get_db_handle(), and sql_close().

765 {
766 #ifdef SWITCH_HAVE_PGSQL
767 
768  switch_pgsql_handle_t *handle = NULL;
769 
770  if (!handlep) {
771  return;
772  }
773  handle = *handlep;
774 
775  if (handle) {
777 
778  switch_safe_free(handle->dsn);
779  free(handle);
780  }
781  *handlep = NULL;
782 #else
783  return;
784 #endif
785 }
struct switch_pgsql_handle switch_pgsql_handle_t
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_pgsql_status_t switch_pgsql_handle_disconnect(switch_pgsql_handle_t *handle)
Disconnects a PGSQL connection from the database.
Definition: switch_pgsql.c:225
switch_pgsql_status_t switch_pgsql_handle_disconnect ( switch_pgsql_handle_t handle)

Disconnects a PGSQL connection from the database.

Parameters
handleThe PGSQL database handle to disconnect.
Returns
Returns SWITCH_PGSQL_SUCCESS or SWITCH_PGSQL_FAIL.

Definition at line 225 of file switch_pgsql.c.

References SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, switch_log_printf(), SWITCH_PGSQL_FAIL, SWITCH_PGSQL_STATE_CONNECTED, SWITCH_PGSQL_STATE_DOWN, SWITCH_PGSQL_SUCCESS, and switch_safe_free.

Referenced by switch_pgsql_handle_connect(), and switch_pgsql_handle_destroy().

226 {
227 #ifdef SWITCH_HAVE_PGSQL
228 
229  if (!handle) {
230  return SWITCH_PGSQL_FAIL;
231  }
232 
233  if (handle->state == SWITCH_PGSQL_STATE_CONNECTED) {
234  PQfinish(handle->con);
235  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "Disconnected from [%s]\n", handle->dsn);
236  }
237  switch_safe_free(handle->sql);
238  handle->state = SWITCH_PGSQL_STATE_DOWN;
239 
240  return SWITCH_PGSQL_SUCCESS;
241 #else
242  return SWITCH_PGSQL_FAIL;
243 #endif
244 }
#define SWITCH_CHANNEL_LOG
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_pgsql_status_t switch_pgsql_handle_exec_base_detailed ( const char *  file,
const char *  func,
int  line,
switch_pgsql_handle_t handle,
const char *  sql,
char **  err 
)

Definition at line 576 of file switch_pgsql.c.

References SWITCH_CHANNEL_ID_LOG, SWITCH_FALSE, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_PGSQL_FAIL, switch_pgsql_finish_results, switch_pgsql_flush(), switch_pgsql_handle_get_error(), switch_pgsql_send_query(), SWITCH_PGSQL_SUCCESS, switch_str_nil, switch_stristr(), SWITCH_TRUE, and zstr.

Referenced by switch_pgsql_handle_exec_detailed(), and switch_pgsql_handle_exec_string_detailed().

578 {
579 #ifdef SWITCH_HAVE_PGSQL
580  char *err_str = NULL, *er = NULL;
581 
582 
583 
584  switch_pgsql_flush(handle);
585  handle->affected_rows = 0;
586 
587  if (!db_is_up(handle)) {
588  er = strdup("Database is not up!");
589  goto error;
590  }
591 
592  if (handle->auto_commit == SWITCH_FALSE && handle->in_txn == SWITCH_FALSE) {
593  if (switch_pgsql_send_query(handle, "BEGIN") != SWITCH_PGSQL_SUCCESS) {
594  er = strdup("Error sending BEGIN!");
596  db_is_up(handle); /* If finish_results failed, maybe the db went dead */
597  }
598  goto error;
599  }
600 
602  db_is_up(handle);
603  er = strdup("Error sending BEGIN!");
604  goto error;
605  }
606  handle->in_txn = SWITCH_TRUE;
607  }
608 
609  if (switch_pgsql_send_query(handle, sql) != SWITCH_PGSQL_SUCCESS) {
610  er = strdup("Error sending query!");
612  db_is_up(handle);
613  }
614  goto error;
615  }
616 
617  return SWITCH_PGSQL_SUCCESS;
618 
619  error:
620  err_str = switch_pgsql_handle_get_error(handle);
621 
622  if (zstr(err_str)) {
623  if (zstr(er)) {
624  err_str = strdup((char *)"SQL ERROR!");
625  } else {
626  err_str = er;
627  }
628  } else {
629  if (!zstr(er)) {
630  free(er);
631  }
632  }
633 
634  if (err_str) {
635  if (!switch_stristr("already exists", err_str) && !switch_stristr("duplicate key name", err_str)) {
636  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));
637  }
638  if (err) {
639  *err = err_str;
640  } else {
641  free(err_str);
642  }
643  }
644 #endif
645  return SWITCH_PGSQL_FAIL;
646 }
#define zstr(x)
Definition: switch_utils.h:281
switch_pgsql_status_t switch_pgsql_flush(switch_pgsql_handle_t *handle)
Definition: switch_pgsql.c:842
#define switch_pgsql_finish_results(handle)
Definition: switch_pgsql.h:107
switch_pgsql_status_t switch_pgsql_send_query(switch_pgsql_handle_t *handle, const char *sql)
Definition: switch_pgsql.c:246
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
char * switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle)
Definition: switch_pgsql.c:796
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char * switch_stristr(const char *instr, const char *str)
switch_pgsql_status_t switch_pgsql_handle_exec_detailed ( const char *  file,
const char *  func,
int  line,
switch_pgsql_handle_t handle,
const char *  sql,
char **  err 
)

Definition at line 648 of file switch_pgsql.c.

References SWITCH_PGSQL_FAIL, switch_pgsql_finish_results, and switch_pgsql_handle_exec_base_detailed().

650 {
651 #ifdef SWITCH_HAVE_PGSQL
652  if (switch_pgsql_handle_exec_base_detailed(file, func, line, handle, sql, err) == SWITCH_PGSQL_FAIL) {
653  goto error;
654  }
655 
656  return switch_pgsql_finish_results(handle);
657  error:
658 #endif
659  return SWITCH_PGSQL_FAIL;
660 }
#define switch_pgsql_finish_results(handle)
Definition: switch_pgsql.h:107
switch_pgsql_status_t switch_pgsql_handle_exec_base_detailed(const char *file, const char *func, int line, switch_pgsql_handle_t *handle, const char *sql, char **err)
Definition: switch_pgsql.c:576
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 
)

Definition at line 521 of file switch_pgsql.c.

References SWITCH_PGSQL_FAIL, switch_pgsql_finish_results, switch_pgsql_free_result(), switch_pgsql_handle_exec_base_detailed(), switch_pgsql_next_result, and SWITCH_PGSQL_SUCCESS.

523 {
524 #ifdef SWITCH_HAVE_PGSQL
526  char *val = NULL;
527  switch_pgsql_result_t *result = NULL;
528 
529  handle->affected_rows = 0;
530 
531  if (switch_pgsql_handle_exec_base_detailed(file, func, line, handle, sql, err) == SWITCH_PGSQL_FAIL) {
532  goto error;
533  }
534 
535  if(switch_pgsql_next_result(handle, &result) == SWITCH_PGSQL_FAIL) {
536  goto error;
537  }
538 
539  if (result) {
540  switch (result->status) {
541 #if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 2
542  case PGRES_SINGLE_TUPLE:
543  /* Added in PostgreSQL 9.2 */
544 #endif
545  case PGRES_COMMAND_OK:
546  case PGRES_TUPLES_OK:
547  break;
548  default:
549  sstatus = SWITCH_PGSQL_FAIL;
550  goto done;
551  }
552  }
553 
554  if (handle->affected_rows <= 0) {
555  goto done;
556  }
557 
558  val = PQgetvalue(result->result, 0, 0);
559  strncpy(resbuf, val, len);
560 
561  done:
562 
563  switch_pgsql_free_result(&result);
565  sstatus = SWITCH_PGSQL_FAIL;
566  }
567 
568  return sstatus;
569  error:
570  return SWITCH_PGSQL_FAIL;
571 #else
572  return SWITCH_PGSQL_FAIL;
573 #endif
574 }
switch_pgsql_status_t
Definition: switch_pgsql.h:53
void switch_pgsql_free_result(switch_pgsql_result_t **result)
Definition: switch_pgsql.c:439
struct switch_pgsql_result switch_pgsql_result_t
#define switch_pgsql_finish_results(handle)
Definition: switch_pgsql.h:107
#define switch_pgsql_next_result(h, r)
Definition: switch_pgsql.h:102
switch_pgsql_status_t switch_pgsql_handle_exec_base_detailed(const char *file, const char *func, int line, switch_pgsql_handle_t *handle, const char *sql, char **err)
Definition: switch_pgsql.c:576
char* switch_pgsql_handle_get_error ( switch_pgsql_handle_t handle)

Definition at line 796 of file switch_pgsql.c.

References switch_strdup.

Referenced by switch_pgsql_handle_callback_exec_detailed(), switch_pgsql_handle_connect(), switch_pgsql_handle_exec_base_detailed(), switch_pgsql_next_result_timed(), switch_pgsql_send_query(), and switch_pgsql_SQLEndTran().

797 {
798 #ifdef SWITCH_HAVE_PGSQL
799  char * err_str;
800  if (!handle) {
801  return NULL;
802  };
803  switch_strdup(err_str, PQerrorMessage(handle->con));
804  return err_str;
805 #else
806  return NULL;
807 #endif
808 }
#define switch_strdup(ptr, s)
switch_pgsql_state_t switch_pgsql_handle_get_state ( switch_pgsql_handle_t handle)

Definition at line 787 of file switch_pgsql.c.

References SWITCH_PGSQL_STATE_ERROR, and SWITCH_PGSQL_STATE_INIT.

788 {
789 #ifdef SWITCH_HAVE_PGSQL
790  return handle ? handle->state : SWITCH_PGSQL_STATE_INIT;
791 #else
793 #endif
794 }
switch_pgsql_handle_t* switch_pgsql_handle_new ( const char *  dsn)

Create a new handle for the PGSQL connection.

Parameters
dsnThe DSN of the database to connect to. See documentation for PQconnectdb() at http://www.postgresql.org/docs/9.0/static/libpq-connect.html. The DSN MUST be prefixed with 'pgsql;' to use the switch_cache_db* functionality. However, the DSN passed to this function directly MUST NOT be prefixed with 'pgsql;'.
Returns
Returns a pointer to a newly allocated switch_pgsql_handle_t type or NULL on failure.

Definition at line 66 of file switch_pgsql.c.

References DEFAULT_PGSQL_RETRIES, memset(), SWITCH_FALSE, SWITCH_PGSQL_STATE_INIT, switch_safe_free, and SWITCH_TRUE.

Referenced by _switch_cache_db_get_db_handle().

67 {
68 #ifdef SWITCH_HAVE_PGSQL
69  switch_pgsql_handle_t *new_handle;
70 
71  if (!(new_handle = malloc(sizeof(*new_handle)))) {
72  goto err;
73  }
74 
75  memset(new_handle, 0, sizeof(*new_handle));
76 
77  if (!(new_handle->dsn = strdup(dsn))) {
78  goto err;
79  }
80 
81  new_handle->sock = 0;
82  new_handle->state = SWITCH_PGSQL_STATE_INIT;
83  new_handle->con = NULL;
84  new_handle->affected_rows = 0;
85  new_handle->num_retries = DEFAULT_PGSQL_RETRIES;
86  new_handle->auto_commit = SWITCH_TRUE;
87  new_handle->in_txn = SWITCH_FALSE;
88 
89  return new_handle;
90 
91  err:
92  if (new_handle) {
93  switch_safe_free(new_handle->dsn);
94  switch_safe_free(new_handle);
95  }
96 #endif
97  return NULL;
98 }
struct switch_pgsql_handle switch_pgsql_handle_t
#define DEFAULT_PGSQL_RETRIES
Definition: switch_pgsql.h:38
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
memset(buf, 0, buflen)
switch_pgsql_status_t switch_pgsql_next_result_timed ( switch_pgsql_handle_t handle,
switch_pgsql_result_t **  result_out,
int  msec 
)

Definition at line 287 of file switch_pgsql.c.

References memset(), SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, switch_log_printf(), switch_micro_time_now(), switch_pgsql_cancel, SWITCH_PGSQL_FAIL, switch_pgsql_flush(), switch_pgsql_handle_get_error(), SWITCH_PGSQL_STATE_ERROR, SWITCH_PGSQL_SUCCESS, and switch_safe_free.

288 {
289 #ifdef SWITCH_HAVE_PGSQL
291  switch_time_t start;
292  switch_time_t ctime;
293  unsigned int usec = msec * 1000;
294  char *err_str;
295  struct pollfd fds[2] = { {0} };
296  int poll_res = 0;
297 
298  if(!handle) {
299  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "**BUG** Null handle passed to switch_pgsql_next_result.\n");
300  return SWITCH_PGSQL_FAIL;
301  }
302 
303  /* Try to consume input that might be waiting right away */
304  if (PQconsumeInput(handle->con)) {
305  /* And check to see if we have a full result ready for reading */
306  if (PQisBusy(handle->con)) {
307 
308  /* Wait for a result to become available, up to msec milliseconds */
309  start = switch_micro_time_now();
310  while((ctime = switch_micro_time_now()) - start <= usec) {
311  int wait_time = (usec - (ctime - start)) / 1000;
312  fds[0].fd = handle->sock;
313  fds[0].events |= POLLIN;
314  fds[0].events |= POLLERR;
315  fds[0].events |= POLLNVAL;
316  fds[0].events |= POLLHUP;
317  fds[0].events |= POLLPRI;
318  fds[0].events |= POLLRDNORM;
319  fds[0].events |= POLLRDBAND;
320 
321  /* Wait for the PostgreSQL socket to be ready for data reads. */
322  if ((poll_res = poll(&fds[0], 1, wait_time)) > 0 ) {
323  if (fds[0].revents & POLLHUP || fds[0].revents & POLLNVAL) {
324  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PGSQL socket closed or invalid while waiting for result for query (%s)\n", handle->sql);
325  goto error;
326  } else if (fds[0].revents & POLLERR) {
327  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll error trying to read PGSQL socket for query (%s)\n", handle->sql);
328  goto error;
329  } else if (fds[0].revents & POLLIN || fds[0].revents & POLLPRI || fds[0].revents & POLLRDNORM || fds[0].revents & POLLRDBAND) {
330  /* Then try to consume any input waiting. */
331  if (PQconsumeInput(handle->con)) {
332  if (PQstatus(handle->con) == CONNECTION_BAD) {
333  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Connection terminated while waiting for result.\n");
334  handle->state = SWITCH_PGSQL_STATE_ERROR;
335  goto error;
336  }
337 
338  /* And check to see if we have a full result ready for reading */
339  if (!PQisBusy(handle->con)) {
340  /* If we can pull a full result without blocking, then break this loop */
341  break;
342  }
343  } else {
344  /* If we had an error trying to consume input, report it and cancel the query. */
345  err_str = switch_pgsql_handle_get_error(handle);
346  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
347  switch_safe_free(err_str);
348  switch_pgsql_cancel(handle);
349  goto error;
350  }
351  }
352  } else if (poll_res == -1) {
353  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Poll failed trying to read PGSQL socket for query (%s)\n", handle->sql);
354  goto error;
355  }
356  }
357 
358  /* If we broke the loop above because of a timeout, report that and cancel the query. */
359  if (ctime - start > usec) {
360  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Query (%s) took too long to complete or database not responding.\n", handle->sql);
361  switch_pgsql_cancel(handle);
362  goto error;
363  }
364 
365  }
366  } else {
367  /* If we had an error trying to consume input, report it and cancel the query. */
368  err_str = switch_pgsql_handle_get_error(handle);
369  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "An error occurred trying to consume input for query (%s): %s\n", handle->sql, err_str);
370  switch_safe_free(err_str);
371  /* switch_pgsql_cancel(handle); */
372  goto error;
373  }
374 
375 
376  /* At this point, we know we can read a full result without blocking. */
377  if(!(res = malloc(sizeof(switch_pgsql_result_t)))) {
379  goto error;
380  }
381  memset(res, 0, sizeof(switch_pgsql_result_t));
382 
383 
384  res->result = PQgetResult(handle->con);
385  if (res->result) {
386  *result_out = res;
387  res->status = PQresultStatus(res->result);
388  switch(res->status) {
389 #if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 2
390  case PGRES_SINGLE_TUPLE:
391  /* Added in PostgreSQL 9.2 */
392 #endif
393  case PGRES_TUPLES_OK:
394  {
395  res->rows = PQntuples(res->result);
396  handle->affected_rows = res->rows;
397  res->cols = PQnfields(res->result);
398  }
399  break;
400 #if POSTGRESQL_MAJOR_VERSION >= 9 && POSTGRESQL_MINOR_VERSION >= 1
401  case PGRES_COPY_BOTH:
402  /* Added in PostgreSQL 9.1 */
403 #endif
404  case PGRES_COPY_OUT:
405  case PGRES_COPY_IN:
406  case PGRES_COMMAND_OK:
407  break;
408  case PGRES_EMPTY_QUERY:
409  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_EMPTY_QUERY\n", handle->sql);
410  case PGRES_BAD_RESPONSE:
411  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_BAD_RESPONSE\n", handle->sql);
412  case PGRES_NONFATAL_ERROR:
413  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_NONFATAL_ERROR\n", handle->sql);
414  case PGRES_FATAL_ERROR:
415  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Query (%s) returned PGRES_FATAL_ERROR\n", handle->sql);
416  res->err = PQresultErrorMessage(res->result);
417  goto error;
418  break;
419  }
420  } else {
421  free(res);
422  res = NULL;
423  *result_out = NULL;
424  }
425 
426  return SWITCH_PGSQL_SUCCESS;
427  error:
428 
429  /* Make sure the failed connection does not have any transactions marked as in progress */
430  switch_pgsql_flush(handle);
431 
432  /* Try to reconnect to the DB if we were dropped */
433  db_is_up(handle);
434 
435 #endif
436  return SWITCH_PGSQL_FAIL;
437 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
#define SWITCH_CHANNEL_LOG
int64_t switch_time_t
Definition: switch_apr.h:188
struct switch_pgsql_result switch_pgsql_result_t
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_pgsql_status_t switch_pgsql_flush(switch_pgsql_handle_t *handle)
Definition: switch_pgsql.c:842
#define switch_pgsql_cancel(handle)
Definition: switch_pgsql.h:99
char * switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle)
Definition: switch_pgsql.c:796
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
memset(buf, 0, buflen)
switch_pgsql_status_t switch_pgsql_send_query ( switch_pgsql_handle_t handle,
const char *  sql 
)

Definition at line 246 of file switch_pgsql.c.

References SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, switch_log_printf(), SWITCH_PGSQL_FAIL, switch_pgsql_finish_results, switch_pgsql_handle_get_error(), SWITCH_PGSQL_SUCCESS, and switch_safe_free.

Referenced by switch_pgsql_handle_exec_base_detailed().

247 {
248 #ifdef SWITCH_HAVE_PGSQL
249  char *err_str;
250 
251  switch_safe_free(handle->sql);
252  handle->sql = strdup(sql);
253  if (!PQsendQuery(handle->con, sql)) {
254  err_str = switch_pgsql_handle_get_error(handle);
255  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to send query (%s) to database: %s\n", sql, err_str);
257  goto error;
258  }
259 
260  return SWITCH_PGSQL_SUCCESS;
261  error:
262 #endif
263  return SWITCH_PGSQL_FAIL;
264 }
#define SWITCH_CHANNEL_LOG
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
#define switch_pgsql_finish_results(handle)
Definition: switch_pgsql.h:107
char * switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle)
Definition: switch_pgsql.c:796
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_pgsql_set_num_retries ( switch_pgsql_handle_t handle,
int  num_retries 
)

Sets the number of retries if the PGSQL connection fails.

Parameters
handleA fully allocated switch_pgsql_handle_t returned from a call to switch_pgsql_handle_new().
num_retriesHow many times to retry connecting to the database if this connection fails.

Definition at line 216 of file switch_pgsql.c.

217 {
218 #ifdef SWITCH_HAVE_PGSQL
219  if (handle) {
220  handle->num_retries = num_retries;
221  }
222 #endif
223 }
switch_pgsql_status_t switch_pgsql_SQLEndTran ( switch_pgsql_handle_t handle,
switch_bool_t  commit 
)

Definition at line 865 of file switch_pgsql.c.

References SWITCH_CHANNEL_LOG, SWITCH_FALSE, SWITCH_LOG_CRIT, switch_log_printf(), SWITCH_PGSQL_FAIL, switch_pgsql_handle_get_error(), SWITCH_PGSQL_SUCCESS, and switch_safe_free.

Referenced by do_trans(), switch_cache_db_persistant_execute_trans_full(), and switch_core_sqldb_start().

866 {
867 #ifdef SWITCH_HAVE_PGSQL
868  char * err_str = NULL;
869  if (commit) {
870  if(!PQsendQuery(handle->con, "COMMIT")) {
871  err_str = switch_pgsql_handle_get_error(handle);
872  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not commit transaction: %s\n", err_str);
873  switch_safe_free(err_str);
874  return SWITCH_PGSQL_FAIL;
875  }
876  } else {
877  if(!PQsendQuery(handle->con, "ROLLBACK")) {
878  err_str = switch_pgsql_handle_get_error(handle);
879  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Could not rollback transaction: %s\n", err_str);
880  switch_safe_free(err_str);
881  return SWITCH_PGSQL_FAIL;
882  }
883  }
884  handle->in_txn = SWITCH_FALSE;
885  return SWITCH_PGSQL_SUCCESS;
886 #else
888 #endif
889 }
switch_pgsql_status_t
Definition: switch_pgsql.h:53
#define SWITCH_CHANNEL_LOG
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
char * switch_pgsql_handle_get_error(switch_pgsql_handle_t *handle)
Definition: switch_pgsql.c:796
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_pgsql_status_t switch_pgsql_SQLSetAutoCommitAttr ( switch_pgsql_handle_t handle,
switch_bool_t  on 
)

Definition at line 828 of file switch_pgsql.c.

References SWITCH_FALSE, SWITCH_PGSQL_SUCCESS, and SWITCH_TRUE.

Referenced by do_trans(), switch_cache_db_persistant_execute_trans_full(), and switch_core_sqldb_start().

829 {
830 #ifdef SWITCH_HAVE_PGSQL
831  if (on) {
832  handle->auto_commit = SWITCH_TRUE;
833  } else {
834  handle->auto_commit = SWITCH_FALSE;
835  }
836  return SWITCH_PGSQL_SUCCESS;
837 #else
839 #endif
840 }
switch_pgsql_status_t
Definition: switch_pgsql.h:53