Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Macros | Enumerations | Functions | Variables
res_config_pgsql.c File Reference

PostgreSQL plugin for Asterisk RealTime Architecture. More...

#include "asterisk.h"
#include <libpq-fe.h>
#include "asterisk/file.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"

Go to the source code of this file.

Data Structures

struct  columns
 
struct  tables::psql_columns
 
struct  psql_tables
 
struct  tables
 

Macros

#define ESCAPE_CLAUSE   (USE_BACKSLASH_AS_STRING ? " ESCAPE '\\'" : " ESCAPE '\\\\'")
 
#define ESCAPE_STRING(buffer, stringname)
 
#define has_schema_support   (version > 70300 ? 1 : 0)
 
#define IS_SQL_LIKE_CLAUSE(x)   ((x) && ast_ends_with(x, " LIKE"))
 
#define MAX_DB_OPTION_SIZE   64
 
#define release_table(table)   ast_rwlock_unlock(&(table)->lock);
 
#define RES_CONFIG_PGSQL_CONF   "res_pgsql.conf"
 
#define USE_BACKSLASH_AS_STRING   (version >= 90100 ? 1 : 0)
 

Enumerations

enum  { RQ_WARN, RQ_CREATECLOSE, RQ_CREATECHAR }
 

Functions

static void __init_escapebuf_buf (void)
 
static void __init_findtable_buf (void)
 
static void __init_semibuf_buf (void)
 
static void __init_sql_buf (void)
 
static void __init_where_buf (void)
 
static void __reg_module (void)
 
static void __unreg_module (void)
 
static int _pgsql_exec (const char *database, const char *tablename, const char *sql, PGresult **result)
 Helper function for pgsql_exec. For running queries, use pgsql_exec() More...
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct ast_configconfig_pgsql (const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl, const char *who_asked)
 
static int destroy_pgsql (const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *fields)
 
static void destroy_table (struct tables *table)
 
static struct columnsfind_column (struct tables *t, const char *colname)
 
static struct tablesfind_table (const char *database, const char *orig_tablename)
 
static char * handle_cli_realtime_pgsql_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_realtime_pgsql_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int load_module (void)
 
static int parse_config (int reload)
 
static int pgsql_exec (const char *database, const char *tablename, const char *sql, PGresult **result)
 Do a postgres query, with reconnection support. More...
 
static int pgsql_reconnect (const char *database)
 
static struct ast_configrealtime_multi_pgsql (const char *database, const char *table, const struct ast_variable *fields)
 
static struct ast_variablerealtime_pgsql (const char *database, const char *tablename, const struct ast_variable *fields)
 
static int reload (void)
 
static int require_pgsql (const char *database, const char *tablename, va_list ap)
 
static int store_pgsql (const char *database, const char *table, const struct ast_variable *fields)
 
static int unload_module (void)
 
static int unload_pgsql (const char *database, const char *tablename)
 
static int update2_pgsql (const char *database, const char *tablename, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
 
static int update_pgsql (const char *database, const char *tablename, const char *keyfield, const char *lookup, const struct ast_variable *fields)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PostgreSQL RealTime Configuration Driver" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "da6642af068ee5e6490c5b1d2cc1d238" , .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_REALTIME_DRIVER, .requires = "extconfig", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_realtime []
 
static time_t connect_time = 0
 
static char dbappname [MAX_DB_OPTION_SIZE] = ""
 
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_threadstorage escapebuf_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_escapebuf_buf , .custom_init = NULL , }
 
static struct ast_threadstorage findtable_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_findtable_buf , .custom_init = NULL , }
 
static int order_multi_row_results_by_initial_column = 1
 
static struct ast_config_engine pgsql_engine
 
static ast_mutex_t pgsql_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
static PGconn * pgsqlConn = NULL
 
static struct psql_tables psql_tables = { .first = NULL, .last = NULL, .lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} } , }
 
static enum { ... }  requirements
 
static struct ast_threadstorage semibuf_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_semibuf_buf , .custom_init = NULL , }
 
static struct ast_threadstorage sql_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_sql_buf , .custom_init = NULL , }
 
static int version
 
static struct ast_threadstorage where_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_where_buf , .custom_init = NULL , }
 

Detailed Description

PostgreSQL plugin for Asterisk RealTime Architecture.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Manuel Guesdon mgues.nosp@m.don@.nosp@m.oxymi.nosp@m.um.n.nosp@m.et - PostgreSQL RealTime Driver Author/Adaptor

PostgreSQL http://www.postgresql.org

Definition in file res_config_pgsql.c.

Function Documentation

static int _pgsql_exec ( const char *  database,
const char *  tablename,
const char *  sql,
PGresult **  result 
)
static

Helper function for pgsql_exec. For running queries, use pgsql_exec()

Connect if not currently connected. Run the given query.

