changeset 10659:7309b5c84ca9 HEAD

lib-dict: Changed dict_iterate API.
author Timo Sirainen <tss@iki.fi>
date Sun, 07 Feb 2010 16:27:18 +0200
parents 9780cd3cc48a
children 56b1d4dd9c7d
files src/dict/dict-commands.c src/dict/dict-connection.c src/lib-dict/dict-client.c src/lib-dict/dict-db.c src/lib-dict/dict-file.c src/lib-dict/dict-private.h src/lib-dict/dict-sql.c src/lib-dict/dict.c src/lib-dict/dict.h src/plugins/acl/acl-lookup-dict.c src/plugins/expire/expire-tool.c
diffstat 11 files changed, 84 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/src/dict/dict-commands.c	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/dict/dict-commands.c	Sun Feb 07 16:27:18 2010 +0200
@@ -52,7 +52,7 @@
 
 	str = t_str_new(256);
 	o_stream_cork(conn->output);
-	while ((ret = dict_iterate(conn->iter_ctx, &key, &value)) > 0) {
+	while (dict_iterate(conn->iter_ctx, &key, &value)) {
 		str_truncate(str, 0);
 		str_printfa(str, "%c%s\t%s\n", DICT_PROTOCOL_REPLY_OK,
 			    key, value);
@@ -60,25 +60,25 @@
 
 		if (o_stream_get_buffer_used_size(conn->output) >
 		    DICT_OUTPUT_OPTIMAL_SIZE) {
-			if (o_stream_flush(conn->output) <= 0)
-				break;
+			if (o_stream_flush(conn->output) <= 0) {
+				/* continue later */
+				o_stream_uncork(conn->output);
+				return 0;
+			}
 			/* flushed everything, continue */
 		}
 	}
 
-	if (ret <= 0) {
-		/* finished iterating */
-		o_stream_unset_flush_callback(conn->output);
-		dict_iterate_deinit(&conn->iter_ctx);
+	/* finished iterating */
+	o_stream_unset_flush_callback(conn->output);
 
-		str_truncate(str, 0);
-		if (ret < 0)
-			str_append_c(str, DICT_PROTOCOL_REPLY_FAIL);
-		str_append_c(str, '\n');
-		o_stream_send(conn->output, str_data(str), str_len(str));
-	}
+	str_truncate(str, 0);
+	if ((ret = dict_iterate_deinit(&conn->iter_ctx)) < 0)
+		str_append_c(str, DICT_PROTOCOL_REPLY_FAIL);
+	str_append_c(str, '\n');
+	o_stream_send(conn->output, str_data(str), str_len(str));
 	o_stream_uncork(conn->output);
-	return ret <= 0 ? 1 : 0;
+	return 1;
 }
 
 static int cmd_iterate(struct dict_connection *conn, const char *line)
--- a/src/dict/dict-connection.c	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/dict/dict-connection.c	Sun Feb 07 16:27:18 2010 +0200
@@ -166,7 +166,7 @@
 	}
 
 	if (conn->iter_ctx != NULL)
-		dict_iterate_deinit(&conn->iter_ctx);
+		(void)dict_iterate_deinit(&conn->iter_ctx);
 
 	io_remove(&conn->io);
 	i_stream_destroy(&conn->input);
--- a/src/lib-dict/dict-client.c	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/lib-dict/dict-client.c	Sun Feb 07 16:27:18 2010 +0200
@@ -493,8 +493,8 @@
 	return &ctx->ctx;
 }
 
-static int client_dict_iterate(struct dict_iterate_context *_ctx,
-			       const char **key_r, const char **value_r)
+static bool client_dict_iterate(struct dict_iterate_context *_ctx,
+				const char **key_r, const char **value_r)
 {
 	struct client_dict_iterate_context *ctx =
 		(struct client_dict_iterate_context *)_ctx;
@@ -502,16 +502,18 @@
 	char *line, *value;
 
 	if (ctx->failed)
-		return -1;
+		return FALSE;
 
 	/* read next reply */
 	line = client_dict_read_line(dict);
-	if (line == NULL)
-		return -1;
+	if (line == NULL) {
+		ctx->failed = TRUE;
+		return FALSE;
+	}
 
 	if (*line == '\0') {
 		/* end of iteration */
-		return 0;
+		return FALSE;
 	}
 
 	/* line contains key \t value */
@@ -522,7 +524,8 @@
 		value = strchr(++line, '\t');
 		break;
 	case DICT_PROTOCOL_REPLY_FAIL:
-		return -1;
+		ctx->failed = TRUE;
+		return FALSE;
 	default:
 		value = NULL;
 		break;
@@ -530,24 +533,27 @@
 	if (value == NULL) {
 		/* broken protocol */
 		i_error("dict client (%s) sent broken reply", dict->path);
-		return -1;
+		ctx->failed = TRUE;
+		return FALSE;
 	}
 	*value++ = '\0';
 
 	*key_r = p_strdup(ctx->pool, dict_client_unescape(line));
 	*value_r = p_strdup(ctx->pool, dict_client_unescape(value));
-	return 1;
+	return TRUE;
 }
 
