#include "asterisk.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libpq-fe.h>
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/options.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"
Include dependency graph for res_config_pgsql.c:
Go to the source code of this file.
Defines | |
#define | MAX_DB_OPTION_SIZE 64 |
#define | RES_CONFIG_PGSQL_CONF "res_pgsql.conf" |
Functions | |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"PostgreSQL RealTime Configuration Driver",.load=load_module,.unload=unload_module,.reload=reload) | |
AST_MUTEX_DEFINE_STATIC (pgsql_lock) | |
static struct ast_config * | config_pgsql (const char *database, const char *table, const char *file, struct ast_config *cfg, int withcomments) |
static int | load_module (void) |
static int | parse_config (void) |
static int | pgsql_reconnect (const char *database) |
static struct ast_config * | realtime_multi_pgsql (const char *database, const char *table, va_list ap) |
static struct ast_variable * | realtime_pgsql (const char *database, const char *table, va_list ap) |
static int | realtime_pgsql_status (int fd, int argc, char **argv) |
static int | reload (void) |
static int | unload_module (void) |
static int | update_pgsql (const char *database, const char *table, const char *keyfield, const char *lookup, va_list ap) |
Variables | |
static struct ast_cli_entry | cli_realtime [] |
static char | cli_realtime_pgsql_status_usage [] |
static time_t | connect_time = 0 |
static char | dbhost [MAX_DB_OPTION_SIZE] = "" |
static char | dbname [MAX_DB_OPTION_SIZE] = "" |
static char | dbpass [MAX_DB_OPTION_SIZE] = "" |
static int | dbport = 5432 |
static char | dbsock [MAX_DB_OPTION_SIZE] = "" |
static char | dbuser [MAX_DB_OPTION_SIZE] = "" |
static struct ast_config_engine | pgsql_engine |
PGconn * | pgsqlConn = NULL |
Definition in file res_config_pgsql.c.
#define MAX_DB_OPTION_SIZE 64 |
Definition at line 55 of file res_config_pgsql.c.
#define RES_CONFIG_PGSQL_CONF "res_pgsql.conf" |
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_GLOBAL_SYMBOLS | , | |||
"PostgreSQL RealTime Configuration Driver" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload | |||
) |
AST_MUTEX_DEFINE_STATIC | ( | pgsql_lock | ) |
static struct ast_config* config_pgsql | ( | const char * | database, | |
const char * | table, | |||
const char * | file, | |||
struct ast_config * | cfg, | |||
int | withcomments | |||
) | [static] |
Definition at line 439 of file res_config_pgsql.c.
References ast_build_string(), ast_category_append(), ast_category_new(), ast_config_internal_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_append(), ast_variable_new(), last, LOG_DEBUG, LOG_WARNING, pgsql_reconnect(), pgsqlConn, RES_CONFIG_PGSQL_CONF, and result.
00442 { 00443 PGresult *result = NULL; 00444 long num_rows; 00445 struct ast_variable *new_v; 00446 struct ast_category *cur_cat = NULL; 00447 char sqlbuf[1024] = ""; 00448 char *sql; 00449 size_t sqlleft = sizeof(sqlbuf); 00450 char last[80] = ""; 00451 int last_cat_metric = 0; 00452 00453 last[0] = '\0'; 00454 00455 if (!file || !strcmp(file, RES_CONFIG_PGSQL_CONF)) { 00456 ast_log(LOG_WARNING, "Postgresql RealTime: Cannot configure myself.\n"); 00457 return NULL; 00458 } 00459 00460 ast_build_string(&sql, &sqlleft, "SELECT category, var_name, var_val, cat_metric FROM %s ", table); 00461 ast_build_string(&sql, &sqlleft, "WHERE filename='%s' and commented=0", file); 00462 ast_build_string(&sql, &sqlleft, "ORDER BY cat_metric DESC, var_metric ASC, category, var_name "); 00463 00464 ast_log(LOG_DEBUG, "Postgresql RealTime: Static SQL: %s\n", sqlbuf); 00465 00466 /* We now have our complete statement; Lets connect to the server and execute it. */ 00467 ast_mutex_lock(&pgsql_lock); 00468 if (!pgsql_reconnect(database)) { 00469 ast_mutex_unlock(&pgsql_lock); 00470 return NULL; 00471 } 00472 00473 if (!(result = PQexec(pgsqlConn, sqlbuf))) { 00474 ast_log(LOG_WARNING, 00475 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00476 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00477 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n", 00478 PQerrorMessage(pgsqlConn)); 00479 ast_mutex_unlock(&pgsql_lock); 00480 return NULL; 00481 } else { 00482 ExecStatusType result_status = PQresultStatus(result); 00483 if (result_status != PGRES_COMMAND_OK 00484 && result_status != PGRES_TUPLES_OK 00485 && result_status != PGRES_NONFATAL_ERROR) { 00486 ast_log(LOG_WARNING, 00487 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00488 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00489 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n", 00490 PQresultErrorMessage(result), PQresStatus(result_status)); 00491 ast_mutex_unlock(&pgsql_lock); 00492 return NULL; 00493 } 00494 } 00495 00496 if ((num_rows = PQntuples(result)) > 0) { 00497 int rowIndex = 0; 00498 00499 ast_log(LOG_DEBUG, "Postgresql RealTime: Found %ld rows.\n", num_rows); 00500 00501 for (rowIndex = 0; rowIndex < num_rows; rowIndex++) { 00502 char *field_category = PQgetvalue(result, rowIndex, 0); 00503 char *field_var_name = PQgetvalue(result, rowIndex, 1); 00504 char *field_var_val = PQgetvalue(result, rowIndex, 2); 00505 char *field_cat_metric = PQgetvalue(result, rowIndex, 3); 00506 if (!strcmp(field_var_name, "#include")) { 00507 if (!ast_config_internal_load(field_var_val, cfg, 0)) { 00508 PQclear(result); 00509 ast_mutex_unlock(&pgsql_lock); 00510 return NULL; 00511 } 00512 continue; 00513 } 00514 00515 if (strcmp(last, field_category) || last_cat_metric != atoi(field_cat_metric)) { 00516 cur_cat = ast_category_new(field_category); 00517 if (!cur_cat) 00518 break; 00519 strcpy(last, field_category); 00520 last_cat_metric = atoi(field_cat_metric); 00521 ast_category_append(cfg, cur_cat); 00522 } 00523 new_v = ast_variable_new(field_var_name, field_var_val); 00524 ast_variable_append(cur_cat, new_v); 00525 } 00526 } else { 00527 ast_log(LOG_WARNING, 00528 "Postgresql RealTime: Could not find config '%s' in database.\n", file); 00529 } 00530 00531 PQclear(result); 00532 ast_mutex_unlock(&pgsql_lock); 00533 00534 return cfg; 00535 }
static int load_module | ( | void | ) | [static] |
Definition at line 545 of file res_config_pgsql.c.
References ast_cli_register_multiple(), ast_config_engine_register(), ast_log(), AST_MODULE_LOAD_DECLINE, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), cli_realtime, LOG_DEBUG, LOG_WARNING, option_verbose, parse_config(), pgsql_engine, pgsql_reconnect(), and pgsqlConn.
00546 { 00547 if(!parse_config()) 00548 return AST_MODULE_LOAD_DECLINE; 00549 00550 ast_mutex_lock(&pgsql_lock); 00551 00552 if (!pgsql_reconnect(NULL)) { 00553 ast_log(LOG_WARNING, 00554 "Postgresql RealTime: Couldn't establish connection. Check debug.\n"); 00555 ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n", 00556 PQerrorMessage(pgsqlConn)); 00557 } 00558 00559 ast_config_engine_register(&pgsql_engine); 00560 if (option_verbose) { 00561 ast_verbose("Postgresql RealTime driver loaded.\n"); 00562 } 00563 ast_cli_register_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry)); 00564 00565 ast_mutex_unlock(&pgsql_lock); 00566 00567 return 0; 00568 }
static int parse_config | ( | void | ) | [static] |
Definition at line 619 of file res_config_pgsql.c.
References ast_config_destroy(), ast_config_load(), ast_log(), ast_variable_retrieve(), config, dbhost, dbname, dbpass, dbport, dbsock, dbuser, LOG_DEBUG, LOG_WARNING, RES_CONFIG_PGSQL_CONF, and s.
00620 { 00621 struct ast_config *config; 00622 const char *s; 00623 00624 config = ast_config_load(RES_CONFIG_PGSQL_CONF); 00625 00626 if (!config) { 00627 ast_log(LOG_WARNING, "Unable to load config %s\n",RES_CONFIG_PGSQL_CONF); 00628 return 0; 00629 } 00630 if (!(s = ast_variable_retrieve(config, "general", "dbuser"))) { 00631 ast_log(LOG_WARNING, 00632 "Postgresql RealTime: No database user found, using 'asterisk' as default.\n"); 00633 strcpy(dbuser, "asterisk"); 00634 } else { 00635 ast_copy_string(dbuser, s, sizeof(dbuser)); 00636 } 00637 00638 if (!(s = ast_variable_retrieve(config, "general", "dbpass"))) { 00639 ast_log(LOG_WARNING, 00640 "Postgresql RealTime: No database password found, using 'asterisk' as default.\n"); 00641 strcpy(dbpass, "asterisk"); 00642 } else { 00643 ast_copy_string(dbpass, s, sizeof(dbpass)); 00644 } 00645 00646 if (!(s = ast_variable_retrieve(config, "general", "dbhost"))) { 00647 ast_log(LOG_WARNING, 00648 "Postgresql RealTime: No database host found, using localhost via socket.\n"); 00649 dbhost[0] = '\0'; 00650 } else { 00651 ast_copy_string(dbhost, s, sizeof(dbhost)); 00652 } 00653 00654 if (!(s = ast_variable_retrieve(config, "general", "dbname"))) { 00655 ast_log(LOG_WARNING, 00656 "Postgresql RealTime: No database name found, using 'asterisk' as default.\n"); 00657 strcpy(dbname, "asterisk"); 00658 } else { 00659 ast_copy_string(dbname, s, sizeof(dbname)); 00660 } 00661 00662 if (!(s = ast_variable_retrieve(config, "general", "dbport"))) { 00663 ast_log(LOG_WARNING, 00664 "Postgresql RealTime: No database port found, using 5432 as default.\n"); 00665 dbport = 5432; 00666 } else { 00667 dbport = atoi(s); 00668 } 00669 00670 if (dbhost && !(s = ast_variable_retrieve(config, "general", "dbsock"))) { 00671 ast_log(LOG_WARNING, 00672 "Postgresql RealTime: No database socket found, using '/tmp/pgsql.sock' as default.\n"); 00673 strcpy(dbsock, "/tmp/pgsql.sock"); 00674 } else { 00675 ast_copy_string(dbsock, s, sizeof(dbsock)); 00676 } 00677 ast_config_destroy(config); 00678 00679 if (dbhost) { 00680 ast_log(LOG_DEBUG, "Postgresql RealTime Host: %s\n", dbhost); 00681 ast_log(LOG_DEBUG, "Postgresql RealTime Port: %i\n", dbport); 00682 } else { 00683 ast_log(LOG_DEBUG, "Postgresql RealTime Socket: %s\n", dbsock); 00684 } 00685 ast_log(LOG_DEBUG, "Postgresql RealTime User: %s\n", dbuser); 00686 ast_log(LOG_DEBUG, "Postgresql RealTime Password: %s\n", dbpass); 00687 ast_log(LOG_DEBUG, "Postgresql RealTime DBName: %s\n", dbname); 00688 00689 return 1; 00690 }
static int pgsql_reconnect | ( | const char * | database | ) | [static] |
Definition at line 692 of file res_config_pgsql.c.
References ast_log(), ast_malloc, connect_time, dbhost, dbname, dbpass, dbport, dbsock, dbuser, free, LOG_DEBUG, LOG_ERROR, pgsqlConn, and S_OR.
Referenced by config_pgsql(), load_module(), realtime_multi_pgsql(), realtime_pgsql(), reload(), and update_pgsql().
00693 { 00694 char my_database[50]; 00695 00696 ast_copy_string(my_database, S_OR(database, dbname), sizeof(my_database)); 00697 00698 /* mutex lock should have been locked before calling this function. */ 00699 00700 if (pgsqlConn && PQstatus(pgsqlConn) != CONNECTION_OK) { 00701 PQfinish(pgsqlConn); 00702 pgsqlConn = NULL; 00703 } 00704 00705 if ((!pgsqlConn) && (dbhost || dbsock) && dbuser && dbpass && my_database) { 00706 char *connInfo = NULL; 00707 unsigned int size = 100 + strlen(dbhost) 00708 + strlen(dbuser) 00709 + strlen(dbpass) 00710 + strlen(my_database); 00711 00712 if (!(connInfo = ast_malloc(size))) 00713 return 0; 00714 00715 sprintf(connInfo, "host=%s port=%d dbname=%s user=%s password=%s", 00716 dbhost, dbport, my_database, dbuser, dbpass); 00717 ast_log(LOG_DEBUG, "%u connInfo=%s\n", size, connInfo); 00718 pgsqlConn = PQconnectdb(connInfo); 00719 ast_log(LOG_DEBUG, "%u connInfo=%s\n", size, connInfo); 00720 free(connInfo); 00721 connInfo = NULL; 00722 ast_log(LOG_DEBUG, "pgsqlConn=%p\n", pgsqlConn); 00723 if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) { 00724 ast_log(LOG_DEBUG, "Postgresql RealTime: Successfully connected to database.\n"); 00725 connect_time = time(NULL); 00726 return 1; 00727 } else { 00728 ast_log(LOG_ERROR, 00729 "Postgresql RealTime: Failed to connect database server %s on %s. Check debug for more info.\n", 00730 dbname, dbhost); 00731 ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n", 00732 PQresultErrorMessage(NULL)); 00733 return 0; 00734 } 00735 } else { 00736 ast_log(LOG_DEBUG, "Postgresql RealTime: Everything is fine.\n"); 00737 return 1; 00738 } 00739 }
static struct ast_config* realtime_multi_pgsql | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Definition at line 202 of file res_config_pgsql.c.
References ast_calloc, ast_category_append(), ast_category_new(), ast_category_rename(), ast_config_new(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_strlen_zero(), ast_variable_append(), ast_variable_new(), free, LOG_DEBUG, LOG_WARNING, pgsql_reconnect(), pgsqlConn, result, strsep(), and var.
00203 { 00204 PGresult *result = NULL; 00205 int num_rows = 0; 00206 char sql[256]; 00207 const char *initfield = NULL; 00208 char *stringp; 00209 char *chunk; 00210 char *op; 00211 const char *newparam, *newval; 00212 struct ast_realloca ra; 00213 struct ast_variable *var = NULL; 00214 struct ast_config *cfg = NULL; 00215 struct ast_category *cat = NULL; 00216 00217 if (!table) { 00218 ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n"); 00219 return NULL; 00220 } 00221 00222 memset(&ra, 0, sizeof(ra)); 00223 00224 if (!(cfg = ast_config_new())) 00225 return NULL; 00226 00227 /* Get the first parameter and first value in our list of passed paramater/value pairs */ 00228 newparam = va_arg(ap, const char *); 00229 newval = va_arg(ap, const char *); 00230 if (!newparam || !newval) { 00231 ast_log(LOG_WARNING, 00232 "Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n"); 00233 if (pgsqlConn) { 00234 PQfinish(pgsqlConn); 00235 pgsqlConn = NULL; 00236 }; 00237 return NULL; 00238 } 00239 00240 initfield = ast_strdupa(newparam); 00241 if ((op = strchr(initfield, ' '))) { 00242 *op = '\0'; 00243 } 00244 00245 /* Create the first part of the query using the first parameter/value pairs we just extracted 00246 If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ 00247 00248 if (!strchr(newparam, ' ')) 00249 op = " ="; 00250 else 00251 op = ""; 00252 00253 snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, 00254 newval); 00255 while ((newparam = va_arg(ap, const char *))) { 00256 newval = va_arg(ap, const char *); 00257 if (!strchr(newparam, ' ')) 00258 op = " ="; 00259 else 00260 op = ""; 00261 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, 00262 op, newval); 00263 } 00264 00265 if (initfield) { 00266 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield); 00267 } 00268 00269 va_end(ap); 00270 00271 /* We now have our complete statement; Lets connect to the server and execute it. */ 00272 ast_mutex_lock(&pgsql_lock); 00273 if (!pgsql_reconnect(database)) { 00274 ast_mutex_unlock(&pgsql_lock); 00275 return NULL; 00276 } 00277 00278 if (!(result = PQexec(pgsqlConn, sql))) { 00279 ast_log(LOG_WARNING, 00280 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00281 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00282 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n", 00283 PQerrorMessage(pgsqlConn)); 00284 ast_mutex_unlock(&pgsql_lock); 00285 return NULL; 00286 } else { 00287 ExecStatusType result_status = PQresultStatus(result); 00288 if (result_status != PGRES_COMMAND_OK 00289 && result_status != PGRES_TUPLES_OK 00290 && result_status != PGRES_NONFATAL_ERROR) { 00291 ast_log(LOG_WARNING, 00292 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00293 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00294 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n", 00295 PQresultErrorMessage(result), PQresStatus(result_status)); 00296 ast_mutex_unlock(&pgsql_lock); 00297 return NULL; 00298 } 00299 } 00300 00301 ast_log(LOG_DEBUG, "2Postgresql RealTime: Result=%p Query: %s\n", result, sql); 00302 00303 if ((num_rows = PQntuples(result)) > 0) { 00304 int numFields = PQnfields(result); 00305 int i = 0; 00306 int rowIndex = 0; 00307 char **fieldnames = NULL; 00308 00309 ast_log(LOG_DEBUG, "Postgresql RealTime: Found %d rows.\n", num_rows); 00310 00311 if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) { 00312 ast_mutex_unlock(&pgsql_lock); 00313 PQclear(result); 00314 return NULL; 00315 } 00316 for (i = 0; i < numFields; i++) 00317 fieldnames[i] = PQfname(result, i); 00318 00319 for (rowIndex = 0; rowIndex < num_rows; rowIndex++) { 00320 var = NULL; 00321 if (!(cat = ast_category_new(""))) 00322 continue; 00323 for (i = 0; i < numFields; i++) { 00324 stringp = PQgetvalue(result, rowIndex, i); 00325 while (stringp) { 00326 chunk = strsep(&stringp, ";"); 00327 if (chunk && !ast_strlen_zero(ast_strip(chunk))) { 00328 if (initfield && !strcmp(initfield, fieldnames[i])) { 00329 ast_category_rename(cat, chunk); 00330 } 00331 var = ast_variable_new(fieldnames[i], chunk); 00332 ast_variable_append(cat, var); 00333 } 00334 } 00335 } 00336 ast_category_append(cfg, cat); 00337 } 00338 free(fieldnames); 00339 } else { 00340 ast_log(LOG_WARNING, 00341 "Postgresql RealTime: Could not find any rows in table %s.\n", table); 00342 } 00343 00344 ast_mutex_unlock(&pgsql_lock); 00345 PQclear(result); 00346 00347 return cfg; 00348 }
static struct ast_variable* realtime_pgsql | ( | const char * | database, | |
const char * | table, | |||
va_list | ap | |||
) | [static] |
Definition at line 79 of file res_config_pgsql.c.
References ast_calloc, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), ast_variable_new(), free, LOG_DEBUG, LOG_WARNING, ast_variable::next, pgsql_reconnect(), result, strsep(), and var.
00080 { 00081 PGresult *result = NULL; 00082 int num_rows = 0; 00083 char sql[256]; 00084 char *stringp; 00085 char *chunk; 00086 char *op; 00087 const char *newparam, *newval; 00088 struct ast_variable *var = NULL, *prev = NULL; 00089 00090 if (!table) { 00091 ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n"); 00092 return NULL; 00093 } 00094 00095 /* Get the first parameter and first value in our list of passed paramater/value pairs */ 00096 newparam = va_arg(ap, const char *); 00097 newval = va_arg(ap, const char *); 00098 if (!newparam || !newval) { 00099 ast_log(LOG_WARNING, 00100 "Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n"); 00101 if (pgsqlConn) { 00102 PQfinish(pgsqlConn); 00103 pgsqlConn = NULL; 00104 }; 00105 return NULL; 00106 } 00107 00108 /* Create the first part of the query using the first parameter/value pairs we just extracted 00109 If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ 00110 op = strchr(newparam, ' ') ? "" : " ="; 00111 00112 snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s '%s'", table, newparam, op, 00113 newval); 00114 while ((newparam = va_arg(ap, const char *))) { 00115 newval = va_arg(ap, const char *); 00116 if (!strchr(newparam, ' ')) 00117 op = " ="; 00118 else 00119 op = ""; 00120 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s '%s'", newparam, 00121 op, newval); 00122 } 00123 va_end(ap); 00124 00125 /* We now have our complete statement; Lets connect to the server and execute it. */ 00126 ast_mutex_lock(&pgsql_lock); 00127 if (!pgsql_reconnect(database)) { 00128 ast_mutex_unlock(&pgsql_lock); 00129 return NULL; 00130 } 00131 00132 if (!(result = PQexec(pgsqlConn, sql))) { 00133 ast_log(LOG_WARNING, 00134 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00135 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00136 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n", 00137 PQerrorMessage(pgsqlConn)); 00138 ast_mutex_unlock(&pgsql_lock); 00139 return NULL; 00140 } else { 00141 ExecStatusType result_status = PQresultStatus(result); 00142 if (result_status != PGRES_COMMAND_OK 00143 && result_status != PGRES_TUPLES_OK 00144 && result_status != PGRES_NONFATAL_ERROR) { 00145 ast_log(LOG_WARNING, 00146 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00147 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00148 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n", 00149 PQresultErrorMessage(result), PQresStatus(result_status)); 00150 ast_mutex_unlock(&pgsql_lock); 00151 return NULL; 00152 } 00153 } 00154 00155 ast_log(LOG_DEBUG, "1Postgresql RealTime: Result=%p Query: %s\n", result, sql); 00156 00157 if ((num_rows = PQntuples(result)) > 0) { 00158 int i = 0; 00159 int rowIndex = 0; 00160 int numFields = PQnfields(result); 00161 char **fieldnames = NULL; 00162 00163 ast_log(LOG_DEBUG, "Postgresql RealTime: Found %d rows.\n", num_rows); 00164 00165 if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) { 00166 ast_mutex_unlock(&pgsql_lock); 00167 PQclear(result); 00168 return NULL; 00169 } 00170 for (i = 0; i < numFields; i++) 00171 fieldnames[i] = PQfname(result, i); 00172 for (rowIndex = 0; rowIndex < num_rows; rowIndex++) { 00173 for (i = 0; i < numFields; i++) { 00174 stringp = PQgetvalue(result, rowIndex, i); 00175 while (stringp) { 00176 chunk = strsep(&stringp, ";"); 00177 if (chunk && !ast_strlen_zero(ast_strip(chunk))) { 00178 if (prev) { 00179 prev->next = ast_variable_new(fieldnames[i], chunk); 00180 if (prev->next) { 00181 prev = prev->next; 00182 } 00183 } else { 00184 prev = var = ast_variable_new(fieldnames[i], chunk); 00185 } 00186 } 00187 } 00188 } 00189 } 00190 free(fieldnames); 00191 } else { 00192 ast_log(LOG_WARNING, 00193 "Postgresql RealTime: Could not find any rows in table %s.\n", table); 00194 } 00195 00196 ast_mutex_unlock(&pgsql_lock); 00197 PQclear(result); 00198 00199 return var; 00200 }
static int realtime_pgsql_status | ( | int | fd, | |
int | argc, | |||
char ** | argv | |||
) | [static] |
Definition at line 741 of file res_config_pgsql.c.
References ast_cli(), connect_time, dbhost, dbname, dbport, dbsock, dbuser, pgsqlConn, RESULT_FAILURE, and RESULT_SUCCESS.
00742 { 00743 char status[256], status2[100] = ""; 00744 int ctime = time(NULL) - connect_time; 00745 00746 if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) { 00747 if (dbhost) { 00748 snprintf(status, 255, "Connected to %s@%s, port %d", dbname, dbhost, dbport); 00749 } else if (dbsock) { 00750 snprintf(status, 255, "Connected to %s on socket file %s", dbname, dbsock); 00751 } else { 00752 snprintf(status, 255, "Connected to %s@%s", dbname, dbhost); 00753 } 00754 00755 if (dbuser && *dbuser) { 00756 snprintf(status2, 99, " with username %s", dbuser); 00757 } 00758 00759 if (ctime > 31536000) { 00760 ast_cli(fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", 00761 status, status2, ctime / 31536000, (ctime % 31536000) / 86400, 00762 (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60); 00763 } else if (ctime > 86400) { 00764 ast_cli(fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status, 00765 status2, ctime / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, 00766 ctime % 60); 00767 } else if (ctime > 3600) { 00768 ast_cli(fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2, 00769 ctime / 3600, (ctime % 3600) / 60, ctime % 60); 00770 } else if (ctime > 60) { 00771 ast_cli(fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60, 00772 ctime % 60); 00773 } else { 00774 ast_cli(fd, "%s%s for %d seconds.\n", status, status2, ctime); 00775 } 00776 00777 return RESULT_SUCCESS; 00778 } else { 00779 return RESULT_FAILURE; 00780 } 00781 }
static int reload | ( | void | ) | [static] |
Definition at line 593 of file res_config_pgsql.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), LOG_DEBUG, LOG_WARNING, parse_config(), pgsql_reconnect(), pgsqlConn, and VERBOSE_PREFIX_2.
00594 { 00595 /* Aquire control before doing anything to the module itself. */ 00596 ast_mutex_lock(&pgsql_lock); 00597 00598 if (pgsqlConn) { 00599 PQfinish(pgsqlConn); 00600 pgsqlConn = NULL; 00601 }; 00602 parse_config(); 00603 00604 if (!pgsql_reconnect(NULL)) { 00605 ast_log(LOG_WARNING, 00606 "Postgresql RealTime: Couldn't establish connection. Check debug.\n"); 00607 ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n", 00608 PQerrorMessage(pgsqlConn)); 00609 } 00610 00611 ast_verbose(VERBOSE_PREFIX_2 "Postgresql RealTime reloaded.\n"); 00612 00613 /* Done reloading. Release lock so others can now use driver. */ 00614 ast_mutex_unlock(&pgsql_lock); 00615 00616 return 0; 00617 }
static int unload_module | ( | void | ) | [static] |
Definition at line 570 of file res_config_pgsql.c.
References ast_cli_unregister_multiple(), ast_config_engine_deregister(), ast_module_user_hangup_all, ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), cli_realtime, option_verbose, pgsql_engine, and pgsqlConn.
00571 { 00572 /* Aquire control before doing anything to the module itself. */ 00573 ast_mutex_lock(&pgsql_lock); 00574 00575 if (pgsqlConn) { 00576 PQfinish(pgsqlConn); 00577 pgsqlConn = NULL; 00578 }; 00579 ast_cli_unregister_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry)); 00580 ast_config_engine_deregister(&pgsql_engine); 00581 if (option_verbose) { 00582 ast_verbose("Postgresql RealTime unloaded.\n"); 00583 } 00584 00585 ast_module_user_hangup_all(); 00586 00587 /* Unlock so something else can destroy the lock. */ 00588 ast_mutex_unlock(&pgsql_lock); 00589 00590 return 0; 00591 }
static int update_pgsql | ( | const char * | database, | |
const char * | table, | |||
const char * | keyfield, | |||
const char * | lookup, | |||
va_list | ap | |||
) | [static] |
Definition at line 350 of file res_config_pgsql.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_DEBUG, LOG_WARNING, pgsql_reconnect(), pgsqlConn, and result.
00352 { 00353 PGresult *result = NULL; 00354 int numrows = 0; 00355 char sql[256]; 00356 const char *newparam, *newval; 00357 00358 if (!table) { 00359 ast_log(LOG_WARNING, "Postgresql RealTime: No table specified.\n"); 00360 return -1; 00361 } 00362 00363 /* Get the first parameter and first value in our list of passed paramater/value pairs */ 00364 newparam = va_arg(ap, const char *); 00365 newval = va_arg(ap, const char *); 00366 if (!newparam || !newval) { 00367 ast_log(LOG_WARNING, 00368 "Postgresql RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n"); 00369 if (pgsqlConn) { 00370 PQfinish(pgsqlConn); 00371 pgsqlConn = NULL; 00372 }; 00373 return -1; 00374 } 00375 00376 /* Create the first part of the query using the first parameter/value pairs we just extracted 00377 If there is only 1 set, then we have our query. Otherwise, loop thru the list and concat */ 00378 00379 snprintf(sql, sizeof(sql), "UPDATE %s SET %s = '%s'", table, newparam, newval); 00380 while ((newparam = va_arg(ap, const char *))) { 00381 newval = va_arg(ap, const char *); 00382 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), ", %s = '%s'", newparam, 00383 newval); 00384 } 00385 va_end(ap); 00386 snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " WHERE %s = '%s'", keyfield, 00387 lookup); 00388 00389 ast_log(LOG_DEBUG, "Postgresql RealTime: Update SQL: %s\n", sql); 00390 00391 /* We now have our complete statement; Lets connect to the server and execute it. */ 00392 ast_mutex_lock(&pgsql_lock); 00393 if (!pgsql_reconnect(database)) { 00394 ast_mutex_unlock(&pgsql_lock); 00395 return -1; 00396 } 00397 00398 if (!(result = PQexec(pgsqlConn, sql))) { 00399 ast_log(LOG_WARNING, 00400 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00401 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00402 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n", 00403 PQerrorMessage(pgsqlConn)); 00404 ast_mutex_unlock(&pgsql_lock); 00405 return -1; 00406 } else { 00407 ExecStatusType result_status = PQresultStatus(result); 00408 if (result_status != PGRES_COMMAND_OK 00409 && result_status != PGRES_TUPLES_OK 00410 && result_status != PGRES_NONFATAL_ERROR) { 00411 ast_log(LOG_WARNING, 00412 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00413 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00414 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n", 00415 PQresultErrorMessage(result), PQresStatus(result_status)); 00416 ast_mutex_unlock(&pgsql_lock); 00417 return -1; 00418 } 00419 } 00420 00421 numrows = atoi(PQcmdTuples(result)); 00422 ast_mutex_unlock(&pgsql_lock); 00423 00424 ast_log(LOG_DEBUG, "Postgresql RealTime: Updated %d rows on table: %s\n", numrows, 00425 table); 00426 00427 /* From http://dev.pgsql.com/doc/pgsql/en/pgsql-affected-rows.html 00428 * An integer greater than zero indicates the number of rows affected 00429 * Zero indicates that no records were updated 00430 * -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.) 00431 */ 00432 00433 if (numrows >= 0) 00434 return (int) numrows; 00435 00436 return -1; 00437 }
struct ast_cli_entry cli_realtime[] [static] |
Initial value:
{ { { "realtime", "pgsql", "status", NULL }, realtime_pgsql_status, "Shows connection information for the Postgresql RealTime driver", cli_realtime_pgsql_status_usage }, }
Definition at line 73 of file res_config_pgsql.c.
char cli_realtime_pgsql_status_usage[] [static] |
Initial value:
"Usage: realtime pgsql status\n" " Shows connection information for the Postgresql RealTime driver\n"
Definition at line 69 of file res_config_pgsql.c.
time_t connect_time = 0 [static] |
Definition at line 63 of file res_config_pgsql.c.
char dbhost[MAX_DB_OPTION_SIZE] = "" [static] |
Definition at line 57 of file res_config_pgsql.c.
char dbname[MAX_DB_OPTION_SIZE] = "" [static] |
Definition at line 60 of file res_config_pgsql.c.
char dbpass[MAX_DB_OPTION_SIZE] = "" [static] |
Definition at line 59 of file res_config_pgsql.c.
int dbport = 5432 [static] |
Definition at line 62 of file res_config_pgsql.c.
char dbsock[MAX_DB_OPTION_SIZE] = "" [static] |
Definition at line 61 of file res_config_pgsql.c.
char dbuser[MAX_DB_OPTION_SIZE] = "" [static] |
Definition at line 58 of file res_config_pgsql.c.
struct ast_config_engine pgsql_engine [static] |
Definition at line 537 of file res_config_pgsql.c.
Referenced by load_module(), and unload_module().
PGconn* pgsqlConn = NULL |
Definition at line 53 of file res_config_pgsql.c.
Referenced by config_pgsql(), load_module(), pgsql_reconnect(), realtime_multi_pgsql(), realtime_pgsql_status(), reload(), unload_module(), and update_pgsql().