|  | 
| static void | __reg_module (void) | 
|  | 
| static void | __unreg_module (void) | 
|  | 
| struct ast_module * | AST_MODULE_SELF_SYM (void) | 
|  | 
|  | AST_THREADSTORAGE_CUSTOM_SCOPE (find_buf, NULL, ast_free_ptr, static) | 
|  | 
|  | AST_THREADSTORAGE_CUSTOM_SCOPE (modify2_buf, NULL, ast_free_ptr, static) | 
|  | 
|  | AST_THREADSTORAGE_CUSTOM_SCOPE (modify3_buf, NULL, ast_free_ptr, static) | 
|  | 
|  | AST_THREADSTORAGE_CUSTOM_SCOPE (modify_buf, NULL, ast_free_ptr, static) | 
|  | 
|  | AST_THREADSTORAGE_CUSTOM_SCOPE (scratch2_buf, NULL, ast_free_ptr, static) | 
|  | 
|  | AST_THREADSTORAGE_CUSTOM_SCOPE (scratch_buf, NULL, ast_free_ptr, static) | 
|  | 
|  | AST_THREADSTORAGE_CUSTOM_SCOPE (sql2_buf, NULL, ast_free_ptr, static) | 
|  | 
|  | AST_THREADSTORAGE_CUSTOM_SCOPE (sql_buf, NULL, ast_free_ptr, static) | 
|  | 
| static struct ast_config * | config_mysql (const char *database, const char *table, const char *file, struct ast_config *cfg, struct ast_flags config_flags, const char *unused, const char *who_asked) | 
|  | 
| static char * | decode_chunk (char *chunk) | 
|  | 
| static int | destroy_mysql (const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields) | 
|  | 
| static void | destroy_table (struct tables *table) | 
|  | 
| static struct columns * | find_column (struct tables *table, const char *colname) | 
|  | 
| static struct mysql_conn * | find_database (const char *database, int for_write) | 
|  | 
| static struct tables * | find_table (const char *database, const char *tablename) | 
|  | 
| static char * | handle_cli_realtime_mysql_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
|  | 
| static char * | handle_cli_realtime_mysql_status (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) | 
|  | 
| static int | load_module (void) | 
|  | 
| static int | load_mysql_config (struct ast_config *config, const char *category, struct mysql_conn *conn) | 
|  | 
| static int | mysql_reconnect (struct mysql_conn *conn) | 
|  | 
| static int | parse_config (int reload) | 
|  | 
| static struct ast_config * | realtime_multi_mysql (const char *database, const char *table, const struct ast_variable *rt_fields) | 
|  | 
| static struct ast_variable * | realtime_mysql (const char *database, const char *table, const struct ast_variable *rt_fields) | 
|  | 
| static void | release_table (struct tables *table) | 
|  | 
| static int | reload (void) | 
|  | 
| static int | require_mysql (const char *database, const char *tablename, va_list ap) | 
|  | 
| static int | store_mysql (const char *database, const char *table, const struct ast_variable *rt_fields) | 
|  | 
| static int | unload_module (void) | 
|  | 
| static int | unload_mysql (const char *database, const char *tablename) | 
|  | 
| static int | update2_mysql (const char *database, const char *tablename, const struct ast_variable *lookup_fields, const struct ast_variable *update_fields) | 
|  | 
| static int | update_mysql (const char *database, const char *tablename, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields) | 
|  | 
MySQL CDR backend. 
Definition in file res_config_mysql.c.
  
  | 
        
          | static struct ast_config * config_mysql | ( | const char * | database, |  
          |  |  | const char * | table, |  
          |  |  | const char * | file, |  
          |  |  | struct ast_config * | cfg, |  
          |  |  | struct ast_flags | config_flags, |  
          |  |  | const char * | unused, |  
          |  |  | const char * | who_asked |  
          |  | ) |  |  |  | static | 
 
Definition at line 876 of file res_config_mysql.c.
  877{
  880    MYSQL_ROW row;
  881    uint64_t num_rows;
  886    int last_cat_metric = 0;
  887 
  889 
  893    }
  894 
  896        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  898    }
  899 
  900    ast_str_set(&sql, 0, 
"SELECT category, var_name, var_val, cat_metric FROM %s WHERE filename='%s' and commented=0 ORDER BY filename, category, cat_metric desc, var_metric asc, var_name, var_val, id", table, file);
 
  901 
  903 
  904    
  907    }
  908 
  910        ast_log(
LOG_WARNING, 
"MySQL RealTime: Failed to query database. Check debug for more info.\n");
 
  912        ast_debug(1, 
"MySQL RealTime: Query Failed because: %s\n", mysql_error(&dbh->
handle));
 
  915    }
  916 
  918        num_rows = mysql_num_rows(
result);
 
  919        ast_debug(1, 
"MySQL RealTime: Found %" PRIu64 
" rows.\n", num_rows);
 
  920 
  921        
  922
  923 
  924        while ((row = mysql_fetch_row(
result))) {
 
  925            if (!strcmp(row[1], "#include")) {
  927                    mysql_free_result(
result);
 
  930                }
  931                continue;
  932            }
  933 
  934            if (strcmp(
last, row[0]) || last_cat_metric != atoi(row[3])) {
 
  936                if (!cur_cat) {
  937                    break;
  938                }
  939                strcpy(
last, row[0]);
 
  940                last_cat_metric = atoi(row[3]);
  942            }
  944            if (cur_cat)
  946        }
  947    } else {
  948        ast_log(
LOG_WARNING, 
"MySQL RealTime: Could not find config '%s' in database.\n", file);
 
  949    }
  950 
  951    mysql_free_result(
result);
 
  953 
  954    return cfg;
  955}