-static void client_dict_iterate_deinit(struct dict_iterate_context *_ctx)
+static int client_dict_iterate_deinit(struct dict_iterate_context *_ctx)
 {
 	struct client_dict *dict = (struct client_dict *)_ctx->dict;
 	struct client_dict_iterate_context *ctx =
 		(struct client_dict_iterate_context *)_ctx;
+	int ret = ctx->failed ? -1 : 0;
 
 	pool_unref(&ctx->pool);
 	i_free(ctx);
 	dict->in_iteration = FALSE;
+	return ret;
 }
 
 static struct dict_transaction_context *
--- a/src/lib-dict/dict-db.c	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/lib-dict/dict-db.c	Sun Feb 07 16:27:18 2010 +0200
@@ -34,6 +34,7 @@
 			    const char **key_r, const char **value_r);
 
 	enum dict_iterate_flags flags;
+	bool failed;
 };
 
 struct db_dict_transaction_context {
@@ -341,24 +342,30 @@
 	return &ctx->ctx;
 }
 
-static int db_dict_iterate(struct dict_iterate_context *_ctx,
-			   const char **key_r, const char **value_r)
+static bool db_dict_iterate(struct dict_iterate_context *_ctx,
+			    const char **key_r, const char **value_r)
 {
 	struct db_dict_iterate_context *ctx =
 		(struct db_dict_iterate_context *)_ctx;
+	int ret;
 
-	return ctx->iterate_next(ctx, key_r, value_r);
+	ret = ctx->iterate_next(ctx, key_r, value_r);
+	if (ret < 0)
+		ctx->failed = TRUE;
+	return ret > 0;
 }
 
-static void db_dict_iterate_deinit(struct dict_iterate_context *_ctx)
+static int db_dict_iterate_deinit(struct dict_iterate_context *_ctx)
 {
 	struct db_dict_iterate_context *ctx =
 		(struct db_dict_iterate_context *)_ctx;
+	int ret = ctx->failed ? -1 : 0;
 
 	ctx->cursor->c_close(ctx->cursor);
 	pool_unref(&ctx->pool);
 	i_free(ctx->path);
 	i_free(ctx);
+	return ret;
 }
 
 static struct dict_transaction_context *
--- a/src/lib-dict/dict-file.c	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/lib-dict/dict-file.c	Sun Feb 07 16:27:18 2010 +0200
@@ -181,8 +181,8 @@
 	return &ctx->ctx;
 }
 
-static int file_dict_iterate(struct dict_iterate_context *_ctx,
-			     const char **key_r, const char **value_r)
+static bool file_dict_iterate(struct dict_iterate_context *_ctx,
+			      const char **key_r, const char **value_r)
 {
 	struct file_dict_iterate_context *ctx =
 		(struct file_dict_iterate_context *)_ctx;
@@ -198,19 +198,21 @@
 
 		*key_r = key;
 		*value_r = value;
-		return 1;
+		return TRUE;
 	}
-	return ctx->failed ? -1 : 0;
+	return FALSE;
 }
 
-static void file_dict_iterate_deinit(struct dict_iterate_context *_ctx)
+static int file_dict_iterate_deinit(struct dict_iterate_context *_ctx)
 {
 	struct file_dict_iterate_context *ctx =
 		(struct file_dict_iterate_context *)_ctx;
+	int ret = ctx->failed ? -1 : 0;
 
 	hash_table_iterate_deinit(&ctx->iter);
 	i_free(ctx->path);
 	i_free(ctx);
+	return ret;
 }
 
 static struct dict_transaction_context *
