50#define RES_CONFIG_PGSQL_CONF "res_pgsql.conf"
54#define has_schema_support (version > 70300 ? 1 : 0)
55#define USE_BACKSLASH_AS_STRING (version >= 90100 ? 1 : 0)
57#define MAX_DB_OPTION_SIZE 64
99#define ESCAPE_STRING(buffer, stringname) \
101 int len = strlen(stringname); \
102 struct ast_str *semi = ast_str_thread_get(&semibuf_buf, len * 3 + 1); \
103 const char *chunk = stringname; \
104 ast_str_reset(semi); \
105 for (; *chunk; chunk++) { \
106 if (strchr(";^", *chunk)) { \
107 ast_str_append(&semi, 0, "^%02hhX", *chunk); \
109 ast_str_append(&semi, 0, "%c", *chunk); \
112 if (ast_str_strlen(semi) > (ast_str_size(buffer) - 1) / 2) { \
113 ast_str_make_space(&buffer, ast_str_strlen(semi) * 2 + 1); \
115 PQescapeStringConn(pgsqlConn, ast_str_buffer(buffer), ast_str_buffer(semi), ast_str_size(buffer), &pgresult); \
145static int _pgsql_exec(
const char *database,
const char *tablename,
const char *sql, PGresult **
result)
147 ExecStatusType result_status;
150 ast_debug(1,
"PostgreSQL connection not defined, connecting\n");
158 ast_debug(1,
"PostgreSQL connection successful\n");
162 result_status = PQresultStatus(*
result);
163 if (result_status != PGRES_COMMAND_OK
164 && result_status != PGRES_TUPLES_OK
165 && result_status != PGRES_NONFATAL_ERROR) {
167 ast_log(
LOG_ERROR,
"PostgreSQL RealTime: Failed to query '%s@%s'.\n", tablename, database);
170 PQresultErrorMessage(*
result),
171 PQresStatus(result_status));
175 if (PQstatus(
pgsqlConn) != CONNECTION_OK) {
185 ast_debug(1,
"PostgreSQL query successful: %s\n", sql);
219static int pgsql_exec(
const char *database,
const char *tablename,
const char *sql, PGresult **
result)
228 while (attempts++ < 2) {
229 ast_debug(1,
"PostgreSQL query attempt %d\n", attempts);
245 ast_debug(1,
"PostgreSQL query attempt %d failed, trying again\n", attempts);
258 char *fname, *ftype, *flen, *fnotnull, *fdef;
263 if (!strcasecmp(
table->name, orig_tablename)) {
264 ast_debug(1,
"Found table in cache; now locking\n");
266 ast_debug(1,
"Lock cached table; now returning\n");
272 if (database ==
NULL) {
277 ast_debug(1,
"Table '%s' not found in cache, querying now\n", orig_tablename);
281 char *schemaname, *tablename, *tmp_schemaname, *tmp_tablename;
282 if (strchr(orig_tablename,
'.')) {
284 tmp_tablename = strchr(tmp_schemaname,
'.');
285 *tmp_tablename++ =
'\0';
291 tablename =
ast_alloca(strlen(tmp_tablename) * 2 + 1);
292 PQescapeStringConn(
pgsqlConn, tablename, tmp_tablename, strlen(tmp_tablename),
NULL);
293 schemaname =
ast_alloca(strlen(tmp_schemaname) * 2 + 1);
294 PQescapeStringConn(
pgsqlConn, schemaname, tmp_schemaname, strlen(tmp_schemaname),
NULL);
296 ast_str_set(&sql, 0,
"SELECT a.attname, t.typname, a.attlen, a.attnotnull, pg_catalog.pg_get_expr(d.adbin, d.adrelid) adsrc, a.atttypmod FROM (((pg_catalog.pg_class c INNER JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace AND c.relname = '%s' AND n.nspname = %s%s%s) INNER JOIN pg_catalog.pg_attribute a ON (NOT a.attisdropped) AND a.attnum > 0 AND a.attrelid = c.oid) INNER JOIN pg_catalog.pg_type t ON t.oid = a.atttypid) LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum ORDER BY n.nspname, c.relname, attnum",
301 tablename =
ast_alloca(strlen(orig_tablename) * 2 + 1);
302 PQescapeStringConn(
pgsqlConn, tablename, orig_tablename, strlen(orig_tablename),
NULL);
304 ast_str_set(&sql, 0,
"SELECT a.attname, t.typname, a.attlen, a.attnotnull, d.adsrc, a.atttypmod FROM pg_class c, pg_type t, pg_attribute a LEFT OUTER JOIN pg_attrdef d ON a.atthasdef AND d.adrelid = a.attrelid AND d.adnum = a.attnum WHERE c.oid = a.attrelid AND a.atttypid = t.oid AND (a.attnum > 0) AND c.relname = '%s' ORDER BY c.relname, attnum", tablename);
310 ast_debug(1,
"Query of table structure complete. Now retrieving results.\n");
311 if (exec_result != 0) {
312 ast_log(
LOG_ERROR,
"Failed to query database columns for table %s\n", orig_tablename);
322 strcpy(
table->name, orig_tablename);
327 for (i = 0; i < rows; i++) {
328 fname = PQgetvalue(
result, i, 0);
329 ftype = PQgetvalue(
result, i, 1);
330 flen = PQgetvalue(
result, i, 2);
331 fnotnull = PQgetvalue(
result, i, 3);
332 fdef = PQgetvalue(
result, i, 4);
333 ast_verb(4,
"Found column '%s' of type '%s'\n", fname, ftype);
335 if (!(column =
ast_calloc(1,
sizeof(*column) + strlen(fname) + strlen(ftype) + 2))) {
336 ast_log(
LOG_ERROR,
"Unable to allocate column element for %s, %s\n", orig_tablename, fname);
342 if (strcmp(flen,
"-1") == 0) {
344 flen = PQgetvalue(
result, i, 5);
345 sscanf(flen,
"%30d", &column->
len);
348 sscanf(flen,
"%30d", &column->
len);
350 column->
name = (
char *)column +
sizeof(*column);
351 column->
type = (
char *)column +
sizeof(*column) + strlen(fname) + 1;
352 strcpy(column->
name, fname);
353 strcpy(column->
type, ftype);
354 if (*fnotnull ==
't') {
373#define release_table(table) ast_rwlock_unlock(&(table)->lock);
381 if (strcmp(column->
name, colname) == 0) {
388#define IS_SQL_LIKE_CLAUSE(x) ((x) && ast_ends_with(x, " LIKE"))
389#define ESCAPE_CLAUSE (USE_BACKSLASH_AS_STRING ? " ESCAPE '\\'" : " ESCAPE '\\\\'")
428 "PostgreSQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
439 if (!strchr(field->
name,
' ')) {
456 while ((field = field->
next)) {
458 if (!strchr(field->
name,
' ')) {
486 if (PQntuples(
result) > 0) {
488 int numFields = PQnfields(
result);
489 char **fieldnames =
NULL;
491 ast_debug(1,
"PostgreSQL RealTime: Found a row.\n");
493 if (!(fieldnames =
ast_calloc(1, numFields *
sizeof(
char *)))) {
497 for (i = 0; i < numFields; i++)
498 fieldnames[i] = PQfname(
result, i);
499 for (i = 0; i < numFields; i++) {
500 stringp = PQgetvalue(
result, 0, i);
502 chunk =
strsep(&stringp,
";");
517 ast_debug(1,
"Postgresql RealTime: Could not find any rows in table %s@%s.\n", tablename, database);
528 int num_rows = 0, pgresult;
532 const char *initfield =
NULL;
568 "PostgreSQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
579 if ((op = strchr(initfield,
' '))) {
586 if (!strchr(field->
name,
' ')) {
605 while ((field = field->
next)) {
607 if (!strchr(field->
name,
' ')) {
638 ExecStatusType result_status = PQresultStatus(
result);
639 if (result_status != PGRES_COMMAND_OK
640 && result_status != PGRES_TUPLES_OK
641 && result_status != PGRES_NONFATAL_ERROR) {
643 "PostgreSQL RealTime: Failed to query %s@%s. Check debug for more info.\n",
table, database);
645 ast_debug(1,
"PostgreSQL RealTime: Query Failed because: %s (%s)\n",
646 PQresultErrorMessage(
result), PQresStatus(result_status));
655 if ((num_rows = PQntuples(
result)) > 0) {
656 int numFields = PQnfields(
result);
659 char **fieldnames =
NULL;
661 ast_debug(1,
"PostgreSQL RealTime: Found %d rows.\n", num_rows);
663 if (!(fieldnames =
ast_calloc(1, numFields *
sizeof(
char *)))) {
668 for (i = 0; i < numFields; i++)
669 fieldnames[i] = PQfname(
result, i);
671 for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
677 for (i = 0; i < numFields; i++) {
678 stringp = PQgetvalue(
result, rowIndex, i);
680 chunk =
strsep(&stringp,
";");
682 if (initfield && !strcmp(initfield, fieldnames[i])) {
694 ast_debug(1,
"PostgreSQL RealTime: Could not find any rows in table %s.\n",
table);
702static int update_pgsql(
const char *database,
const char *tablename,
const char *keyfield,
706 int numrows = 0, pgresult;
743 "PostgreSQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
755 if (strcmp(column->
name, field->
name) == 0) {
761 ast_log(
LOG_ERROR,
"PostgreSQL RealTime: Updating on column '%s', but that column does not exist within the table '%s'!\n", field->
name, tablename);
779 while ((field = field->
next)) {
781 ast_log(
LOG_NOTICE,
"Attempted to update column '%s' in table '%s', but column does not exist!\n", field->
name, tablename);
799 ast_log(
LOG_ERROR,
"PostgreSQL RealTime: detected invalid input: '%s'\n", lookup);
813 ExecStatusType result_status = PQresultStatus(
result);
814 if (result_status != PGRES_COMMAND_OK
815 && result_status != PGRES_TUPLES_OK
816 && result_status != PGRES_NONFATAL_ERROR) {
818 "PostgreSQL RealTime: Failed to query database. Check debug for more info.\n");
820 ast_debug(1,
"PostgreSQL RealTime: Query Failed because: %s (%s)\n",
821 PQresultErrorMessage(
result), PQresStatus(result_status));
827 numrows = atoi(PQcmdTuples(
result));
830 ast_debug(1,
"PostgreSQL RealTime: Updated %d rows on table: %s\n", numrows, tablename);
839 return (
int) numrows;
847 int numrows = 0, pgresult,
first = 1;
865 if (!escapebuf || !sql || !where) {
889 for (field = lookup_fields; field; field = field->
next) {
891 ast_log(
LOG_ERROR,
"Attempted to update based on criteria column '%s' (%s@%s), but that column does not exist!\n", field->
name, tablename,
database);
910 "PostgreSQL RealTime: Realtime update requires at least 1 parameter and 1 value to search on.\n");
922 for (field = update_fields; field; field = field->
next) {
952 numrows = atoi(PQcmdTuples(
result));
955 ast_debug(1,
"PostgreSQL RealTime: Updated %d rows on table: %s\n", numrows, tablename);
964 return (
int) numrows;
1004 "PostgreSQL RealTime: Realtime storage requires at least 1 parameter and 1 value to store.\n");
1019 while ((field = field->
next)) {
1035 numrows = atoi(PQcmdTuples(
result));
1038 ast_debug(1,
"PostgreSQL RealTime: row inserted on table: %s.\n",
table);
1086 "PostgreSQL RealTime: Realtime destroy requires at least 1 parameter and 1 value to search on.\n");
1101 for (field = fields; field; field = field->
next) {
1115 numrows = atoi(PQcmdTuples(
result));
1118 ast_debug(1,
"PostgreSQL RealTime: Deleted %d rows on table: %s\n", numrows,
table);
1127 return (
int) numrows;
1135 struct ast_flags flags,
const char *suggested_incl,
const char *who_asked)
1143 int last_cat_metric = 0;
1158 ast_str_set(&sql, 0,
"SELECT category, var_name, var_val, cat_metric FROM %s "
1159 "WHERE filename='%s' and commented=0 "
1160 "ORDER BY cat_metric DESC, var_metric ASC, category, var_name ",
table,
file);
1172 if ((num_rows = PQntuples(
result)) > 0) {
1175 ast_debug(1,
"PostgreSQL RealTime: Found %ld rows.\n", num_rows);
1177 for (rowIndex = 0; rowIndex < num_rows; rowIndex++) {
1178 char *field_category = PQgetvalue(
result, rowIndex, 0);
1179 char *field_var_name = PQgetvalue(
result, rowIndex, 1);
1180 char *field_var_val = PQgetvalue(
result, rowIndex, 2);
1181 char *field_cat_metric = PQgetvalue(
result, rowIndex, 3);
1182 if (!strcmp(field_var_name,
"#include")) {
1190 if (strcmp(
last, field_category) || last_cat_metric != atoi(field_cat_metric)) {
1196 last_cat_metric = atoi(field_cat_metric);
1204 "PostgreSQL RealTime: Could not find config '%s' in database.\n",
file);
1212static int require_pgsql(
const char *database,
const char *tablename, va_list ap)
1228 ast_log(
LOG_WARNING,
"Table %s not found in database. This table should exist if you're using realtime.\n", tablename);
1232 while ((elm = va_arg(ap,
char *))) {
1234 size = va_arg(ap,
unsigned int);
1236 if (strcmp(column->
name, elm) == 0) {
1238 if ((strncmp(column->
type,
"char", 4) == 0 || strncmp(column->
type,
"varchar", 7) == 0 || strcmp(column->
type,
"bpchar") == 0 || strncmp(column->
type,
"text", 4) == 0)) {
1239 if (column->
len != -1 && (size > column->
len)) {
1240 ast_log(
LOG_WARNING,
"Column '%s' should be at least %d long, but is only %d long.\n", column->
name, size, column->
len);
1243 }
else if (strncmp(column->
type,
"int", 3) == 0) {
1244 int typesize = atoi(column->
type + 3);
1250 ast_log(
LOG_WARNING,
"Column '%s' may not be large enough for the required data length: %d\n", column->
name, size);
1254 ast_log(
LOG_WARNING,
"Column '%s' may not be large enough for the required data length: %d\n", column->
name, size);
1257 ast_log(
LOG_WARNING,
"Column '%s' is of the incorrect type: (need %s(%d) but saw %s)\n",
1263 "a rather stiff drink ",
1264 size, column->
type);
1267 }
else if (strncmp(column->
type,
"float", 5) == 0) {
1272 }
else if (strncmp(column->
type,
"timestamp", 9) == 0) {
1287 ast_log(
LOG_WARNING,
"Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
1298 snprintf(fieldtype,
sizeof(fieldtype),
"CHAR(%u)",
1299 size < 15 ? size * 2 :
1300 (size * 3 / 2 > 255) ? 255 : size * 3 / 2);
1302 snprintf(fieldtype,
sizeof(fieldtype),
"INT2");
1304 snprintf(fieldtype,
sizeof(fieldtype),
"INT4");
1306 snprintf(fieldtype,
sizeof(fieldtype),
"INT8");
1309 snprintf(fieldtype,
sizeof(fieldtype),
"CHAR(20)");
1311 snprintf(fieldtype,
sizeof(fieldtype),
"FLOAT8");
1313 snprintf(fieldtype,
sizeof(fieldtype),
"DATE");
1315 snprintf(fieldtype,
sizeof(fieldtype),
"TIMESTAMP");
1321 ast_str_set(&sql, 0,
"ALTER TABLE %s ADD COLUMN %s %s", tablename, elm, fieldtype);
1322 ast_debug(1,
"About to lock pgsql_lock (running alter on table '%s' to add column '%s')\n", tablename, elm);
1325 ast_debug(1,
"About to run ALTER query on table '%s' to add column '%s'\n", tablename, elm);
1333 ast_debug(1,
"Finished running ALTER query on table '%s'\n", tablename);
1334 if (PQresultStatus(
result) != PGRES_COMMAND_OK) {
1358 ast_debug(2,
"About to lock table cache list\n");
1360 ast_debug(2,
"About to traverse table cache list\n");
1362 if (strcmp(cur->
name, tablename) == 0) {
1363 ast_debug(2,
"About to remove matching cache entry\n");
1365 ast_debug(2,
"About to destroy matching cache entry\n");
1374 return cur ? 0 : -1;
1464 "PostgreSQL RealTime: No database user found, using 'asterisk' as default.\n");
1465 strcpy(
dbuser,
"asterisk");
1472 "PostgreSQL RealTime: No database password found, using 'asterisk' as default.\n");
1473 strcpy(
dbpass,
"asterisk");
1480 "PostgreSQL RealTime: No database host found, using localhost via socket.\n");
1488 "PostgreSQL RealTime: No database name found, using 'asterisk' as default.\n");
1489 strcpy(
dbname,
"asterisk");
1496 "PostgreSQL RealTime: No database port found, using 5432 as default.\n");
1512 "PostgreSQL RealTime: No database socket found, using '/tmp/.s.PGSQL.%d' as default.\n",
dbport);
1520 "PostgreSQL RealTime: no requirements setting found, using 'warn' as default.\n");
1522 }
else if (!strcasecmp(s,
"createclose")) {
1524 }
else if (!strcasecmp(s,
"createchar")) {
1548 "PostgreSQL RealTime: Couldn't establish connection. Check debug.\n");
1549 ast_debug(1,
"PostgreSQL RealTime: Cannot Connect: %s\n", PQerrorMessage(
pgsqlConn));
1552 ast_verb(2,
"PostgreSQL RealTime reloaded.\n");
1562 char my_database[50];
1569 if (PQstatus(
pgsqlConn) == CONNECTION_OK) {
1583 ast_log(
LOG_ERROR,
"PostgreSQL RealTime: Failed to allocate memory for connection string.\n");
1587 ast_str_set(&conn_info, 0,
"host=%s port=%d dbname=%s user=%s",
1604 ast_debug(1,
"PostgreSQL RealTime: Successfully connected to database.\n");
1610 "PostgreSQL RealTime: Failed to connect database %s on %s: %s\n",
1611 my_database,
dbhost, PQresultErrorMessage(
NULL));
1615 ast_debug(1,
"PostgreSQL RealTime: One or more of the parameters in the config does not pass our validity checks.\n");
1628 e->
command =
"realtime show pgsql cache";
1630 "Usage: realtime show pgsql cache [<table>]\n"
1631 " Shows table cache for the PostgreSQL RealTime driver\n";
1637 l = strlen(
a->word);
1641 if (!strncasecmp(
a->word, cur->
name, l) && ++which >
a->n) {
1657 }
else if (
a->argc == 5) {
1661 ast_cli(
a->fd,
"Columns for Table Cache '%s':\n",
a->argv[4]);
1662 ast_cli(
a->fd,
"%-20.20s %-20.20s %-3.3s %-8.8s\n",
"Name",
"Type",
"Len",
"Nullable");
1668 ast_cli(
a->fd,
"No such table '%s'\n",
a->argv[4]);
1676 char connection_info[256];
1677 char credentials[100] =
"";
1683 e->
command =
"realtime show pgsql status";
1685 "Usage: realtime show pgsql status\n"
1686 " Shows connection information for the PostgreSQL RealTime driver\n";
1696 snprintf(connection_info,
sizeof(connection_info),
"%s@%s, port %d",
dbname,
dbhost,
dbport);
1698 snprintf(connection_info,
sizeof(connection_info),
"%s on socket file %s",
dbname,
dbsock);
1700 snprintf(connection_info,
sizeof(connection_info),
"%s@%s",
dbname,
dbhost);
1703 snprintf(credentials,
sizeof(credentials),
" with username %s",
dbuser);
1710 snprintf(
buf,
sizeof(
buf),
"Connected to %s%s for ", connection_info, credentials);
1714 ast_cli(
a->fd,
"Unable to connect %s%s\n", connection_info, credentials);
1726 .
requires =
"extconfig",
struct sla_ringing_trunk * first
struct sla_ringing_trunk * last
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_calloc(num, len)
A wrapper for calloc()
static const char config[]
General Asterisk PBX channel definitions.
Standard Command Line Interface.
void ast_cli_print_timestr_fromseconds(int fd, int seconds, const char *prefix)
Print on cli a duration in seconds in format s year(s), s week(s), s day(s), s hour(s),...
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Generic File Format Support. Should be included by clients of the file handling routines....
static struct ast_threadstorage buf2
static struct ast_threadstorage buf1
char * strsep(char **str, const char *delims)
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
void ast_category_rename(struct ast_category *cat, const char *name)
#define CONFIG_STATUS_FILEMISSING
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
void ast_category_append(struct ast_config *config, struct ast_category *category)
Appends a category to a config.
void ast_variable_append(struct ast_category *category, struct ast_variable *variable)
#define ast_category_new_anonymous()
Create a nameless category that is not backed by a file.
#define ast_variable_new(name, value, filename)
int ast_config_engine_deregister(struct ast_config_engine *del)
Deregister config engine.
#define CONFIG_STATUS_FILEUNCHANGED
char * ast_realtime_decode_chunk(char *chunk)
Remove standard encoding from realtime values, which ensures that a semicolon embedded within a singl...
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
int ast_rq_is_int(require_type type)
Check if require type is an integer type.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
require_type
Types used in ast_realtime_require_field.
struct ast_config * ast_config_internal_load(const char *configfile, struct ast_config *cfg, struct ast_flags flags, const char *suggested_incl_file, const char *who_asked)
#define ast_category_new_dynamic(name)
Create a category that is not backed by a file.
int ast_config_engine_register(struct ast_config_engine *newconfig)
Register config engine.
@ CONFIG_FLAG_FILEUNCHANGED
#define DEBUG_ATLEAST(level)
#define ast_debug(level,...)
Log a DEBUG message.
#define ast_verb(level,...)
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
#define AST_LIST_HEAD_STATIC(name, type)
Defines a structure to be used to hold a list of specified type, statically initialized.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_LOCK(head)
Locks a list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Asterisk locking-related definitions:
#define ast_rwlock_wrlock(a)
#define ast_rwlock_rdlock(a)
#define ast_mutex_unlock(a)
#define ast_rwlock_init(rwlock)
wrapper for rwlock with tracking enabled
#define ast_rwlock_destroy(rwlock)
#define ast_rwlock_unlock(a)
#define ast_mutex_lock(a)
#define AST_MUTEX_DEFINE_STATIC(mutex)
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_REALTIME_DRIVER
@ AST_MODULE_SUPPORT_EXTENDED
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Core PBX routines and definitions.
static int parse_config(int reload)
static char dbuser[MAX_DB_OPTION_SIZE]
static char dbappname[MAX_DB_OPTION_SIZE]
static struct ast_threadstorage where_buf
static struct ast_config * realtime_multi_pgsql(const char *database, const char *table, const struct ast_variable *fields)
static void destroy_table(struct tables *table)
static int pgsql_exec(const char *database, const char *tablename, const char *sql, PGresult **result)
Do a postgres query, with reconnection support.
static int update2_pgsql(const char *database, const char *tablename, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields)
static int order_multi_row_results_by_initial_column
static struct ast_threadstorage escapebuf_buf
static struct ast_cli_entry cli_realtime[]
static enum @427 requirements
static int destroy_pgsql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *fields)
#define IS_SQL_LIKE_CLAUSE(x)
static char dbname[MAX_DB_OPTION_SIZE]
static char dbpass[MAX_DB_OPTION_SIZE]
static int update_pgsql(const char *database, const char *tablename, const char *keyfield, const char *lookup, const struct ast_variable *fields)
#define release_table(table)
static int unload_pgsql(const char *database, const char *tablename)
static char * handle_cli_realtime_pgsql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
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 RES_CONFIG_PGSQL_CONF
#define has_schema_support
static int store_pgsql(const char *database, const char *table, const struct ast_variable *fields)
static PGconn * pgsqlConn
static struct ast_config_engine pgsql_engine
static ast_mutex_t pgsql_lock
#define ESCAPE_STRING(buffer, stringname)
static char dbhost[MAX_DB_OPTION_SIZE]
static int pgsql_reconnect(const char *database)
static int load_module(void)
static time_t connect_time
static char dbsock[MAX_DB_OPTION_SIZE]
static int require_pgsql(const char *database, const char *tablename, va_list ap)
static struct columns * find_column(struct tables *t, const char *colname)
static int unload_module(void)
static struct ast_threadstorage findtable_buf
static char * handle_cli_realtime_pgsql_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define MAX_DB_OPTION_SIZE
static struct ast_threadstorage semibuf_buf
static struct tables * find_table(const char *database, const char *orig_tablename)
static struct ast_variable * realtime_pgsql(const char *database, const char *tablename, const struct ast_variable *fields)
static struct ast_config * config_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 struct ast_threadstorage sql_buf
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
struct ast_str * ast_str_thread_get(struct ast_threadstorage *ts, size_t init_len)
Retrieve a thread locally stored dynamic string.
descriptor for a cli entry.
Configuration engine structure, used to define realtime drivers.
Structure used to handle boolean flags.
Structure for rwlock and tracking information.
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
struct columns::@428 list
struct mysql_conn * database
struct tables::psql_columns columns
struct tables::mysql_columns columns
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.