struct sla_ringing_trunk * last
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_variable_new(name, value, filename)
@ CONFIG_FLAG_FILEUNCHANGED
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.
#define ast_debug(level,...)
Log a DEBUG message.
#define RES_CONFIG_MYSQL_CONF
static struct mysql_conn * find_database(const char *database, int for_write)
static int mysql_reconnect(struct mysql_conn *conn)
#define release_database(a)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Structure for variables, used for configurations and for channel variables.
#define ast_clear_flag(p, flag)
References ast_category_append(), ast_category_new_dynamic, ast_clear_flag, ast_config_internal_load(), ast_debug, ast_log, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_thread_get(), ast_variable_append(), ast_variable_new, CONFIG_FLAG_FILEUNCHANGED, find_database(), mysql_conn::handle, last, LOG_WARNING, mysql_reconnect(), NULL, release_database, RES_CONFIG_MYSQL_CONF, and result.
 
 
  
  | 
        
          | static int destroy_mysql | ( | const char * | database, |  
          |  |  | const char * | table, |  
          |  |  | const char * | keyfield, |  
          |  |  | const char * | lookup, |  
          |  |  | const struct ast_variable * | rt_fields |  
          |  | ) |  |  |  | static | 
 
Definition at line 810 of file res_config_mysql.c.
  811{
  813    uint64_t numrows;
  817 
  819        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  820        return -1;
  821    }
  822 
  823    if (!table) {
  826        return -1;
  827    }
  828 
  829    
  830    
  831
  833        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime destroying requires at least 1 parameter and 1 value to search on.\n");
 
  835        return -1;
  836    }
  837 
  838    
  841        return -1;
  842    }
  843 
  844    
  845
  848    for (field = rt_fields; field; field = field->
next) {
 
  851    }
  852 
  854 
  855    
  859        return -1;
  860    }
  861 
  862    numrows = mysql_affected_rows(&dbh->
handle);
 
  864 
  865    ast_debug(1, 
"MySQL RealTime: Deleted %" PRIu64 
" rows on table: %s\n", numrows, table);
 
  866 
  867    
  868
  869
  870
  871
  872 
  873    return (int)numrows;
  874}
#define ESCAPE_STRING(buf, var)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
struct ast_variable * next
References ast_debug, ast_log, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_thread_get(), ast_strlen_zero(), buf, ESCAPE_STRING, find_database(), mysql_conn::handle, LOG_WARNING, mysql_reconnect(), ast_variable::name, ast_variable::next, release_database, and ast_variable::value.
 
 
  
  | 
        
          | static struct mysql_conn * find_database | ( | const char * | database, |  
          |  |  | int | for_write |  
          |  | ) |  |  |  | static | 
 
Definition at line 132 of file res_config_mysql.c.
  133{
  134    char *whichdb;
  135    const char *ptr;
  137 
  138    if ((ptr = strchr(database, '/'))) {
  139        
  140        if (for_write) {
  142        } else {
  144            strncpy(whichdb, database, ptr - database);
  145            whichdb[ptr - database] = '\0';
  146        }
  147    } else {
  149    }
  150 
  155            break;
  156        }
  157    }
  159    return cur;
  160}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_RWLIST_TRAVERSE
struct mysql_conn::@4 list
References ast_alloca, ast_mutex_lock, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, mysql_conn::list, mysql_conn::lock, and mysql_conn::unique_name.
Referenced by config_mysql(), destroy_mysql(), find_table(), realtime_multi_mysql(), realtime_mysql(), store_mysql(), update2_mysql(), and update_mysql().
 
 
  
  | 
        
          | static struct tables * find_table | ( | const char * | database, |  
          |  |  | const char * | tablename |  
          |  | ) |  |  |  | static | 
 
Definition at line 176 of file res_config_mysql.c.
  177{
  181    char *fname, *ftype, *flen, *fdflt, *fnull;
  184    MYSQL_ROW row;
  185 
  188    }
  189 
  192        if (!strcasecmp(table->
name, tablename)) {
 
  196            return table;
  197        }
  198    }
  199 
  200    
  202 
  207    }
  208 
  210        ast_log(
LOG_ERROR, 
"Failed to query database '%s', table '%s' columns: %s\n", database, tablename, mysql_error(&dbh->
handle));
 
  214    }
  215 
  216    if (!(table = 
ast_calloc(1, 
sizeof(*table) + strlen(tablename) + 1))) {
 
  221    }
  222    strcpy(table->
name, tablename); 
 
  226 
  228        while ((row = mysql_fetch_row(
result))) {
 
  229            fname = row[0];
  230            ftype = row[1];
  231            fnull = row[2];
  232            fdflt = row[4];
  233            ast_verb(4, 
"Found column '%s' of type '%s'\n", fname, ftype);
 
  234 
  236                fdflt = "";
  237            }
  238 
  239            if (!(column = 
ast_calloc(1, 
sizeof(*column) + strlen(fname) + strlen(ftype) + strlen(fdflt) + 3))) {
 
  240                ast_log(
LOG_ERROR, 
"Unable to allocate column element %s for %s\n", fname, tablename);
 
  245            }
  246 
  247            if ((flen = strchr(ftype, '('))) {
  248                sscanf(flen, 
"(%30d)", &column->
len);
 
  249            } else {
  250                
  252            }
  253 
  254            column->