--- a/src/lib-dict/dict-private.h	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/lib-dict/dict-private.h	Sun Feb 07 16:27:18 2010 +0200
@@ -16,9 +16,9 @@
 	struct dict_iterate_context *
 		(*iterate_init)(struct dict *dict, const char *path,
 				enum dict_iterate_flags flags);
-	int (*iterate)(struct dict_iterate_context *ctx,
-		       const char **key_r, const char **value_r);
-	void (*iterate_deinit)(struct dict_iterate_context *ctx);
+	bool (*iterate)(struct dict_iterate_context *ctx,
+			const char **key_r, const char **value_r);
+	int (*iterate_deinit)(struct dict_iterate_context *ctx);
 
 	struct dict_transaction_context *(*transaction_init)(struct dict *dict);
 	int (*transaction_commit)(struct dict_transaction_context *ctx,
--- a/src/lib-dict/dict-sql.c	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/lib-dict/dict-sql.c	Sun Feb 07 16:27:18 2010 +0200
@@ -42,6 +42,7 @@
 	string_t *key;
 	const struct dict_sql_map *map;
 	unsigned int key_prefix_len, pattern_prefix_len, next_map_idx;
+	bool failed;
 };
 
 struct sql_dict_inc_row {
@@ -397,8 +398,8 @@
 	return &ctx->ctx;
 }
 
-static int sql_dict_iterate(struct dict_iterate_context *_ctx,
-			    const char **key_r, const char **value_r)
+static bool sql_dict_iterate(struct dict_iterate_context *_ctx,
+			     const char **key_r, const char **value_r)
 {
 	struct sql_dict_iterate_context *ctx =
 		(struct sql_dict_iterate_context *)_ctx;
@@ -406,18 +407,21 @@
 	unsigned int i, count;
 	int ret;
 
-	if (ctx->result == NULL)
-		return -1;
+	if (ctx->result == NULL) {
+		ctx->failed = TRUE;
+		return FALSE;
+	}
 
 	while ((ret = sql_result_next_row(ctx->result)) == 0) {
 		/* see if there are more results in the next map */
 		if (!sql_dict_iterate_next_query(ctx))
-			return 0;
+			return FALSE;
 	}
 	if (ret < 0) {
+		ctx->failed = TRUE;
 		i_error("dict sql iterate failed: %s",
 			sql_result_get_error(ctx->result));
-		return ret;
+		return FALSE;
 	}
 
 	/* convert fetched row to dict key */
@@ -442,19 +446,21 @@
 
 	*key_r = str_c(ctx->key);
 	*value_r = sql_result_get_field_value(ctx->result, 0);
-	return 1;
+	return TRUE;
 }
 
-static void sql_dict_iterate_deinit(struct dict_iterate_context *_ctx)
+static int sql_dict_iterate_deinit(struct dict_iterate_context *_ctx)
 {
 	struct sql_dict_iterate_context *ctx =
 		(struct sql_dict_iterate_context *)_ctx;
+	int ret = ctx->failed ? -1 : 0;
 
 	if (ctx->result != NULL)
 		sql_result_unref(ctx->result);
 	str_free(&ctx->key);
 	i_free(ctx->path);
 	i_free(ctx);
+	return ret;
 }
 
 static struct dict_transaction_context *
--- a/src/lib-dict/dict.c	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/lib-dict/dict.c	Sun Feb 07 16:27:18 2010 +0200
@@ -122,18 +122,18 @@
 	return dict->v.iterate_init(dict, path, flags);
 }
 
-int dict_iterate(struct dict_iterate_context *ctx,
-		 const char **key_r, const char **value_r)
+bool dict_iterate(struct dict_iterate_context *ctx,
+		  const char **key_r, const char **value_r)
 {
 	return ctx->dict->v.iterate(ctx, key_r, value_r);
 }
 
-void dict_iterate_deinit(struct dict_iterate_context **_ctx)
+int dict_iterate_deinit(struct dict_iterate_context **_ctx)
 {
 	struct dict_iterate_context *ctx = *_ctx;
 
 	*_ctx = NULL;
-	ctx->dict->v.iterate_deinit(ctx);
+	return ctx->dict->v.iterate_deinit(ctx);
 }
 
 struct dict_transaction_context *dict_transaction_begin(struct dict *dict)
--- a/src/lib-dict/dict.h	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/lib-dict/dict.h	Sun Feb 07 16:27:18 2010 +0200
@@ -48,10 +48,10 @@
 struct dict_iterate_context *
 dict_iterate_init(struct dict *dict, const char *path, 
 		  enum dict_iterate_flags flags);
