dovecot-2.0: dict server: Forgot to add new files in previous co...

dovecot at dovecot.org dovecot at dovecot.org
Sat May 30 00:13:18 EEST 2009


details:   http://hg.dovecot.org/dovecot-2.0/rev/fb32daa5c50a
changeset: 9406:fb32daa5c50a
user:      Timo Sirainen <tss at iki.fi>
date:      Fri May 29 17:13:13 2009 -0400
description:
dict server: Forgot to add new files in previous commit.

diffstat:

4 files changed, 566 insertions(+)
src/dict/dict-commands.c   |  332 ++++++++++++++++++++++++++++++++++++++++++++
src/dict/dict-commands.h   |    8 +
src/dict/dict-connection.c |  189 +++++++++++++++++++++++++
src/dict/dict-connection.h |   37 ++++

diffs (truncated from 582 to 300 lines):

diff -r aa08a4506d89 -r fb32daa5c50a src/dict/dict-commands.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dict/dict-commands.c	Fri May 29 17:13:13 2009 -0400
@@ -0,0 +1,332 @@
+/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "ostream.h"
+#include "str.h"
+#include "dict-client.h"
+#include "dict-settings.h"
+#include "dict-connection.h"
+#include "dict-commands.h"
+
+#include <stdlib.h>
+
+#define DICT_OUTPUT_OPTIMAL_SIZE 1024
+
+struct dict_client_cmd {
+	int cmd;
+	int (*func)(struct dict_connection *conn, const char *line);
+};
+
+static int cmd_lookup(struct dict_connection *conn, const char *line)
+{
+	const char *reply;
+	const char *value;
+	int ret;
+
+	if (conn->iter_ctx != NULL) {
+		i_error("dict client: LOOKUP: Can't lookup while iterating");
+		return -1;
+	}
+
+	/* <key> */
+	ret = dict_lookup(conn->dict, pool_datastack_create(), line, &value);
+	if (ret > 0) {
+		reply = t_strdup_printf("%c%s\n",
+					DICT_PROTOCOL_REPLY_OK, value);
+		o_stream_send_str(conn->output, reply);
+	} else {
+		reply = t_strdup_printf("%c\n", ret == 0 ?
+					DICT_PROTOCOL_REPLY_NOTFOUND :
+					DICT_PROTOCOL_REPLY_FAIL);
+		o_stream_send_str(conn->output, reply);
+	}
+	return 0;
+}
+
+static int cmd_iterate_flush(struct dict_connection *conn)
+{
+	string_t *str;
+	const char *key, *value;
+	int ret;
+
+	str = t_str_new(256);
+	o_stream_cork(conn->output);
+	while ((ret = dict_iterate(conn->iter_ctx, &key, &value)) > 0) {
+		str_truncate(str, 0);
+		str_printfa(str, "%s\t%s\n", key, value);
+		o_stream_send(conn->output, str_data(str), str_len(str));
+
+		if (o_stream_get_buffer_used_size(conn->output) >
+		    DICT_OUTPUT_OPTIMAL_SIZE) {
+			if (o_stream_flush(conn->output) <= 0)
+				break;
+			/* flushed everything, continue */
+		}
+	}
+
+	if (ret <= 0) {
+		/* finished iterating */
+		o_stream_unset_flush_callback(conn->output);
+		dict_iterate_deinit(&conn->iter_ctx);
+		o_stream_send(conn->output, "\n", 1);
+	}
+	o_stream_uncork(conn->output);
+	return ret <= 0 ? 1 : 0;
+}
+
+static int cmd_iterate(struct dict_connection *conn, const char *line)
+{
+	const char *const *args;
+
+	if (conn->iter_ctx != NULL) {
+		i_error("dict client: ITERATE: Already iterating");
+		return -1;
+	}
+
+	args = t_strsplit(line, "\t");
+	if (str_array_length(args) != 2) {
+		i_error("dict client: ITERATE: broken input");
+		return -1;
+	}
+
+	/* <flags> <path> */
+	conn->iter_ctx = dict_iterate_init(conn->dict, args[1], atoi(args[0]));
+
+	o_stream_set_flush_callback(conn->output, cmd_iterate_flush, conn);
+	cmd_iterate_flush(conn);
+	return 0;
+}
+
+static struct dict_connection_transaction *
+dict_connection_transaction_lookup(struct dict_connection *conn,
+				   unsigned int id)
+{
+	struct dict_connection_transaction *transactions;
+	unsigned int i, count;
+
+	if (!array_is_created(&conn->transactions))
+		return NULL;
+
+	transactions = array_get_modifiable(&conn->transactions, &count);
+	for (i = 0; i < count; i++) {
+		if (transactions[i].id == id)
+			return &transactions[i];
+	}
+	return NULL;
+}
+
+static void
+dict_connection_transaction_array_remove(struct dict_connection *conn,
+					 struct dict_connection_transaction *trans)
+{
+	const struct dict_connection_transaction *transactions;
+	unsigned int i, count;
+
+	transactions = array_get(&conn->transactions, &count);
+	for (i = 0; i < count; i++) {
+		if (&transactions[i] == trans) {
+			array_delete(&conn->transactions, i, 1);
+			break;
+		}
+	}
+}
+
+static int cmd_begin(struct dict_connection *conn, const char *line)
+{
+	struct dict_connection_transaction *trans;
+	unsigned int id;
+
+	if (!is_numeric(line, '\0')) {
+		i_error("dict client: Invalid transaction ID %s", line);
+		return -1;
+	}
+
+	id = (unsigned int)strtoul(line, NULL, 10);
+	if (dict_connection_transaction_lookup(conn, id) != NULL) {
+		i_error("dict client: Transaction ID %u already exists", id);
+		return -1;
+	}
+
+	if (!array_is_created(&conn->transactions))
+		i_array_init(&conn->transactions, 4);
+
+	/* <id> */
+	trans = array_append_space(&conn->transactions);
+	trans->id = id;
+	trans->ctx = dict_transaction_begin(conn->dict);
+	return 0;
+}
+
+static int
+dict_connection_transaction_lookup_parse(struct dict_connection *conn,
+					 const char *line,
+					 struct dict_connection_transaction **trans_r)
+{
+	unsigned int id;
+
+	if (!is_numeric(line, '\0')) {
+		i_error("dict client: Invalid transaction ID %s", line);
+		return -1;
+	}
+
+	id = (unsigned int)strtoul(line, NULL, 10);
+	*trans_r = dict_connection_transaction_lookup(conn, id);
+	if (*trans_r == NULL) {
+		i_error("dict client: Transaction ID %u doesn't exist", id);
+		return -1;
+	}
+	return 0;
+}
+
+static int cmd_commit(struct dict_connection *conn, const char *line)
+{
+	struct dict_connection_transaction *trans;
+	const char *reply;
+	int ret;
+
+	if (conn->iter_ctx != NULL) {
+		i_error("dict client: COMMIT: Can't commit while iterating");
+		return -1;
+	}
+
+	if (dict_connection_transaction_lookup_parse(conn, line, &trans) < 0)
+		return -1;
+
+	ret = dict_transaction_commit(&trans->ctx);
+	reply = t_strdup_printf("%c\n", ret == 0 ? DICT_PROTOCOL_REPLY_OK :
+				DICT_PROTOCOL_REPLY_FAIL);
+	o_stream_send_str(conn->output, reply);
+	dict_connection_transaction_array_remove(conn, trans);
+	return 0;
+}
+
+static int
+cmd_commit_async(struct dict_connection *conn, const char *line)
+{
+	struct dict_connection_transaction *trans;
+
+	if (conn->iter_ctx != NULL) {
+		i_error("dict client: COMMIT: Can't commit while iterating");
+		return -1;
+	}
+
+	if (dict_connection_transaction_lookup_parse(conn, line, &trans) < 0)
+		return -1;
+
+	dict_transaction_commit_async(&trans->ctx);
+	dict_connection_transaction_array_remove(conn, trans);
+	return 0;
+}
+
+static int cmd_rollback(struct dict_connection *conn, const char *line)
+{
+	struct dict_connection_transaction *trans;
+
+	if (dict_connection_transaction_lookup_parse(conn, line, &trans) < 0)
+		return -1;
+
+	dict_transaction_rollback(&trans->ctx);
+	dict_connection_transaction_array_remove(conn, trans);
+	return 0;
+}
+
+static int cmd_set(struct dict_connection *conn, const char *line)
+{
+	struct dict_connection_transaction *trans;
+	const char *const *args;
+
+	/* <id> <key> <value> */
+	args = t_strsplit(line, "\t");
+	if (str_array_length(args) != 3) {
+		i_error("dict client: SET: broken input");
+		return -1;
+	}
+
+	if (dict_connection_transaction_lookup_parse(conn, args[0], &trans) < 0)
+		return -1;
+
+        dict_set(trans->ctx, args[1], args[2]);
+	return 0;
+}
+
+static int cmd_unset(struct dict_connection *conn, const char *line)
+{
+	struct dict_connection_transaction *trans;
+	const char *const *args;
+
+	/* <id> <key> */
+	args = t_strsplit(line, "\t");
+	if (str_array_length(args) != 2) {
+		i_error("dict client: UNSET: broken input");
+		return -1;
+	}
+
+	if (dict_connection_transaction_lookup_parse(conn, args[0], &trans) < 0)
+		return -1;
+
+        dict_unset(trans->ctx, args[1]);
+	return 0;
+}
+
+static int cmd_atomic_inc(struct dict_connection *conn, const char *line)
+{
+	struct dict_connection_transaction *trans;
+	const char *const *args;
+	long long arg;
+
+	/* <id> <key> <diff> */
+	args = t_strsplit(line, "\t");
+	if (str_array_length(args) != 3) {
+		i_error("dict client: ATOMIC_INC: broken input");
+		return -1;
+	}
+
+	if (dict_connection_transaction_lookup_parse(conn, args[0], &trans) < 0)
+		return -1;
+
+	if (*args[2] != '-')
+		arg = (long long)strtoull(args[2], NULL, 10);
+	else
+		arg = -(long long)strtoull(args[2]+1, NULL, 10);
+        dict_atomic_inc(trans->ctx, args[1], arg);
+	return 0;
+}
+
+static struct dict_client_cmd cmds[] = {


More information about the dovecot-cvs mailing list