name = (
char *)column + 
sizeof(*column);
 
  255            column->
type = (
char *)column + 
sizeof(*column) + strlen(fname) + 1;
 
  256            column->
dflt = (
char *)column + 
sizeof(*column) + strlen(fname) + 1 + strlen(ftype) + 1;
 
  257            strcpy(column->
name, fname);
 
  258            strcpy(column->
type, ftype);
 
  259            strcpy(column->
dflt, fdflt);
 
  260            column->
null = (strcmp(fnull, 
"YES") == 0 ? 1 : 0);
 
  262        }
  263        mysql_free_result(
result);
 
  264    }
  265 
  270    return table;
  271}
#define ast_calloc(num, len)
A wrapper for calloc()
#define ast_verb(level,...)
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_LOCK(head)
Locks a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
#define ast_mutex_init(pmutex)
static void destroy_table(struct tables *table)
struct mysql_conn * database
References ast_calloc, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_mutex_init, ast_mutex_lock, ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_thread_get(), ast_verb, tables::columns, tables::database, destroy_table(), columns::dflt, find_database(), mysql_conn::handle, columns::len, mysql_conn::list, tables::lock, LOG_ERROR, mysql_reconnect(), columns::name, tables::name, columns::null, NULL, release_database, result, tables::table, and columns::type.
Referenced by handle_cli_realtime_mysql_cache(), require_mysql(), update2_mysql(), and update_mysql().
 
 
Definition at line 1394 of file res_config_mysql.c.
 1395{
 1397    int l, which;
 1399 
 1400    switch (cmd) {
 1402        e->
command = 
"realtime mysql cache";
 
 1404            "Usage: realtime mysql cache [<database> <table>]\n"
 1405            "       Shows table cache for the MySQL RealTime driver\n";
 1408        if (
a->argc < 4 || 
a->argc > 5) {
 
 1410        }
 1411        l = strlen(
a->word);
 
 1412        which = 0;
 1418                    break;
 1419                }
 1420            }
 1422        } else {
 1426                if (!strncasecmp(
a->word, cur->
unique_name, l) && ++which > 
a->n) {
 
 1428                    break;
 1429                }
 1430            }
 1432        }
 1433        return ret;
 1434    }
 1435 
 1437        
 1441        }
 1443    } 
else if (
a->argc == 4) {
 
 1444        int found = 0;
 1445        
 1448            if (!strcasecmp(cur->database->
unique_name, 
a->argv[3])) {
 
 1450                found = 1;
 1451            }
 1452        }
 1454        if (!found) {
 1455            ast_cli(
a->fd, 
"No tables cached within %s database\n", 
a->argv[3]);
 
 1456        }
 1457    } 
else if (
a->argc == 5) {
 
 1458        
 1461            ast_cli(
a->fd, 
"Columns for Table Cache '%s':\n", 
a->argv[3]);
 
 1462            ast_cli(
a->fd, 
"%-20.20s %-20.20s %-3.3s\n", 
"Name", 
"Type", 
"Len");
 
 1465            }
 1467        } else {
 1468            ast_cli(
a->fd, 
"No such table '%s'\n", 
a->argv[3]);
 
 1469        }
 1470    }
 1472}
#define ast_strdup(str)
A wrapper for strdup()
void ast_cli(int fd, const char *fmt,...)
static struct tables * find_table(const char *database, const char *tablename)
#define release_table(table)
References a, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, tables::columns, ast_cli_entry::command, tables::database, find_table(), columns::len, mysql_conn::list, columns::list, tables::list, columns::name, tables::name, NULL, release_table, columns::type, mysql_conn::unique_name, and ast_cli_entry::usage.
 
 
Definition at line 1474 of file res_config_mysql.c.
 1475{
 1476    char status[256], status2[100] = 
"", 
type[20];
 
 1478    int ctime = 0, found = 0;
 1480    int l = 0, which = 0;
 1481 
 1482    switch (cmd) {
 1484        e->
command = 
"realtime mysql status";
 
 1486            "Usage: realtime mysql status [<database>]\n"
 1487            "       Shows connection information for the MySQL RealTime driver\n";
 1493                if (!strncasecmp(
a->word, cur->
unique_name, l) && ++which > 
a->n) {
 
 1495                    break;
 1496                }
 1497            }
 1499        }
 1500        return ret;
 1501    }
 1502 
 1505 
 1508        if (
a->argc == 3 || (
a->argc == 4 && !strcasecmp(
a->argv[3], cur->
unique_name))) {
 
 1509            found = 1;
 1510 
 1512                snprintf(
type, 
sizeof(
type), 
"connected to");
 
 1514            } else {
 1515                snprintf(
type, 
sizeof(
type), 
"configured for");
 
 1516                ctime = -1;
 1517            }
 1518 
 1521            } else {
 1523            }
 1524 
 1526                snprintf(status2, 
sizeof(status2), 
" with username %s", cur->
user);
 
 1527            } else {
 1528                status2[0] = '\0';
 1529            }
 1530 
 1531            if (ctime > 31536000) {
 1532                ast_cli(
a->fd, 
"%s%s for %.1f years.\n", 
status, status2, (
double)ctime / 31536000.0);
 
 1533            } else if (ctime > 86400 * 30) {
 1534                ast_cli(
a->fd, 
"%s%s for %d days.\n", 
status, status2, ctime / 86400);
 
 1535            } else if (ctime > 86400) {
 1536                ast_cli(
a->fd, 
"%s%s for %d days, %d hours.\n", 
status, status2, ctime / 86400, (ctime % 86400) / 3600);
 
 1537            } else if (ctime > 3600) {
 1538                ast_cli(
a->fd, 
"%s%s for %d hours, %d minutes.\n", 
status, status2, ctime / 3600, (ctime % 3600) / 60);
 
 1539            } else if (ctime > 60) {
 1540                ast_cli(
a->fd, 
"%s%s for %d minutes.\n", 
status, status2, ctime / 60);
 
 1541            } else if (ctime > -1) {
 1542                ast_cli(
a->fd, 
"%s%s for %d seconds.\n", 
status, status2, ctime);
 
 1543            } else {
 1545            }
 1546        }
 1547    }
 1549 
 1550    if (!found) {
 1551        ast_cli(
a->fd, 
"No connections configured.\n");
 
 1552    }
 1554}
