changeset 4511:3f808dd8f568 HEAD

If invalid key is given to dict_set() or dict_atomic_inc() fail the whole transaction in commit. Keep track of changes that are actually done, so if nothing has changed in transaction don't even bother to commit it.
author Timo Sirainen <tss@iki.fi>
date Sun, 30 Jul 2006 21:06:09 +0300
parents 96f0677c2bca
children b5d4c1e9a492
files src/lib-dict/dict-private.h src/lib-dict/dict-sql.c src/lib-dict/dict.c
diffstat 3 files changed, 30 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-dict/dict-private.h	Sun Jul 30 21:03:18 2006 +0300
+++ b/src/lib-dict/dict-private.h	Sun Jul 30 21:06:09 2006 +0300
@@ -40,6 +40,8 @@
 
 struct dict_transaction_context {
 	struct dict *dict;
+
+	unsigned int changed:1;
 };
 
 #endif
--- a/src/lib-dict/dict-sql.c	Sun Jul 30 21:03:18 2006 +0300
+++ b/src/lib-dict/dict-sql.c	Sun Jul 30 21:06:09 2006 +0300
@@ -31,6 +31,9 @@
 	struct dict_transaction_context ctx;
 
 	struct sql_transaction_context *sql_ctx;
+
+	unsigned int failed:1;
+	unsigned int changed:1;
 };
 
 static int sql_dict_read_config(struct sql_dict *dict, const char *path)
@@ -275,9 +278,17 @@
 	const char *error;
 	int ret;
 
-	ret = sql_transaction_commit_s(&ctx->sql_ctx, &error);
-	if (ret < 0)
-		i_error("sql dict: commit failed: %s", error);
+	if (ctx->failed) {
+		sql_transaction_rollback(&ctx->sql_ctx);
+		ret = -1;
+	} else if (_ctx->changed) {
+		ret = sql_transaction_commit_s(&ctx->sql_ctx, &error);
+		if (ret < 0)
+			i_error("sql dict: commit failed: %s", error);
+	} else {
+		/* nothing to be done */
+		ret = 0;
+	}
 	i_free(ctx);
 	return ret;
 }
@@ -287,7 +298,8 @@
 	struct sql_dict_transaction_context *ctx =
 		(struct sql_dict_transaction_context *)_ctx;
 
-	sql_transaction_rollback(&ctx->sql_ctx);
+	if (_ctx->changed)
+		sql_transaction_rollback(&ctx->sql_ctx);
 	i_free(ctx);
 }
 
@@ -300,8 +312,11 @@
 	const char *query;
 	bool priv;
 
-	if (sql_path_fix(&key, &priv) < 0)
+	if (sql_path_fix(&key, &priv) < 0) {
+		i_error("sql dict: Invalid key: %s", key);
+		ctx->failed = TRUE;
 		return;
+	}
 
 	t_push();
 	if (priv) {
@@ -338,8 +353,11 @@
 	const char *query;
 	bool priv;
 
-	if (sql_path_fix(&key, &priv) < 0)
+	if (sql_path_fix(&key, &priv) < 0) {
+		i_error("sql dict: Invalid key: %s", key);
+		ctx->failed = TRUE;
 		return;
+	}
 
 	t_push();
 	if (priv) {
--- a/src/lib-dict/dict.c	Sun Jul 30 21:03:18 2006 +0300
+++ b/src/lib-dict/dict.c	Sun Jul 30 21:06:09 2006 +0300
@@ -125,11 +125,14 @@
 	      const char *key, const char *value)
 {
 	ctx->dict->v.set(ctx, key, value);
+	ctx->changed = TRUE;
 }
 
 void dict_atomic_inc(struct dict_transaction_context *ctx,
 		     const char *key, long long diff)
 {
-	if (diff != 0)
+	if (diff != 0) {
 		ctx->dict->v.atomic_inc(ctx, key, diff);
+		ctx->changed = TRUE;
+	}
 }