-/* Returns -1 = error, 0 = finished, 1 = key/value set */
-int dict_iterate(struct dict_iterate_context *ctx,
-		 const char **key_r, const char **value_r);
-void dict_iterate_deinit(struct dict_iterate_context **ctx);
+bool dict_iterate(struct dict_iterate_context *ctx,
+		  const char **key_r, const char **value_r);
+/* Returns 0 = ok, -1 = iteration failed */
+int dict_iterate_deinit(struct dict_iterate_context **ctx);
 
 /* Start a new dictionary transaction. */
 struct dict_transaction_context *dict_transaction_begin(struct dict *dict);
--- a/src/plugins/acl/acl-lookup-dict.c	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/plugins/acl/acl-lookup-dict.c	Sun Feb 07 16:27:18 2010 +0200
@@ -154,7 +154,7 @@
 	prefix = DICT_PATH_SHARED DICT_SHARED_BOXES_PATH;
 	prefix_len = strlen(prefix);
 	iter = dict_iterate_init(dict->dict, prefix, DICT_ITERATE_FLAG_RECURSE);
-	while ((ret = dict_iterate(iter, &key, &value)) > 0) {
+	while (dict_iterate(iter, &key, &value)) {
 		/* prefix/$dest/$source */
 		key += prefix_len;
 		p = strchr(key, '/');
@@ -163,8 +163,7 @@
 			array_append(&old_ids_arr, &key, 1);
 		}
 	}
-	dict_iterate_deinit(&iter);
-	if (ret < 0) {
+	if (dict_iterate_deinit(&iter) < 0) {
 		i_error("acl: dict iteration failed, can't update dict");
 		return -1;
 	}
@@ -300,19 +299,16 @@
 acl_lookup_dict_iterate_visible_next(struct acl_lookup_dict_iter *iter)
 {
 	const char *key, *value;
-	int ret;
 
 	if (iter->dict_iter == NULL)
 		return 0;
 
-	ret = dict_iterate(iter->dict_iter, &key, &value);
-	if (ret > 0) {
+	if (dict_iterate(iter->dict_iter, &key, &value)) {
 		i_assert(iter->prefix_len < strlen(key));
 		return key + iter->prefix_len;
 	}
-	if (ret < 0)
+	if (dict_iterate_deinit(&iter->dict_iter) < 0)
 		iter->failed = TRUE;
-	dict_iterate_deinit(&iter->dict_iter);
 
 	if (iter->iter_idx < array_count(&iter->iter_ids)) {
 		/* get to the next iterator */
@@ -328,8 +324,10 @@
 	int ret = iter->failed ? -1 : 0;
 
 	*_iter = NULL;
-	if (iter->dict_iter != NULL)
-		dict_iterate_deinit(&iter->dict_iter);
+	if (iter->dict_iter != NULL) {
+		if (dict_iterate_deinit(&iter->dict_iter) < 0)
+			ret = -1;
+	}
 	pool_unref(&iter->pool);
 	return ret;
 }
--- a/src/plugins/expire/expire-tool.c	Sun Feb 07 16:01:51 2010 +0200
+++ b/src/plugins/expire/expire-tool.c	Sun Feb 07 16:27:18 2010 +0200
@@ -231,7 +231,7 @@
 				 DICT_ITERATE_FLAG_SORT_BY_VALUE);
 
 	/* We'll get the oldest values (timestamps) first */
-	while ((ret = dict_iterate(iter, &key, &value)) > 0) {
+	while (dict_iterate(iter, &key, &value)) {
 		/* key = DICT_EXPIRE_PREFIX<user>/<mailbox> */
 		userp = key + strlen(DICT_EXPIRE_PREFIX);
 
@@ -264,7 +264,6 @@
 
 		if (ret < 0) {
 			/* failed to update */
-			ret = 0;
 		} else if (next_expire == 0) {
 			/* no more messages or mailbox deleted */
 			if (!testrun)
@@ -289,12 +288,11 @@
 			} T_END;
 		}
 	}
-	if (ret < 0)
+	if (dict_iterate_deinit(&iter) < 0)
 		i_error("Dictionary iteration failed");
 	if (testrun && userp == NULL)
 		i_info("No entries in dictionary");
 
-	dict_iterate_deinit(&iter);
 	if (!testrun)
 		dict_transaction_commit(&trans);
 	else