Skip to content
Snippets Groups Projects
Commit 5acac798 authored by zuul's avatar zuul Committed by Gerrit Code Review
Browse files

Merge "res_config_mysql: Fix several issues related to recent table changes"

parents 01dd018a 3b3d0688
No related branches found
No related tags found
No related merge requests found
...@@ -126,7 +126,6 @@ static char *handle_cli_realtime_mysql_status(struct ast_cli_entry *e, int cmd, ...@@ -126,7 +126,6 @@ static char *handle_cli_realtime_mysql_status(struct ast_cli_entry *e, int cmd,
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_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn); static int load_mysql_config(struct ast_config *config, const char *category, struct mysql_conn *conn);
static int require_mysql(const char *database, const char *tablename, va_list ap); static int require_mysql(const char *database, const char *tablename, va_list ap);
static int internal_require(const char *database, const char *table, ...) attribute_sentinel;
static struct ast_cli_entry cli_realtime_mysql_status[] = { static struct ast_cli_entry cli_realtime_mysql_status[] = {
AST_CLI_DEFINE(handle_cli_realtime_mysql_status, "Shows connection information for the MySQL RealTime driver"), AST_CLI_DEFINE(handle_cli_realtime_mysql_status, "Shows connection information for the MySQL RealTime driver"),
...@@ -165,16 +164,6 @@ static struct mysql_conn *find_database(const char *database, int for_write) ...@@ -165,16 +164,6 @@ static struct mysql_conn *find_database(const char *database, int for_write)
#define release_database(a) ast_mutex_unlock(&(a)->lock) #define release_database(a) ast_mutex_unlock(&(a)->lock)
static int internal_require(const char *database, const char *table, ...)
{
va_list ap;
int res;
va_start(ap, table);
res = require_mysql(database, table, ap);
va_end(ap);
return res;
}
static void destroy_table(struct tables *table) static void destroy_table(struct tables *table)
{ {
struct columns *column; struct columns *column;
...@@ -600,11 +589,6 @@ static int update_mysql(const char *database, const char *tablename, const char ...@@ -600,11 +589,6 @@ static int update_mysql(const char *database, const char *tablename, const char
ESCAPE_STRING(buf, field->value); ESCAPE_STRING(buf, field->value);
ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, field->name, ast_str_buffer(buf)); ast_str_set(&sql, 0, "UPDATE %s SET `%s` = '%s'", tablename, field->name, ast_str_buffer(buf));
/* If the column length isn't long enough, give a chance to lengthen it. */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
}
while ((field = field->next)) { while ((field = field->next)) {
/* If the column is not within the table, then skip it */ /* If the column is not within the table, then skip it */
if (!(column = find_column(table, field->name))) { if (!(column = find_column(table, field->name))) {
...@@ -614,11 +598,6 @@ static int update_mysql(const char *database, const char *tablename, const char ...@@ -614,11 +598,6 @@ static int update_mysql(const char *database, const char *tablename, const char
ESCAPE_STRING(buf, field->value); ESCAPE_STRING(buf, field->value);
ast_str_append(&sql, 0, ", `%s` = '%s'", field->name, ast_str_buffer(buf)); ast_str_append(&sql, 0, ", `%s` = '%s'", field->name, ast_str_buffer(buf));
/* If the column length isn't long enough, give a chance to lengthen it. */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
}
} }
ESCAPE_STRING(buf, lookup); ESCAPE_STRING(buf, lookup);
...@@ -703,11 +682,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru ...@@ -703,11 +682,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
ESCAPE_STRING(buf, field->value); ESCAPE_STRING(buf, field->value);
ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", field->name, ast_str_buffer(buf)); ast_str_append(&where, 0, "%s `%s` = '%s'", first ? "" : " AND", field->name, ast_str_buffer(buf));
first = 0; first = 0;
/* If the column length isn't long enough, give a chance to lengthen it. */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
}
} }
first = 1; first = 1;
...@@ -721,11 +695,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru ...@@ -721,11 +695,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
ESCAPE_STRING(buf, field->value); ESCAPE_STRING(buf, field->value);
ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", field->name, ast_str_buffer(buf)); ast_str_append(&sql, 0, "%s `%s` = '%s'", first ? "" : ",", field->name, ast_str_buffer(buf));
first = 0; first = 0;
/* If the column length isn't long enough, give a chance to lengthen it. */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
internal_require(database, tablename, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
}
} }
release_table(table); release_table(table);
...@@ -759,7 +728,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru ...@@ -759,7 +728,6 @@ static int update2_mysql(const char *database, const char *tablename, const stru
static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields) static int store_mysql(const char *database, const char *table, const struct ast_variable *rt_fields)
{ {
struct mysql_conn *dbh; struct mysql_conn *dbh;
my_ulonglong insertid;
struct ast_str *sql = ast_str_thread_get(&sql_buf, 16); struct ast_str *sql = ast_str_thread_get(&sql_buf, 16);
struct ast_str *sql2 = ast_str_thread_get(&sql2_buf, 16); struct ast_str *sql2 = ast_str_thread_get(&sql2_buf, 16);
struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16); struct ast_str *buf = ast_str_thread_get(&scratch_buf, 16);
...@@ -792,15 +760,11 @@ static int store_mysql(const char *database, const char *table, const struct ast ...@@ -792,15 +760,11 @@ static int store_mysql(const char *database, const char *table, const struct ast
ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, field->name); ast_str_set(&sql, 0, "INSERT INTO %s (`%s`", table, field->name);
ast_str_set(&sql2, 0, ") VALUES ('%s'", ast_str_buffer(buf)); ast_str_set(&sql2, 0, ") VALUES ('%s'", ast_str_buffer(buf));
internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL);
while ((field = field->next)) { while ((field = field->next)) {
ESCAPE_STRING(buf, field->value); ESCAPE_STRING(buf, field->value);
if (internal_require(database, table, field->name, RQ_CHAR, ast_str_strlen(buf), SENTINEL) == 0) { ast_str_append(&sql, 0, ", `%s`", field->name);
ast_str_append(&sql, 0, ", `%s`", field->name); ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
ast_str_append(&sql2, 0, ", '%s'", ast_str_buffer(buf));
}
} }
ast_str_append(&sql, 0, "%s)", ast_str_buffer(sql2)); ast_str_append(&sql, 0, "%s)", ast_str_buffer(sql2));
ast_debug(1,"MySQL RealTime: Insert SQL: %s\n", ast_str_buffer(sql)); ast_debug(1,"MySQL RealTime: Insert SQL: %s\n", ast_str_buffer(sql));
...@@ -812,18 +776,11 @@ static int store_mysql(const char *database, const char *table, const struct ast ...@@ -812,18 +776,11 @@ static int store_mysql(const char *database, const char *table, const struct ast
return -1; return -1;
} }
/*!\note The return value is non-portable and may change in future versions. */
insertid = mysql_insert_id(&dbh->handle);
release_database(dbh); release_database(dbh);
ast_debug(1, "MySQL RealTime: row inserted on table: %s, id: %llu\n", table, insertid); ast_debug(1, "MySQL RealTime: row inserted on table: %s\n", table);
/* From http://dev.mysql.com/doc/mysql/en/mysql-affected-rows.html return 1;
* An integer greater than zero indicates the number of rows affected
* Zero indicates that no records were updated
* -1 indicates that the query returned an error (although, if the query failed, it should have been caught above.)
*/
return (int)insertid;
} }
static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields) static int destroy_mysql(const char *database, const char *table, const char *keyfield, const char *lookup, const struct ast_variable *rt_fields)
...@@ -989,105 +946,14 @@ static int unload_mysql(const char *database, const char *tablename) ...@@ -989,105 +946,14 @@ static int unload_mysql(const char *database, const char *tablename)
return cur ? 0 : -1; return cur ? 0 : -1;
} }
static int modify_mysql(const char *database, const char *tablename, struct columns *column, require_type type, int len)
{
/*!\note Cannot use ANY of the same scratch space as is used in other functions, as this one is interspersed. */
struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *escbuf = ast_str_thread_get(&modify2_buf, 100);
struct ast_str *typestr = ast_str_thread_get(&modify3_buf, 30);
int waschar = strncasecmp(column->type, "char", 4) == 0 ? 1 : 0;
int wasvarchar = strncasecmp(column->type, "varchar", 7) == 0 ? 1 : 0;
int res = 0;
struct mysql_conn *dbh;
if (!(dbh = find_database(database, 1))) {
return -1;
}
do {
if (type == RQ_CHAR || waschar || wasvarchar) {
if (wasvarchar) {
ast_str_set(&typestr, 0, "VARCHAR(%d)", len);
} else {
ast_str_set(&typestr, 0, "CHAR(%d)", len);
}
} else if (type == RQ_UINTEGER1) {
ast_str_set(&typestr, 0, "tinyint(3) unsigned");
} else if (type == RQ_INTEGER1) {
ast_str_set(&typestr, 0, "tinyint(4)");
} else if (type == RQ_UINTEGER2) {
ast_str_set(&typestr, 0, "smallint(5) unsigned");
} else if (type == RQ_INTEGER2) {
ast_str_set(&typestr, 0, "smallint(6)");
} else if (type == RQ_UINTEGER3) {
ast_str_set(&typestr, 0, "mediumint(8) unsigned");
} else if (type == RQ_INTEGER3) {
ast_str_set(&typestr, 0, "mediumint(8)");
} else if (type == RQ_UINTEGER4) {
ast_str_set(&typestr, 0, "int(10) unsigned");
} else if (type == RQ_INTEGER4) {
ast_str_set(&typestr, 0, "int(11)");
} else if (type == RQ_UINTEGER8) {
ast_str_set(&typestr, 0, "bigint(19) unsigned");
} else if (type == RQ_INTEGER8) {
ast_str_set(&typestr, 0, "bigint(20)");
} else if (type == RQ_DATETIME) {
ast_str_set(&typestr, 0, "datetime");
} else if (type == RQ_DATE) {
ast_str_set(&typestr, 0, "date");
} else if (type == RQ_FLOAT) {
ast_str_set(&typestr, 0, "FLOAT(%d,2)", len);
} else {
ast_log(LOG_ERROR, "Unknown type (should NEVER happen)\n");
res = -1;
break;
}
ast_str_set(&sql, 0, "ALTER TABLE %s MODIFY `%s` %s", tablename, column->name, ast_str_buffer(typestr));
if (!column->null) {
ast_str_append(&sql, 0, " NOT NULL");
}
if (!ast_strlen_zero(column->dflt)) {
ESCAPE_STRING(escbuf, column->dflt);
ast_str_append(&sql, 0, " DEFAULT '%s'", ast_str_buffer(escbuf));
}
if (!mysql_reconnect(dbh)) {
ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
res = -1;
break;
}
/* Execution. */
if (mysql_real_query(&dbh->handle, ast_str_buffer(sql), ast_str_strlen(sql))) {
ast_log(LOG_WARNING, "MySQL RealTime: Failed to modify database: %s\n", mysql_error(&dbh->handle));
ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql));
res = -1;
}
} while (0);
release_database(dbh);
return res;
}
#define PICK_WHICH_ALTER_ACTION(stringtype) \
if (table->database->requirements == RQ_WARN) { \
ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) { \
table_altered = 1; \
} else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) { \
table_altered = 1; \
} else { \
res = -1; \
}
static int require_mysql(const char *database, const char *tablename, va_list ap) static int require_mysql(const char *database, const char *tablename, va_list ap)
{ {
struct columns *column; struct columns *column;
struct tables *table = find_table(database, tablename); struct tables *table = find_table(database, tablename);
char *elm; char *elm;
int type, size, res = 0, table_altered = 0; int type;
int size;
int res = 0;
if (!table) { if (!table) {
ast_log(LOG_WARNING, "Table %s not found in database. This table should exist if you're using realtime.\n", tablename); ast_log(LOG_WARNING, "Table %s not found in database. This table should exist if you're using realtime.\n", tablename);
...@@ -1097,55 +963,54 @@ static int require_mysql(const char *database, const char *tablename, va_list ap ...@@ -1097,55 +963,54 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
while ((elm = va_arg(ap, char *))) { while ((elm = va_arg(ap, char *))) {
type = va_arg(ap, require_type); type = va_arg(ap, require_type);
size = va_arg(ap, int); size = va_arg(ap, int);
AST_LIST_TRAVERSE(&table->columns, column, list) { AST_LIST_TRAVERSE(&table->columns, column, list) {
if (strcmp(column->name, elm) == 0) { if (strcmp(column->name, elm) == 0) {
/* Char can hold anything, as long as it is large enough */ /* Char can hold anything, as long as it is large enough */
if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) { if (strncmp(column->type, "char", 4) == 0 || strncmp(column->type, "varchar", 7) == 0) {
if ((size > column->len) && column->len != -1) { if ((size > column->len) && column->len != -1) {
if (table->database->requirements == RQ_WARN) { 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);
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); res = -1;
res = -1;
} else if (modify_mysql(database, tablename, column, type, size) == 0) {
table_altered = 1;
} else {
res = -1;
}
} }
} else if (strcasestr(column->type, "unsigned")) { } else if (strcasestr(column->type, "unsigned")) {
if (!ast_rq_is_int(type)) { if (!ast_rq_is_int(type)) {
if (table->database->requirements == RQ_WARN) { ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n", database, tablename, column->name, column->type,
database, tablename, column->name, column->type, type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" : type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink");
type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "a rather stiff drink"); res = -1;
res = -1;
} else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
table_altered = 1;
} else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
table_altered = 1;
} else {
res = -1;
}
} else if (strncasecmp(column->type, "tinyint", 1) == 0) { } else if (strncasecmp(column->type, "tinyint", 1) == 0) {
if (type != RQ_UINTEGER1) { if (type != RQ_UINTEGER1) {
PICK_WHICH_ALTER_ACTION(unsigned tinyint) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} else if (strncasecmp(column->type, "smallint", 1) == 0) { } else if (strncasecmp(column->type, "smallint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_UINTEGER2) {
PICK_WHICH_ALTER_ACTION(unsigned smallint) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} else if (strncasecmp(column->type, "mediumint", 1) == 0) { } else if (strncasecmp(column->type, "mediumint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 && type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_UINTEGER3) { type != RQ_UINTEGER3) {
PICK_WHICH_ALTER_ACTION(unsigned mediumint) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} else if (strncasecmp(column->type, "int", 1) == 0) { } else if (strncasecmp(column->type, "int", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 && type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_UINTEGER3 && type != RQ_INTEGER3 && type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_UINTEGER4) { type != RQ_UINTEGER4) {
PICK_WHICH_ALTER_ACTION(unsigned int) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} else if (strncasecmp(column->type, "bigint", 1) == 0) { } else if (strncasecmp(column->type, "bigint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
...@@ -1153,45 +1018,52 @@ static int require_mysql(const char *database, const char *tablename, va_list ap ...@@ -1153,45 +1018,52 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
type != RQ_UINTEGER3 && type != RQ_INTEGER3 && type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_UINTEGER4 && type != RQ_INTEGER4 && type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
type != RQ_UINTEGER8) { type != RQ_UINTEGER8) {
PICK_WHICH_ALTER_ACTION(unsigned bigint) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} }
} else if (strcasestr(column->type, "int")) { } else if (strcasestr(column->type, "int")) {
if (!ast_rq_is_int(type)) { if (!ast_rq_is_int(type)) {
if (table->database->requirements == RQ_WARN) { ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n",
ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' cannot be type '%s' (need %s)\n", database, tablename, column->name, column->type,
database, tablename, column->name, column->type, type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" :
type == RQ_CHAR ? "char" : type == RQ_FLOAT ? "float" : type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" :
type == RQ_DATETIME ? "datetime" : type == RQ_DATE ? "date" : "to get a life, rather than writing silly error messages");
"to get a life, rather than writing silly error messages"); res = -1;
res = -1;
} else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
table_altered = 1;
} else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
table_altered = 1;
} else {
res = -1;
}
} else if (strncasecmp(column->type, "tinyint", 1) == 0) { } else if (strncasecmp(column->type, "tinyint", 1) == 0) {
if (type != RQ_INTEGER1) { if (type != RQ_INTEGER1) {
PICK_WHICH_ALTER_ACTION(tinyint) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} else if (strncasecmp(column->type, "smallint", 1) == 0) { } else if (strncasecmp(column->type, "smallint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_INTEGER2) { if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && type != RQ_INTEGER2) {
PICK_WHICH_ALTER_ACTION(smallint) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} else if (strncasecmp(column->type, "mediumint", 1) == 0) { } else if (strncasecmp(column->type, "mediumint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 && type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_INTEGER3) { type != RQ_INTEGER3) {
PICK_WHICH_ALTER_ACTION(mediumint) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} else if (strncasecmp(column->type, "int", 1) == 0) { } else if (strncasecmp(column->type, "int", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
type != RQ_UINTEGER2 && type != RQ_INTEGER2 && type != RQ_UINTEGER2 && type != RQ_INTEGER2 &&
type != RQ_UINTEGER3 && type != RQ_INTEGER3 && type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_INTEGER4) { type != RQ_INTEGER4) {
PICK_WHICH_ALTER_ACTION(int) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} else if (strncasecmp(column->type, "bigint", 1) == 0) { } else if (strncasecmp(column->type, "bigint", 1) == 0) {
if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 && if (type != RQ_UINTEGER1 && type != RQ_INTEGER1 &&
...@@ -1199,137 +1071,41 @@ static int require_mysql(const char *database, const char *tablename, va_list ap ...@@ -1199,137 +1071,41 @@ static int require_mysql(const char *database, const char *tablename, va_list ap
type != RQ_UINTEGER3 && type != RQ_INTEGER3 && type != RQ_UINTEGER3 && type != RQ_INTEGER3 &&
type != RQ_UINTEGER4 && type != RQ_INTEGER4 && type != RQ_UINTEGER4 && type != RQ_INTEGER4 &&
type != RQ_INTEGER8) { type != RQ_INTEGER8) {
PICK_WHICH_ALTER_ACTION(bigint) ast_log(LOG_WARNING, "Realtime table %s@%s: column '%s' may not be large enough for " \
"the required data length: %d (detected stringtype)\n", \
tablename, database, column->name, size); \
res = -1; \
} }
} }
} else if (strncmp(column->type, "float", 5) == 0) { } else if (strncmp(column->type, "float", 5) == 0) {
if (!ast_rq_is_int(type) && type != RQ_FLOAT) { if (!ast_rq_is_int(type) && type != RQ_FLOAT) {
if (table->database->requirements == RQ_WARN) { ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type); res = -1;
res = -1;
} else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
table_altered = 1;
} else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
table_altered = 1;
} else {
res = -1;
}
} }
} else if (strncmp(column->type, "datetime", 8) == 0 || strncmp(column->type, "timestamp", 9) == 0) { } else if (strncmp(column->type, "datetime", 8) == 0 || strncmp(column->type, "timestamp", 9) == 0) {
if (type != RQ_DATETIME) { if (type != RQ_DATETIME) {
if (table->database->requirements == RQ_WARN) { ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type); res = -1;
res = -1;
} else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
table_altered = 1;
} else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
table_altered = 1;
} else {
res = -1;
}
} }
} else if (strncmp(column->type, "date", 4) == 0) { } else if (strncmp(column->type, "date", 4) == 0) {
if (type != RQ_DATE) { if (type != RQ_DATE) {
if (table->database->requirements == RQ_WARN) { ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
ast_log(LOG_WARNING, "Realtime table %s@%s: Column %s cannot be a %s\n", tablename, database, column->name, column->type);
res = -1;
} else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
table_altered = 1;
} else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
table_altered = 1;
} else {
res = -1;
}
}
} else { /* Other, possibly unsupported types? */
if (table->database->requirements == RQ_WARN) {
ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name);
res = -1; res = -1;
} else if (table->database->requirements == RQ_CREATECLOSE && modify_mysql(database, tablename, column, type, size) == 0) {
table_altered = 1;
} else if (table->database->requirements == RQ_CREATECHAR && modify_mysql(database, tablename, column, RQ_CHAR, size) == 0) {
table_altered = 1;
} else {
} }
} else { /* Other, possibly unsupported types? */
ast_log(LOG_WARNING, "Possibly unsupported column type '%s' on column '%s'\n", column->type, column->name);
res = -1;
} }
break; break;
} }
} }
if (!column) { if (!column) {
if (table->database->requirements == RQ_WARN) { ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
ast_log(LOG_WARNING, "Table %s requires a column '%s' of size '%d', but no such column exists.\n", tablename, elm, size);
} else {
struct ast_str *sql = ast_str_thread_get(&modify_buf, 100), *fieldtype = ast_str_thread_get(&modify3_buf, 16);
if (table->database->requirements == RQ_CREATECHAR || type == RQ_CHAR) {
ast_str_set(&fieldtype, 0, "CHAR(%d)", size);
} else if (type == RQ_UINTEGER1 || type == RQ_UINTEGER2 || type == RQ_UINTEGER3 || type == RQ_UINTEGER4 || type == RQ_UINTEGER8) {
if (type == RQ_UINTEGER1) {
ast_str_set(&fieldtype, 0, "TINYINT(3) UNSIGNED");
} else if (type == RQ_UINTEGER2) {
ast_str_set(&fieldtype, 0, "SMALLINT(5) UNSIGNED");
} else if (type == RQ_UINTEGER3) {
ast_str_set(&fieldtype, 0, "MEDIUMINT(8) UNSIGNED");
} else if (type == RQ_UINTEGER4) {
ast_str_set(&fieldtype, 0, "INT(10) UNSIGNED");
} else if (type == RQ_UINTEGER8) {
ast_str_set(&fieldtype, 0, "BIGINT(20) UNSIGNED");
} else {
ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to squash Tokyo.\n");
continue;
}
} else if (ast_rq_is_int(type)) {
if (type == RQ_INTEGER1) {
ast_str_set(&fieldtype, 0, "TINYINT(3)");
} else if (type == RQ_INTEGER2) {
ast_str_set(&fieldtype, 0, "SMALLINT(5)");
} else if (type == RQ_INTEGER3) {
ast_str_set(&fieldtype, 0, "MEDIUMINT(8)");
} else if (type == RQ_INTEGER4) {
ast_str_set(&fieldtype, 0, "INT(10)");
} else if (type == RQ_INTEGER8) {
ast_str_set(&fieldtype, 0, "BIGINT(20)");
} else {
ast_log(LOG_WARNING, "Somebody should check this code for a rather large bug... it's about to eat Cincinnati.\n");
continue;
}
} else if (type == RQ_FLOAT) {
ast_str_set(&fieldtype, 0, "FLOAT");
} else if (type == RQ_DATE) {
ast_str_set(&fieldtype, 0, "DATE");
} else if (type == RQ_DATETIME) {
ast_str_set(&fieldtype, 0, "DATETIME");
} else {
continue;
}
ast_str_set(&sql, 0, "ALTER TABLE %s ADD COLUMN %s %s", tablename, elm, ast_str_buffer(fieldtype));
ast_mutex_lock(&table->database->lock);
if (!mysql_reconnect(table->database)) {
ast_mutex_unlock(&table->database->lock);
ast_log(LOG_ERROR, "Unable to add column: %s\n", ast_str_buffer(sql));
continue;
}
/* Execution. */
if (mysql_real_query(&table->database->handle, ast_str_buffer(sql), ast_str_strlen(sql))) {
ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
ast_debug(1, "MySQL RealTime: Query: %s\n", ast_str_buffer(sql));
ast_debug(1, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&table->database->handle));
} else {
table_altered = 1;
}
}
} }
} }
release_table(table); release_table(table);
/* If we altered the table, we must refresh the cache */
if (table_altered) {
unload_mysql(database, tablename);
release_table(find_table(database, tablename));
}
return res; return res;
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment