[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