[asterisk-addons-commits] tilghman: trunk r677 - /trunk/res/res_config_mysql.c
SVN commits to the Asterisk addons project
asterisk-addons-commits at lists.digium.com
Mon Oct 13 19:12:43 CDT 2008
Author: tilghman
Date: Mon Oct 13 19:12:42 2008
New Revision: 677
URL: http://svn.digium.com/view/asterisk-addons?view=rev&rev=677
Log:
Merge branch for -addons, relating to the realtime_update2 branch. See commit
number 148570 on the asterisk repository for more information.
Modified:
trunk/res/res_config_mysql.c
Modified: trunk/res/res_config_mysql.c
URL: http://svn.digium.com/view/asterisk-addons/trunk/res/res_config_mysql.c?view=diff&rev=677&r1=676&r2=677
==============================================================================
--- trunk/res/res_config_mysql.c (original)
+++ trunk/res/res_config_mysql.c Mon Oct 13 19:12:42 2008
@@ -109,6 +109,10 @@
AST_CLI_DEFINE(handle_cli_realtime_mysql_cache, "Shows cached tables within the MySQL realtime driver"),
};
+AST_THREADSTORAGE(sql_buf);
+AST_THREADSTORAGE(where_buf);
+AST_THREADSTORAGE(escapebuf_buf);
+
static int internal_require(const char *database, const char *table, ...)
{
va_list ap;
@@ -486,14 +490,7 @@
return -1;
}
- /* Check that the column exists in the table */
- AST_LIST_TRAVERSE(&table->columns, column, list) {
- if (strcmp(column->name, keyfield) == 0) {
- break;
- }
- }
-
- if (!column) {
+ if (!(column = find_column(table, keyfield))) {
ast_log(LOG_ERROR, "MySQL RealTime: Updating on column '%s', but that column does not exist within the table '%s'!\n", keyfield, tablename);
ast_mutex_unlock(&table->lock);
ast_free(sql);
@@ -589,6 +586,123 @@
ast_free(sql);
ast_free(buf);
+
+ numrows = mysql_affected_rows(&dbwrite.handle);
+ ast_mutex_unlock(&dbwrite.lock);
+
+ ast_debug(1, "MySQL RealTime: Updated %llu rows on table: %s\n", numrows, tablename);
+
+ /* From http://dev.mysql.com/doc/mysql/en/mysql-affected-rows.html
+ * 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)numrows;
+}
+
+#define ESCAPE_STRING(buf, var) \
+ do { \
+ size_t size; \
+ if ((size = strlen(var)) * 2 + 1 > (buf)->len) { \
+ ast_str_make_space(&(buf), size * 2 + 1); \
+ } \
+ mysql_real_escape_string(&dbwrite.handle, (buf)->str, var, size); \
+ } while (0)
+
+static int update2_mysql(const char *database, const char *tablename, va_list ap)
+{
+ my_ulonglong numrows;
+ int first = 1;
+ const char *newparam, *newval;
+ struct ast_str *sql = ast_str_thread_get(&sql_buf, 100), *buf = ast_str_thread_get(&escapebuf_buf, 100);
+ struct ast_str *where = ast_str_thread_get(&where_buf, 100);
+ struct tables *table;
+ struct columns *column = NULL;
+
+ if (!tablename) {
+ ast_log(LOG_WARNING, "MySQL RealTime: No table specified.\n");
+ return -1;
+ }
+
+ if (!(table = find_table(tablename))) {
+ ast_log(LOG_ERROR, "Table '%s' does not exist!!\n", tablename);
+ return -1;
+ }
+
+ if (!sql || !buf || !where) {
+ return -1;
+ }
+
+ ast_str_set(&sql, 0, "UPDATE %s SET", tablename);
+ ast_str_set(&where, 0, "WHERE");
+
+ /* Must connect to the server before anything else, as the escape function requires the mysql handle. */
+ ast_mutex_lock(&dbwrite.lock);
+ if (!mysql_reconnect(&dbwrite)) {
+ ast_mutex_unlock(&table->lock);
+ ast_mutex_unlock(&dbwrite.lock);
+ return -1;
+ }
+
+ while ((newparam = va_arg(ap, const char *))) {
+ if (!(column = find_column(table, newparam))) {
+ ast_log(LOG_ERROR, "Updating on column '%s', but that column does not exist within the table '%s'!\n", newparam, tablename);
+ ast_mutex_unlock(&table->lock);
+ return -1;
+ }
+ if (!(newval = va_arg(ap, const char *))) {
+ ast_log(LOG_ERROR, "Invalid arguments: no value specified for column '%s' on '%s@%s'\n", newparam, tablename, database);
+ ast_mutex_unlock(&table->lock);
+ return -1;
+ }
+ ESCAPE_STRING(buf, newval);
+ ast_str_append(&where, 0, "%s %s='%s'", first ? "" : " AND", newparam, buf->str);
+ 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, newparam, RQ_CHAR, buf->used);
+ }
+ }
+
+ first = 1;
+ while ((newparam = va_arg(ap, const char *))) {
+ if (!(newval = va_arg(ap, const char *))) {
+ ast_log(LOG_ERROR, "Invalid arguments: no value specified for column '%s' on '%s@%s'\n", newparam, tablename, database);
+ ast_mutex_unlock(&table->lock);
+ return -1;
+ }
+
+ /* If the column is not within the table, then skip it */
+ if (!(column = find_column(table, newparam))) {
+ ast_log(LOG_WARNING, "Attempted to update column '%s' in table '%s', but column does not exist!\n", newparam, tablename);
+ continue;
+ }
+
+ ESCAPE_STRING(buf, newval);
+ ast_str_append(&sql, 0, "%s %s = '%s'", first ? "" : ",", newparam, buf->str);
+
+ /* 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, newparam, RQ_CHAR, strlen(newval));
+ }
+ }
+ va_end(ap);
+ ast_mutex_unlock(&table->lock);
+
+ ast_str_append(&sql, 0, " %s", where->str);
+
+ ast_debug(1, "MySQL RealTime: Update SQL: %s\n", sql->str);
+
+ /* Execution. */
+ if (mysql_real_query(&dbwrite.handle, sql->str, sql->used)) {
+ ast_log(LOG_WARNING, "MySQL RealTime: Failed to query database. Check debug for more info.\n");
+ ast_debug(1, "MySQL RealTime: Query: %s\n", sql->str);
+ ast_debug(1, "MySQL RealTime: Query Failed because: %s\n", mysql_error(&dbwrite.handle));
+ ast_mutex_unlock(&dbwrite.lock);
+ return -1;
+ }
numrows = mysql_affected_rows(&dbwrite.handle);
ast_mutex_unlock(&dbwrite.lock);
@@ -1205,6 +1319,7 @@
.store_func = store_mysql,
.destroy_func = destroy_mysql,
.update_func = update_mysql,
+ .update2_func = update2_mysql,
.require_func = require_mysql,
.unload_func = unload_mysql,
};
More information about the asterisk-addons-commits
mailing list