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