char host[MAXHOSTNAMELEN]
References a, ast_cli(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, ast_strlen_zero(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, mysql_conn::connect_time, mysql_conn::host, mysql_conn::list, mysql_reconnect(), mysql_conn::name, NULL, mysql_conn::port, mysql_conn::sock, status, type, mysql_conn::unique_name, ast_cli_entry::usage, and mysql_conn::user.
 
 
  
  | 
        
          | static int load_mysql_config | ( | struct ast_config * | config, |  
          |  |  | const char * | category, |  
          |  |  | struct mysql_conn * | conn |  
          |  | ) |  |  |  | static | 
 
Definition at line 1242 of file res_config_mysql.c.
 1243{
 1244    const char *s;
 1245 
 1247        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database user found, using 'asterisk' as default.\n");
 
 1248        s = "asterisk";
 1249    }
 1251 
 1253        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database password found, using 'asterisk' as default.\n");
 
 1254        s = "asterisk";
 1255    }
 1257 
 1259        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database host found, using localhost via socket.\n");
 
 1260        s = "";
 1261    }
 1263 
 1265        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database name found, using 'asterisk' as default.\n");
 
 1266        s = "asterisk";
 1267    }
 1269 
 1271        ast_log(
LOG_WARNING, 
"MySQL RealTime: No database port found, using 3306 as default.\n");
 
 1273    } else
 1274        conn->port = atoi(s);
 
 1275 
 1278            char *paths[3] = { "/tmp/mysql.sock", "/var/lib/mysql/mysql.sock", "/var/run/mysqld/mysqld.sock" };
 1279            struct stat st;
 1280            int i;
 1281            for (i = 0; i < 3; i++) {
 1282                if (!stat(paths[i], &st)) {
 1283                    ast_log(
LOG_WARNING, 
"MySQL RealTime: No database socket found, using '%s' as default.\n", paths[i]);
 
 1285                }
 1286            }
 1287            if (i == 3) {
 1288                ast_log(
LOG_WARNING, 
"MySQL RealTime: No database socket found (and unable to detect a suitable path).\n");
 
 1289                return 0;
 1290            }
 1291        }
 1292    } else
 1294 
 1297    }
 1298 
 1300        ast_log(
LOG_WARNING, 
"MySQL realtime: no requirements setting found, using 'warn' as default.\n");
 
 1302    } else if (!strcasecmp(s, "createclose")) {
 1304    } else if (!strcasecmp(s, "createchar")) {
 1306    } else if (!strcasecmp(s, "warn")) {
 1308    } else {
 1309        ast_log(
LOG_WARNING, 
"MySQL realtime: unrecognized requirements setting '%s', using 'warn'\n", s);
 
 1311    }
 1312 
 1316    } else
 1318    ast_debug(1, 
"MySQL RealTime database name: %s\n", 
conn->name);
 
 1322        ast_debug(1, 
"MySQL RealTime charset: %s\n", 
conn->charset);
 
 1323 
 1324    return 1;
 1325}
static const char config[]
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
References ast_copy_string(), ast_debug, ast_log, ast_strlen_zero(), ast_variable_retrieve(), config, conn, LOG_WARNING, RQ_CREATECHAR, RQ_CREATECLOSE, and RQ_WARN.
Referenced by parse_config().
 
 
  
  | 
        
          | static int mysql_reconnect | ( | struct mysql_conn * | conn | ) |  |  | static | 
 