Parameters
databasedatabase name we are connected to (used for error logging)
tablenametable name we are connected to (used for error logging)
sqlsql query string to execute
resultpointer for where to store the result handle
Returns
-1 on fatal query error
-2 on query failure that resulted in disconnection
0 on success
Note
see pgsql_exec for full example

Definition at line 145 of file res_config_pgsql.c.

References ast_debug.

Referenced by pgsql_exec().

146 {
147  ExecStatusType result_status;
148 
149  if (!pgsqlConn) {
150  ast_debug(1, "PostgreSQL connection not defined, connecting\n");
151 
152  if (pgsql_reconnect(database) != 1) {
153  ast_log(LOG_NOTICE, "reconnect failed\n");
154  *result = NULL;
155  return -1;
156  }
157 
158  ast_debug(1, "PostgreSQL connection successful\n");
159  }
160 
161  *result = PQexec(pgsqlConn, sql);
162  result_status = PQresultStatus(*result);
163  if (result_status != PGRES_COMMAND_OK
164  && result_status != PGRES_TUPLES_OK
165  && result_status != PGRES_NONFATAL_ERROR) {
166 
167  ast_log(LOG_ERROR, "PostgreSQL RealTime: Failed to query '%s@%s'.\n", tablename, database);
168  ast_log(LOG_ERROR, "PostgreSQL RealTime: Query Failed: %s\n", sql);
169  ast_log(LOG_ERROR, "PostgreSQL RealTime: Query Failed because: %s (%s)\n",
170  PQresultErrorMessage(*result),
171  PQresStatus(result_status));
172 
173  /* we may have tried to run a command on a disconnected/disconnecting handle */
174  /* are we no longer connected to the database... if not try again */
175  if (PQstatus(pgsqlConn) != CONNECTION_OK) {
176  PQfinish(pgsqlConn);
177  pgsqlConn = NULL;
178  return -2;
179  }
180 
181  /* connection still okay, which means the query is just plain bad */
182  return -1;
183  }
184 
185  ast_debug(1, "PostgreSQL query successful: %s\n", sql);
186  return 0;
187 }
#define ast_debug(level,...)
Log a DEBUG message.
static int pgsql_exec ( const char *  database,
const char *  tablename,
const char *  sql,
PGresult **  result 
)
static

Do a postgres query, with reconnection support.

Connect if not currently connected. Run the given query and if we're disconnected afterwards, reconnect and query again.

Parameters
databasedatabase name we are connected to (used for error logging)
tablenametable name we are connected to (used for error logging)
sqlsql query string to execute
resultpointer for where to store the result handle
Returns
-1 on query failure
0 on success
1 int i, rows;
2 PGresult *result;
3 char *field_name, *field_type, *field_len, *field_notnull, *field_default;
4 
5 pgsql_exec("db", "table", "SELECT 1", &result)
6 
7 rows = PQntuples(result);
8 for (i = 0; i < rows; i++) {
9  field_name = PQgetvalue(result, i, 0);
10  field_type = PQgetvalue(result, i, 1);
11  field_len = PQgetvalue(result, i, 2);
12  field_notnull = PQgetvalue(result, i, 3);
13  field_default = PQgetvalue(result, i, 4);
14 }

Definition at line 219 of file res_config_pgsql.c.

References _pgsql_exec(), and ast_debug.

220 {
221  int attempts = 0;
222  int res;
223 
224  /* Try the query, note failure if any */
225  /* On first failure, reconnect and try again (_pgsql_exec handles reconnect) */
226  /* On second failure, treat as fatal query error */
227 
228  while (attempts++ < 2) {
229  ast_debug(1, "PostgreSQL query attempt %d\n", attempts);
230  res = _pgsql_exec(database, tablename, sql, result);
231 
232  if (res == 0) {
233  if (attempts > 1) {
234  ast_log(LOG_NOTICE, "PostgreSQL RealTime: Query finally succeeded: %s\n", sql);
235  }
236 
237  return 0;
238  }
239 
240  if (res == -1) {
241  return -1; /* Still connected to db, but could not process query (fatal error) */
242  }
243 
244  /* res == -2 (query on a disconnected handle) */
245  ast_debug(1, "PostgreSQL query attempt %d failed, trying again\n", attempts);
246  }
247 
248  return -1;
249 }
static int _pgsql_exec(const char *database, const char *tablename, const char *sql, PGresult **result)
Helper function for pgsql_exec. For running queries, use pgsql_exec()
#define ast_debug(level,...)
Log a DEBUG message.

Variable Documentation

struct ast_cli_entry cli_realtime[]
static
Initial value:
= {
{ .handler = handle_cli_realtime_pgsql_status , .summary = "Shows connection information for the PostgreSQL RealTime driver" ,},
{ .handler = handle_cli_realtime_pgsql_cache , .summary = "Shows cached tables within the PostgreSQL realtime driver" ,},
}

Definition at line 94 of file res_config_pgsql.c.