|
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.