Definition at line 1327 of file res_config_mysql.c.
 1328{
 1329#ifdef MYSQL_OPT_RECONNECT
 1330    my_bool trueval = 1;
 1331#endif
 1332 
 1333    
 1334 
 1335reconnect_tryagain:
 1337        if (!mysql_init(&
conn->handle)) {
 
 1338            ast_log(
LOG_WARNING, 
"MySQL RealTime: Insufficient memory to allocate MySQL resource.\n");
 
 1339            conn->connected = 0;
 
 1340            return 0;
 1341        }
 1342        if(strlen(
conn->charset) > 2){
 
 1343            char set_names[255];
 1344            char statement[512];
 1345            snprintf(set_names, 
sizeof(set_names), 
"SET NAMES %s", 
conn->charset);
 
 1346            mysql_real_escape_string(&
conn->handle, statement, set_names, 
sizeof(set_names));
 
 1347            mysql_options(&
conn->handle, MYSQL_INIT_COMMAND, set_names);
 
 1348            mysql_options(&
conn->handle, MYSQL_SET_CHARSET_NAME, 
conn->charset);
 
 1349        }
 1350 
 1352#ifdef MYSQL_OPT_RECONNECT
 1353            
 1354
 1355            mysql_options(&
conn->handle, MYSQL_OPT_RECONNECT, &trueval);
 
 1356#endif
 1357            ast_debug(1, 
"MySQL RealTime: Successfully connected to database.\n");
 
 1358            conn->connected = 1;
 
 1360            return 1;
 1361        } else {
 1363            ast_debug(1, 
"MySQL RealTime: Cannot Connect (%d): %s\n", mysql_errno(&
conn->handle), mysql_error(&
conn->handle));
 
 1364            conn->connected = 0;
 
 1365            conn->connect_time = 0;
 
 1366            return 0;
 1367        }
 1368    } else {
 1369        
 1370
 1371        if (mysql_ping(&
conn->handle) != 0 && (usleep(1) + 2 > 0) && mysql_ping(&
conn->handle) != 0) {
 
 1372            conn->connected = 0;
 
 1373            conn->connect_time = 0;
 
 1374            ast_log(
LOG_ERROR, 
"MySQL RealTime: Ping failed (%d).  Trying an explicit reconnect.\n", mysql_errno(&
conn->handle));
 
 1375            ast_debug(1, 
"MySQL RealTime: Server Error (%d): %s\n", mysql_errno(&
conn->handle), mysql_error(&
conn->handle));
 
 1376            goto reconnect_tryagain;
 1377        }
 1378 
 1379        if (!
conn->connected) {
 
 1380            conn->connected = 1;
 
 1382        }
 1383 
 1384        if (mysql_select_db(&
conn->handle, 
conn->name) != 0) {
 
 1385            ast_log(
LOG_WARNING, 
"MySQL RealTime: Unable to select database: %s. Still Connected (%u) - %s.\n", 
conn->name, mysql_errno(&
conn->handle), mysql_error(&
conn->handle));
 
 1386            return 0;
 1387        }
 1388 
 1389        ast_debug(1, 
"MySQL RealTime: Connection okay.\n");
 
 1390        return 1;
 1391    }
 1392}
References ast_debug, ast_log, ast_strlen_zero(), conn, LOG_ERROR, LOG_WARNING, and NULL.
Referenced by config_mysql(), destroy_mysql(), find_table(), handle_cli_realtime_mysql_status(), realtime_multi_mysql(), realtime_mysql(), store_mysql(), update2_mysql(), and update_mysql().
 
 
  
  | 
        
          | static int parse_config | ( | int | reload | ) |  |  | static | 
 
Definition at line 1193 of file res_config_mysql.c.
 1194{
 1197    const char *catg;
 1199 
 1201        
 1203    }
 1204 
 1206        return 0;
 1208        return 0;
 1211    }
 1212 
 1215        
 1218                break;
 1219            }
 1220        }
 1221 
 1222        if (!cur) {
 1223            if (!(cur = 
ast_calloc(1, 
sizeof(*cur) + strlen(catg) + 1))) {
 
 1225                continue;
 1226            }
 1227 
 1231        }
 1232 
 1234    }
 1236 
 1238 
 1239    return 0;
 1240}
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
#define CONFIG_STATUS_FILEMISSING
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
#define AST_RWLIST_INSERT_TAIL
static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn)
#define RES_CONFIG_MYSQL_CONF_OLD
Structure used to handle boolean flags.
References ast_calloc, ast_category_browse(), ast_config_destroy(), ast_config_load, ast_log, ast_mutex_init, AST_RWLIST_INSERT_TAIL, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, mysql_conn::list, load_mysql_config(), mysql_conn::lock, LOG_ERROR, LOG_WARNING, NULL, reload(), RES_CONFIG_MYSQL_CONF, RES_CONFIG_MYSQL_CONF_OLD, and mysql_conn::unique_name.
 
 
  
  | 
        
          | static struct ast_config * realtime_multi_mysql | ( | const char * | database, |  
          |  |  | const char * | table, |  
          |  |  | const struct ast_variable * | rt_fields |  
          |  | ) |  |  |  | static | 
 
Definition at line 420 of file res_config_mysql.c.
  421{
  424    MYSQL_ROW row;
  425    MYSQL_FIELD *fields;
  426    int numFields, i;
  429    const char *initfield = 
NULL;
 
  430    char *stringp;
  431    char *chunk;
  432    char *op;
  433    char *escape = "";
  438 
  440        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  442    }
  443 
  444    if (!table) {
  448    }
  449 
  451        
  455    }
  456 
  457    
  458    if (!field) {
  459        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
 
  463    }
  464 
  466    if ((op = strchr(initfield, ' '))) {
  467        *op = '\0';
  468    }
  469 
  470    
  475    }
  476 
  477    
  478
  479 
  480    if (!strchr(field->
name, 
' ')) {
 
  481        op = " =";
  482    } else {
  483        op = "";
  486        }
  487    }
  488 
  491    while ((field = field->
next)) {
 
  492        escape = "";
  493        if (!strchr(field->
name, 
' ')) {
 
  494            op = " =";
  495        } else {
  496            op = "";
  499            }
  500        }
  503    }
  504 
  505    if (initfield) {
  507    }
  508 
  510 
  511    
  517    }
  518 
  520        numFields = mysql_num_fields(
result);
 
  521        fields = mysql_fetch_fields(
result);
 
  522 
  523        while ((row = mysql_fetch_row(
result))) {
 
  526            if (!cat) {
  527                continue;
  528            }
  529            for (i = 0; i < numFields; i++) {
  531                    continue;
  532                for (stringp = row[i], chunk = 
strsep(&stringp, 
";"); chunk; chunk = 
strsep(&stringp, 
";")) {
 
  534                        if (initfield && !strcmp(initfield, fields[i].
name)) {
 
  536                        }
  539                    }
  540                }
  541            }
  543        }
  544    } else {
  545        ast_debug(1, 
"MySQL RealTime: Could not find any rows in table %s.\n", table);
 
  546    }
  547 
  549    mysql_free_result(
result);
 
  550 
  551    return cfg;
  552}
