changeset 7966:54225d0b6e2b HEAD

dict-sql: Only MySQL supports "INSERT .. ON DUPLICATE KEY". With others just use the INSERT and let created triggers handle updating existing rows.
author Timo Sirainen <tss@iki.fi>
date Mon, 07 Jul 2008 18:44:16 +0530
parents 72a560a00def
children 6d9f2185b9e0
files src/lib-dict/dict-sql.c
diffstat 1 files changed, 42 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-dict/dict-sql.c	Wed Jul 02 09:45:24 2008 +0300
+++ b/src/lib-dict/dict-sql.c	Mon Jul 07 18:44:16 2008 +0530
@@ -22,6 +22,8 @@
 
 	const char *connect_string, *username;
 	const char *table, *select_field, *where_field, *username_field;
+
+	unsigned int has_on_duplicate_key:1;
 };
 
 struct sql_dict_iterate_context {
@@ -133,6 +135,9 @@
 		return NULL;
 	}
 
+	/* currently pgsql and sqlite don't support "ON DUPLICATE KEY" */
+	dict->has_on_duplicate_key = strcmp(driver->name, "mysql") == 0;
+
 	dict->db = sql_pool_new(dict_sql_pool, driver->name,
 				dict->connect_string);
 	return &dict->dict;
@@ -352,27 +357,29 @@
 sql_dict_set_query(struct sql_dict *dict, const char *key, const char *value,
 		   bool priv)
 {
+	string_t *str;
+
+	str = t_str_new(256);
 	if (priv) {
-		return t_strdup_printf(
-			"INSERT INTO %s (%s, %s, %s) VALUES ('%s', '%s', '%s') "
-			"ON DUPLICATE KEY UPDATE %s = '%s'",
-			dict->table, dict->select_field, dict->where_field,
-			dict->username_field,
-			sql_escape_string(dict->db, value),
-			sql_escape_string(dict->db, key),
-			sql_escape_string(dict->db, dict->username),
-			dict->select_field,
-			sql_escape_string(dict->db, value));
+		str_printfa(str, "INSERT INTO %s (%s, %s, %s) "
+			    "VALUES ('%s', '%s', '%s')",
+			    dict->table, dict->select_field, dict->where_field,
+			    dict->username_field,
+			    sql_escape_string(dict->db, value),
+			    sql_escape_string(dict->db, key),
+			    sql_escape_string(dict->db, dict->username));
 	} else {
-		return t_strdup_printf(
-			"INSERT INTO %s (%s, %s) VALUES ('%s', '%s') "
-			"ON DUPLICATE KEY UPDATE %s = '%s'",
-			dict->table, dict->select_field, dict->where_field,
-			sql_escape_string(dict->db, value),
-			sql_escape_string(dict->db, key),
-                        dict->select_field,
-			sql_escape_string(dict->db, value));
+		str_printfa(str, "INSERT INTO %s (%s, %s) VALUES ('%s', '%s')",
+			    dict->table, dict->select_field, dict->where_field,
+			    sql_escape_string(dict->db, value),
+			    sql_escape_string(dict->db, key));
 	}
+	if (dict->has_on_duplicate_key) {
+		str_printfa(str, " ON DUPLICATE KEY UPDATE %s = '%s'",
+			    dict->select_field,
+			    sql_escape_string(dict->db, value));
+	}
+	return str_c(str);
 }
 
 static void sql_dict_set(struct dict_transaction_context *_ctx,
@@ -441,23 +448,26 @@
 sql_dict_atomic_inc_query(struct sql_dict *dict, const char *key,
 			  long long diff, bool priv)
 {
+	string_t *str;
+
+	str = t_str_new(256);
 	if (priv) {
-		return t_strdup_printf(
-			"INSERT INTO %s (%s, %s, %s) VALUES (%lld, '%s', '%s') "
-			"ON DUPLICATE KEY UPDATE %s = %s + %lld",
-			dict->table, dict->select_field, dict->where_field,
-			dict->username_field,
-                        diff, sql_escape_string(dict->db, key),
-			sql_escape_string(dict->db, dict->username),
-                        dict->select_field, dict->select_field, diff);
+		str_printfa(str, "INSERT INTO %s (%s, %s, %s) "
+			    "VALUES (%lld, '%s', '%s')",
+			    dict->table, dict->select_field, dict->where_field,
+			    dict->username_field,
+			    diff, sql_escape_string(dict->db, key),
+			    sql_escape_string(dict->db, dict->username));
 	} else {
-		return t_strdup_printf(
-			"INSERT INTO %s (%s, %s) VALUES (%lld, '%s') "
-			"ON DUPLICATE KEY UPDATE %s = %s + %lld",
-			dict->table, dict->select_field, dict->where_field,
-                        diff, sql_escape_string(dict->db, key),
-                        dict->select_field, dict->select_field, diff);
+		str_printfa(str, "INSERT INTO %s (%s, %s) VALUES (%lld, '%s')",
+			    dict->table, dict->select_field, dict->where_field,
+			    diff, sql_escape_string(dict->db, key));
 	}
+	if (dict->has_on_duplicate_key) {
+		str_printfa(str, " ON DUPLICATE KEY UPDATE %s = %s + %lld",
+			    dict->select_field, dict->select_field, diff);
+	}
+	return str_c(str);
 }
 
 static void sql_dict_atomic_inc(struct dict_transaction_context *_ctx,