#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_calloc, 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 sql[250] = ""; 00448 char last[80] = ""; 00449 int last_cat_metric = 0; 00450 00451 last[0] = '\0'; 00452 00453 if (!file || !strcmp(file, RES_CONFIG_PGSQL_CONF)) { 00454 ast_log(LOG_WARNING, "Postgresql RealTime: Cannot configure myself.\n"); 00455 return NULL; 00456 } 00457 00458 snprintf(sql, sizeof(sql), 00459 "SELECT category, var_name, var_val, cat_metric FROM %s WHERE filename='%s' and commented=0 ORDER BY filename, cat_metric desc, var_metric asc, category, var_name, var_val, id", 00460 table, file); 00461 00462 ast_log(LOG_DEBUG, "Postgresql RealTime: Static SQL: %s\n", sql); 00463 00464 /* We now have our complete statement; Lets connect to the server and execute it. */ 00465 ast_mutex_lock(&pgsql_lock); 00466 if (!pgsql_reconnect(database)) { 00467 ast_mutex_unlock(&pgsql_lock); 00468 return NULL; 00469 } 00470 00471 if (!(result = PQexec(pgsqlConn, sql))) { 00472 ast_log(LOG_WARNING, 00473 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00474 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00475 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s\n", 00476 PQerrorMessage(pgsqlConn)); 00477 ast_mutex_unlock(&pgsql_lock); 00478 return NULL; 00479 } else { 00480 ExecStatusType result_status = PQresultStatus(result); 00481 if (result_status != PGRES_COMMAND_OK 00482 && result_status != PGRES_TUPLES_OK 00483 && result_status != PGRES_NONFATAL_ERROR) { 00484 ast_log(LOG_WARNING, 00485 "Postgresql RealTime: Failed to query database. Check debug for more info.\n"); 00486 ast_log(LOG_DEBUG, "Postgresql RealTime: Query: %s\n", sql); 00487 ast_log(LOG_DEBUG, "Postgresql RealTime: Query Failed because: %s (%s)\n", 00488 PQresultErrorMessage(result), PQresStatus(result_status)); 00489 ast_mutex_unlock(&pgsql_lock); 00490 return NULL; 00491 } 00492 } 00493 00494 if ((num_rows = PQntuples(result)) > 0) { 00495 int numFields = PQnfields(result); 00496 int i = 0; 00497 int rowIndex = 0; 00498 char **fieldnames = NULL; 00499 00500 ast_log(LOG_DEBUG, "Postgresql RealTime: Found %ld rows.\n", num_rows); 00501 00502 if (!(fieldnames = ast_calloc(1, numFields * sizeof(char *)))) { 00503 ast_mutex_unlock(&pgsql_lock); 00504 PQclear(result); 00505 return NULL; 00506 } 00507 for (i = 0; i < numFields; i++) 00508 fieldnames[i] = PQfname(result, i); 00509 00510 for (rowIndex = 0; rowIndex < num_rows; rowIndex++) { 00511 char *field_category = PQgetvalue(result, rowIndex, 0); 00512 char *field_var_name = PQgetvalue(result, rowIndex, 1); 00513 char *field_var_val = PQgetvalue(result, rowIndex, 2); 00514 char *field_cat_metric = PQgetvalue(result, rowIndex, 3); 00515 if (!strcmp(field_var_name, "#include")) { 00516 if (!ast_config_internal_load(field_var_val, cfg, 0)) { 00517 PQclear(result); 00518 ast_mutex_unlock(&pgsql_lock); 00519 return NULL; 00520 } 00521 continue; 00522 } 00523 00524 if (strcmp(last, field_category) || last_cat_metric != atoi(field_cat_metric)) { 00525 cur_cat = ast_category_new(field_category); 00526 if (!cur_cat) 00527 break; 00528 strcpy(last, field_category); 00529 last_cat_metric = atoi(field_cat_metric); 00530 ast_category_append(cfg, cur_cat); 00531 } 00532 new_v = ast_variable_new(field_var_name, field_var_val); 00533 ast_variable_append(cur_cat, new_v); 00534 } 00535 } else { 00536 ast_log(LOG_WARNING, 00537 "Postgresql RealTime: Could not find config '%s' in database.\n", file); 00538 } 00539 00540 PQclear(result); 00541 ast_mutex_unlock(&pgsql_lock); 00542 00543 return cfg; 00544 }
| static int load_module | ( | void | ) | [static] |
Definition at line 554 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.
00555 { 00556 if(!parse_config()) 00557 return AST_MODULE_LOAD_DECLINE; 00558 00559 ast_mutex_lock(&pgsql_lock); 00560 00561 if (!pgsql_reconnect(NULL)) { 00562 ast_log(LOG_WARNING, 00563 "Postgresql RealTime: Couldn't establish connection. Check debug.\n"); 00564 ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n", 00565 PQerrorMessage(pgsqlConn)); 00566 } 00567 00568 ast_config_engine_register(&pgsql_engine); 00569 if (option_verbose) { 00570 ast_verbose("Postgresql RealTime driver loaded.\n"); 00571 } 00572 ast_cli_register_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry)); 00573 00574 ast_mutex_unlock(&pgsql_lock); 00575 00576 return 0; 00577 }
| static int parse_config | ( | void | ) | [static] |
Definition at line 628 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.
00629 { 00630 struct ast_config *config; 00631 const char *s; 00632 00633 config = ast_config_load(RES_CONFIG_PGSQL_CONF); 00634 00635 if (!config) { 00636 ast_log(LOG_WARNING, "Unable to load config %s\n",RES_CONFIG_PGSQL_CONF); 00637 return 0; 00638 } 00639 if (!(s = ast_variable_retrieve(config, "general", "dbuser"))) { 00640 ast_log(LOG_WARNING, 00641 "Postgresql RealTime: No database user found, using 'asterisk' as default.\n"); 00642 strcpy(dbuser, "asterisk"); 00643 } else { 00644 ast_copy_string(dbuser, s, sizeof(dbuser)); 00645 } 00646 00647 if (!(s = ast_variable_retrieve(config, "general", "dbpass"))) { 00648 ast_log(LOG_WARNING, 00649 "Postgresql RealTime: No database password found, using 'asterisk' as default.\n"); 00650 strcpy(dbpass, "asterisk"); 00651 } else { 00652 ast_copy_string(dbpass, s, sizeof(dbpass)); 00653 } 00654 00655 if (!(s = ast_variable_retrieve(config, "general", "dbhost"))) { 00656 ast_log(LOG_WARNING, 00657 "Postgresql RealTime: No database host found, using localhost via socket.\n"); 00658 dbhost[0] = '\0'; 00659 } else { 00660 ast_copy_string(dbhost, s, sizeof(dbhost)); 00661 } 00662 00663 if (!(s = ast_variable_retrieve(config, "general", "dbname"))) { 00664 ast_log(LOG_WARNING, 00665 "Postgresql RealTime: No database name found, using 'asterisk' as default.\n"); 00666 strcpy(dbname, "asterisk"); 00667 } else { 00668 ast_copy_string(dbname, s, sizeof(dbname)); 00669 } 00670 00671 if (!(s = ast_variable_retrieve(config, "general", "dbport"))) { 00672 ast_log(LOG_WARNING, 00673 "Postgresql RealTime: No database port found, using 5432 as default.\n"); 00674 dbport = 5432; 00675 } else { 00676 dbport = atoi(s); 00677 } 00678 00679 if (dbhost && !(s = ast_variable_retrieve(config, "general", "dbsock"))) { 00680 ast_log(LOG_WARNING, 00681 "Postgresql RealTime: No database socket found, using '/tmp/pgsql.sock' as default.\n"); 00682 strcpy(dbsock, "/tmp/pgsql.sock"); 00683 } else { 00684 ast_copy_string(dbsock, s, sizeof(dbsock)); 00685 } 00686 ast_config_destroy(config); 00687 00688 if (dbhost) { 00689 ast_log(LOG_DEBUG, "Postgresql RealTime Host: %s\n", dbhost); 00690 ast_log(LOG_DEBUG, "Postgresql RealTime Port: %i\n", dbport); 00691 } else { 00692 ast_log(LOG_DEBUG, "Postgresql RealTime Socket: %s\n", dbsock); 00693 } 00694 ast_log(LOG_DEBUG, "Postgresql RealTime User: %s\n", dbuser); 00695 ast_log(LOG_DEBUG, "Postgresql RealTime Password: %s\n", dbpass); 00696 ast_log(LOG_DEBUG, "Postgresql RealTime DBName: %s\n", dbname); 00697 00698 return 1; 00699 }
| static int pgsql_reconnect | ( | const char * | database | ) | [static] |
Definition at line 701 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().
00702 { 00703 char my_database[50]; 00704 00705 ast_copy_string(my_database, S_OR(database, dbname), sizeof(my_database)); 00706 00707 /* mutex lock should have been locked before calling this function. */ 00708 00709 if (pgsqlConn && PQstatus(pgsqlConn) != CONNECTION_OK) { 00710 PQfinish(pgsqlConn); 00711 pgsqlConn = NULL; 00712 } 00713 00714 if ((!pgsqlConn) && (dbhost || dbsock) && dbuser && dbpass && my_database) { 00715 char *connInfo = NULL; 00716 unsigned int size = 100 + strlen(dbhost) 00717 + strlen(dbuser) 00718 + strlen(dbpass) 00719 + strlen(my_database); 00720 00721 if (!(connInfo = ast_malloc(size))) 00722 return 0; 00723 00724 sprintf(connInfo, "host=%s port=%d dbname=%s user=%s password=%s", 00725 dbhost, dbport, my_database, dbuser, dbpass); 00726 ast_log(LOG_DEBUG, "%u connInfo=%s\n", size, connInfo); 00727 pgsqlConn = PQconnectdb(connInfo); 00728 ast_log(LOG_DEBUG, "%u connInfo=%s\n", size, connInfo); 00729 free(connInfo); 00730 connInfo = NULL; 00731 ast_log(LOG_DEBUG, "pgsqlConn=%p\n", pgsqlConn); 00732 if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) { 00733 ast_log(LOG_DEBUG, "Postgresql RealTime: Successfully connected to database.\n"); 00734 connect_time = time(NULL); 00735 return 1; 00736 } else { 00737 ast_log(LOG_ERROR, 00738 "Postgresql RealTime: Failed to connect database server %s on %s. Check debug for more info.\n", 00739 dbname, dbhost); 00740 ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n", 00741 PQresultErrorMessage(NULL)); 00742 return 0; 00743 } 00744 } else { 00745 ast_log(LOG_DEBUG, "Postgresql RealTime: Everything is fine.\n"); 00746 return 1; 00747 } 00748 }
| 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 750 of file res_config_pgsql.c.
References ast_cli(), connect_time, dbhost, dbname, dbport, dbsock, dbuser, pgsqlConn, RESULT_FAILURE, and RESULT_SUCCESS.
00751 { 00752 char status[256], status2[100] = ""; 00753 int ctime = time(NULL) - connect_time; 00754 00755 if (pgsqlConn && PQstatus(pgsqlConn) == CONNECTION_OK) { 00756 if (dbhost) { 00757 snprintf(status, 255, "Connected to %s@%s, port %d", dbname, dbhost, dbport); 00758 } else if (dbsock) { 00759 snprintf(status, 255, "Connected to %s on socket file %s", dbname, dbsock); 00760 } else { 00761 snprintf(status, 255, "Connected to %s@%s", dbname, dbhost); 00762 } 00763 00764 if (dbuser && *dbuser) { 00765 snprintf(status2, 99, " with username %s", dbuser); 00766 } 00767 00768 if (ctime > 31536000) { 00769 ast_cli(fd, "%s%s for %d years, %d days, %d hours, %d minutes, %d seconds.\n", 00770 status, status2, ctime / 31536000, (ctime % 31536000) / 86400, 00771 (ctime % 86400) / 3600, (ctime % 3600) / 60, ctime % 60); 00772 } else if (ctime > 86400) { 00773 ast_cli(fd, "%s%s for %d days, %d hours, %d minutes, %d seconds.\n", status, 00774 status2, ctime / 86400, (ctime % 86400) / 3600, (ctime % 3600) / 60, 00775 ctime % 60); 00776 } else if (ctime > 3600) { 00777 ast_cli(fd, "%s%s for %d hours, %d minutes, %d seconds.\n", status, status2, 00778 ctime / 3600, (ctime % 3600) / 60, ctime % 60); 00779 } else if (ctime > 60) { 00780 ast_cli(fd, "%s%s for %d minutes, %d seconds.\n", status, status2, ctime / 60, 00781 ctime % 60); 00782 } else { 00783 ast_cli(fd, "%s%s for %d seconds.\n", status, status2, ctime); 00784 } 00785 00786 return RESULT_SUCCESS; 00787 } else { 00788 return RESULT_FAILURE; 00789 } 00790 }
| static int reload | ( | void | ) | [static] |
Definition at line 602 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.
00603 { 00604 /* Aquire control before doing anything to the module itself. */ 00605 ast_mutex_lock(&pgsql_lock); 00606 00607 if (pgsqlConn) { 00608 PQfinish(pgsqlConn); 00609 pgsqlConn = NULL; 00610 }; 00611 parse_config(); 00612 00613 if (!pgsql_reconnect(NULL)) { 00614 ast_log(LOG_WARNING, 00615 "Postgresql RealTime: Couldn't establish connection. Check debug.\n"); 00616 ast_log(LOG_DEBUG, "Postgresql RealTime: Cannot Connect: %s\n", 00617 PQerrorMessage(pgsqlConn)); 00618 } 00619 00620 ast_verbose(VERBOSE_PREFIX_2 "Postgresql RealTime reloaded.\n"); 00621 00622 /* Done reloading. Release lock so others can now use driver. */ 00623 ast_mutex_unlock(&pgsql_lock); 00624 00625 return 0; 00626 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 579 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.
00580 { 00581 /* Aquire control before doing anything to the module itself. */ 00582 ast_mutex_lock(&pgsql_lock); 00583 00584 if (pgsqlConn) { 00585 PQfinish(pgsqlConn); 00586 pgsqlConn = NULL; 00587 }; 00588 ast_cli_unregister_multiple(cli_realtime, sizeof(cli_realtime) / sizeof(struct ast_cli_entry)); 00589 ast_config_engine_deregister(&pgsql_engine); 00590 if (option_verbose) { 00591 ast_verbose("Postgresql RealTime unloaded.\n"); 00592 } 00593 00594 ast_module_user_hangup_all(); 00595 00596 /* Unlock so something else can destroy the lock. */ 00597 ast_mutex_unlock(&pgsql_lock); 00598 00599 return 0; 00600 }
| 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 546 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().
1.5.1