char * strsep(char **str, const char *delims)
void ast_category_rename(struct ast_category *cat, const char *name)
struct ast_config * ast_config_new(void)
Create a new base configuration structure.
#define ast_category_new_anonymous()
Create a nameless category that is not backed by a file.
static char * ESCAPE_CLAUSE
#define IS_SQL_LIKE_CLAUSE(x)
static char * decode_chunk(char *chunk)
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
References ast_category_append(), ast_category_new_anonymous, ast_category_rename(), ast_config_destroy(), ast_config_new(), ast_debug, ast_log, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_thread_get(), ast_strdupa, ast_strip(), ast_strlen_zero(), ast_variable_append(), ast_variable_new, buf, decode_chunk(), ESCAPE_CLAUSE, ESCAPE_STRING, find_database(), mysql_conn::handle, IS_SQL_LIKE_CLAUSE, LOG_WARNING, mysql_reconnect(), name, ast_variable::name, ast_variable::next, NULL, release_database, result, strsep(), ast_variable::value, and var.
 
 
  
  | 
        
          | static struct ast_variable * realtime_mysql | ( | const char * | database, |  
          |  |  | const char * | table, |  
          |  |  | const struct ast_variable * | rt_fields |  
          |  | ) |  |  |  | static | 
 
Definition at line 310 of file res_config_mysql.c.
  311{
  314    MYSQL_ROW row;
  315    MYSQL_FIELD *fields;
  316    int numFields, i;
  319    char *stringp;
  320    char *chunk;
  321    char *op;
  322    char *escape = "";
  325 
  327        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: %s (check res_mysql.conf)\n", database);
 
  329    }
  330 
  331    if (!table) {
  335    }
  336 
  337    
  338    if (!field) {
  339        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime retrieval requires at least 1 parameter and 1 value to search on.\n");
 
  342    }
  343 
  344    
  348    }
  349 
  350    
  351
  352 
  353    if (!strchr(field->
name, 
' ')) {
 
  354        op = " =";
  355    } else {
  356        op = "";
  359        }
  360    }
  361 
  364    while ((field = field->
next)) {
 
  365        escape = "";
  366        if (!strchr(field->
name, 
' ')) {
 
  367            op = " =";
  368        } else {
  369            op = "";
  372            }
  373        }
  376    }
  377 
  379 
  380    
  385    }
  386 
  388        numFields = mysql_num_fields(
result);
 
  389        fields = mysql_fetch_fields(
result);
 
  390 
  391        while ((row = mysql_fetch_row(
result))) {
 
  392            for (i = 0; i < numFields; i++) {
  393                
  394                if (row[i] == 
NULL) {
 
  395                    row[i] = "";
  397                    row[i] = " ";
  398                }
  399                for (stringp = row[i], chunk = 
strsep(&stringp, 
";"); chunk; chunk = 
strsep(&stringp, 
";")) {
 
  400                    if (prev) {
  402                            prev = prev->next;
  403                        }
  404                    } else {
  406                    }
  407                }
  408            }
  409        }
  410    } else {
  411        ast_debug(1, 
"MySQL RealTime: Could not find any rows in table %s.\n", table);
 
  412    }
  413 
  415    mysql_free_result(
result);
 
  416 
  418}
References ast_debug, ast_log, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_thread_get(), ast_strlen_zero(), ast_variable_new, buf, decode_chunk(), ESCAPE_CLAUSE, ESCAPE_STRING, find_database(), mysql_conn::handle, IS_SQL_LIKE_CLAUSE, LOG_WARNING, mysql_reconnect(), name, ast_variable::name, ast_variable::next, NULL, release_database, result, strsep(), ast_variable::value, and var.
 
 
  
  | 
        
          | static int require_mysql | ( | const char * | database, |  
          |  |  | const char * | tablename, |  
          |  |  | va_list | ap |  
          |  | ) |  |  |  | static | 
 
Definition at line 973 of file res_config_mysql.c.
  974{
  977    char *elm;
  979    int size;
  980    int res = 0;
  981 
  983        ast_log(
LOG_WARNING, 
"Table %s not found in database.  This table should exist if you're using realtime.\n", tablename);
 
  984        return -1;
  985    }
  986 
  987    while ((elm = va_arg(ap, char *))) {
  989        size = va_arg(ap, int);
  990 
  992            if (strcmp(column->
name, elm) == 0) {
 
  993                
  994                if (strncmp(column->
type, 
"char", 4) == 0 || strncmp(column->
type, 
"varchar", 7) == 0) {
 
  995                    if ((size > column->
len) && column->
len != -1) {
 
  996                        ast_log(
LOG_WARNING, 
"Realtime table %s@%s: Column '%s' should be at least %d long, but is only %d long.\n", 
database, tablename, column->
name, size, column->
len);
 
  997                        res = -1;
  998                    }
 1001                        ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
 
 1005                        res = -1;
 1006                    } 
else if (strncasecmp(column->
type, 
"tinyint", 1) == 0) {
 
 1008                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1009                                "the required data length: %d (detected stringtype)\n",                                      \
 1011                            res = -1;                                                                                        \
 1012                        }
 1013                    } 
else if (strncasecmp(column->
type, 
"smallint", 1) == 0) {
 
 1015                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1016                                "the required data length: %d (detected stringtype)\n",                                      \
 1018                            res = -1;                                                                                        \
 1019                        }
 1020                    } 
else if (strncasecmp(column->
type, 
"mediumint", 1) == 0) {
 
 1024                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1025                                "the required data length: %d (detected stringtype)\n",                                      \
 1027                            res = -1;                                                                                        \
 1028                        }
 1029                    } 
else if (strncasecmp(column->
type, 
"int", 1) == 0) {
 
 1034                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1035                                "the required data length: %d (detected stringtype)\n",                                      \
 1037                            res = -1;                                                                                        \
 1038                        }
 1039                    } 
else if (strncasecmp(column->
type, 
"bigint", 1) == 0) {
 
 1045                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1046                                "the required data length: %d (detected stringtype)\n",                                      \
 1048                            res = -1;                                                                                        \
 1049                        }
 1050                    }
 1053                        ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
 
 1057                            "to get a life, rather than writing silly error messages");
 1058                        res = -1;
 1059                    } 
else if (strncasecmp(column->
type, 
"tinyint", 1) == 0) {
 
 1061                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1062                                "the required data length: %d (detected stringtype)\n",                                      \
 1064                            res = -1;                                                                                        \
 1065                        }
 1066                    } 
else if (strncasecmp(column->
type, 
"smallint", 1) == 0) {
 
 1068                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1069                                "the required data length: %d (detected stringtype)\n",                                      \
 1071                            res = -1;                                                                                        \
 1072                        }
 1073                    } 
else if (strncasecmp(column->
type, 
"mediumint", 1) == 0) {
 
 1077                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1078                                "the required data length: %d (detected stringtype)\n",                                      \
 1080                            res = -1;                                                                                        \
 1081                        }
 1082                    } 
else if (strncasecmp(column->
type, 
"int", 1) == 0) {
 
 1087                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1088                                "the required data length: %d (detected stringtype)\n",                                      \
 1090                            res = -1;                                                                                        \
 1091                        }
 1092                    } 
else if (strncasecmp(column->
type, 
"bigint", 1) == 0) {
 
 1098                            ast_log(
LOG_WARNING, 
"Realtime table %s@%s: column '%s' may not be large enough for "            \
 
 1099                                "the required data length: %d (detected stringtype)\n",                                      \
 1101                            res = -1;                                                                                        \
 1102                        }
 1103                    }
 1104                } 
else if (strncmp(column->
type, 
"float", 5) == 0) {
 
 1107                        res = -1;
 1108                    }
 1109                } 
else if (strncmp(column->
type, 
"datetime", 8) == 0 || strncmp(column->
type, 
"timestamp", 9) == 0) {
 
 1112                        res = -1;
 1113                    }
 1114                } 
else if (strncmp(column->
type, 
"date", 4) == 0) {
 
 1117                        res = -1;
 1118                    }
 1119                } else { 
 1121                    res = -1;
 1122                }
 1123                break;
 1124            }
 1125        }
 1126 
 1127        if (!column) {
 1128            ast_log(
LOG_WARNING, 
"Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
 
 1129        }
 1130    }
 1132 
 1133    return res;
 1134}
char * strcasestr(const char *, const char *)
int ast_rq_is_int(require_type type)
Check if require type is an integer type.
require_type
Types used in ast_realtime_require_field.
References AST_LIST_TRAVERSE, ast_log, ast_rq_is_int(), tables::database, find_table(), columns::len, tables::list, LOG_WARNING, columns::name, release_table, RQ_CHAR, RQ_DATE, RQ_DATETIME, RQ_FLOAT, RQ_INTEGER1, RQ_INTEGER2, RQ_INTEGER3, RQ_INTEGER4, RQ_INTEGER8, RQ_UINTEGER1, RQ_UINTEGER2, RQ_UINTEGER3, RQ_UINTEGER4, RQ_UINTEGER8, strcasestr(), tables::table, type, and columns::type.
 
 
  
  | 
        
          | static int store_mysql | ( | const char * | database, |  
          |  |  | const char * | table, |  
          |  |  | const struct ast_variable * | rt_fields |  
          |  | ) |  |  |  | static | 
 
Definition at line 752 of file res_config_mysql.c.
  753{
  759 
  761        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  762        return -1;
  763    }
  764 
  765    if (!table) {
  768        return -1;
  769    }
  770    
  771    if (!field) {
  772        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime storage requires at least 1 parameter and 1 value to search on.\n");
 
  774        return -1;
  775    }
  776    
  779        return -1;
  780    }
  781    
  782
  786 
  787    while ((field = field->
next)) {
 
  789 
  792    }
  795 
  796    
  800        return -1;
  801    }
  802 
  804 
  805    ast_debug(1, 
"MySQL RealTime: row inserted on table: %s\n", table);
 
  806 
  807    return 1;
  808}
References ast_debug, ast_log, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_thread_get(), buf, ESCAPE_STRING, find_database(), mysql_conn::handle, LOG_WARNING, mysql_reconnect(), ast_variable::name, ast_variable::next, release_database, and ast_variable::value.
 
 
  
  | 
        
          | static int update2_mysql | ( | const char * | database, |  
          |  |  | const char * | tablename, |  
          |  |  | const struct ast_variable * | lookup_fields, |  
          |  |  | const struct ast_variable * | update_fields |  
          |  | ) |  |  |  | static | 
 
Definition at line 655 of file res_config_mysql.c.
  656{
  658    uint64_t numrows;
  665 
  666    if (!tablename) {
  668        return -1;
  669    }
  670 
  673        return -1;
  674    }
  675 
  676    if (!(table = 
find_table(database, tablename))) {
 
  679        return -1;
  680    }
  681 
  682    if (!sql || !
buf || !where) {
 
  685        return -1;
  686    }
  687 
  690 
  691    
  695        return -1;
  696    }
  697 
  699    for (field = lookup_fields; field; field = field->
next) {
 
  701            ast_log(
LOG_ERROR, 
"Updating on column '%s', but that column does not exist within the table '%s'!\n", field->
name, tablename);
 
  704            return -1;
  705        }
  709    }
  710 
  712    for (field = update_fields; field; field = field->
next) {
 
  713        
  715            ast_log(
LOG_WARNING, 
"Attempted to update column '%s' in table '%s', but column does not exist!\n", field->
name, tablename);
 
  716            continue;
  717        }
  718 
  722    }
  723 
  725 
  727 
  729 
  730    
  735        return -1;
  736    }
  737 
  738    numrows = mysql_affected_rows(&dbh->
handle);
 
  740 
  741    ast_debug(1, 
"MySQL RealTime: Updated %" PRIu64 
" rows on table: %s\n", numrows, tablename);
 
  742 
  743    
  744
  745
  746
  747
  748 
  749    return (int)numrows;
  750}
struct sla_ringing_trunk * first
static struct columns * find_column(struct tables *table, const char *colname)
References ast_debug, ast_log, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_thread_get(), buf, ESCAPE_STRING, find_column(), find_database(), find_table(), first, mysql_conn::handle, LOG_ERROR, LOG_WARNING, mysql_reconnect(), ast_variable::name, ast_variable::next, NULL, release_database, release_table, tables::table, and ast_variable::value.
 
 
  
  | 
        
          | static int update_mysql | ( | const char * | database, |  
          |  |  | const char * | tablename, |  
          |  |  | const char * | keyfield, |  
          |  |  | const char * | lookup, |  
          |  |  | const struct ast_variable * | rt_fields |  
          |  | ) |  |  |  | static | 
 
Definition at line 554 of file res_config_mysql.c.
  555{
  557    uint64_t numrows;
  562 
  564        ast_log(
LOG_WARNING, 
"MySQL RealTime: Invalid database specified: '%s' (check res_mysql.conf)\n", database);
 
  565        return -1;
  566    }
  567 
  568    if (!tablename) {
  571        return -1;
  572    }
  573 
  574    if (!(table = 
find_table(database, tablename))) {
 
  577        return -1;
  578    }
  579 
  581        ast_log(
LOG_ERROR, 
"MySQL RealTime: Updating on column '%s', but that column does not exist within the table '%s' (db '%s')!\n", keyfield, tablename, database);
 
  584        return -1;
  585    }
  586 
  587    
  588    if (!field) {
  589        ast_log(
LOG_WARNING, 
"MySQL RealTime: Realtime update requires at least 1 parameter and 1 value to update.\n");
 
  592        return -1;
  593    }
  594 
  595    
  597        ast_log(
LOG_ERROR, 
"MySQL RealTime: Updating column '%s', but that column does not exist within the table '%s' (first pair MUST exist)!\n", field->
name, tablename);
 
  600        return -1;
  601    }
  602 
  603    
  607        return -1;
  608    }
  609 
  610    
  611
  612 
  615 
  616    while ((field = field->
next)) {
 
  617        
  619            ast_log(
LOG_WARNING, 
"Attempted to update column '%s' in table '%s', but column does not exist!\n", field->
name, tablename);
 
  620            continue;
  621        }
  622 
  625    }
  626 
  629 
  631 
  632    
  637        return -1;
  638    }
  639 
  640    numrows = mysql_affected_rows(&dbh->
handle);
 
  643 
  644    ast_debug(1, 
"MySQL RealTime: Updated %" PRIu64 
" rows on table: %s\n", numrows, tablename);
 
  645 
  646    
  647
  648
  649
  650
  651 
  652    return (int)numrows;
  653}
References ast_debug, ast_log, ast_str_append(), ast_str_buffer(), ast_str_set(), ast_str_strlen(), ast_str_thread_get(), buf, ESCAPE_STRING, find_column(), find_database(), find_table(), mysql_conn::handle, LOG_ERROR, LOG_WARNING, mysql_reconnect(), ast_variable::name, ast_variable::next, NULL, release_database, release_table, tables::table, and ast_variable::value.