dovecot-2.0: dict: Added dict_iterate_init_multiple().
dovecot at dovecot.org
dovecot at dovecot.org
Thu Feb 18 08:43:38 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/6aa76d89195d
changeset: 10752:6aa76d89195d
user: Timo Sirainen <tss at iki.fi>
date: Thu Feb 18 08:43:35 2010 +0200
description:
dict: Added dict_iterate_init_multiple().
diffstat:
src/dict/dict-commands.c | 5 +++--
src/lib-dict/dict-client.c | 15 ++++++++++-----
src/lib-dict/dict-file.c | 48 ++++++++++++++++++++++++++++++++++++++----------
src/lib-dict/dict-private.h | 2 +-
src/lib-dict/dict-sql.c | 42 ++++++++++++++++++++++++++++++------------
src/lib-dict/dict.c | 19 +++++++++++++++++--
src/lib-dict/dict.h | 3 +++
7 files changed, 102 insertions(+), 32 deletions(-)
diffs (truncated from 310 to 300 lines):
diff -r 5ec28d7a5d13 -r 6aa76d89195d src/dict/dict-commands.c
--- a/src/dict/dict-commands.c Thu Feb 18 08:20:22 2010 +0200
+++ b/src/dict/dict-commands.c Thu Feb 18 08:43:35 2010 +0200
@@ -91,13 +91,14 @@
}
args = t_strsplit(line, "\t");
- if (str_array_length(args) != 2) {
+ 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]));
+ conn->iter_ctx = dict_iterate_init_multiple(conn->dict, args+1,
+ atoi(args[0]));
o_stream_set_flush_callback(conn->output, cmd_iterate_flush, conn);
cmd_iterate_flush(conn);
diff -r 5ec28d7a5d13 -r 6aa76d89195d src/lib-dict/dict-client.c
--- a/src/lib-dict/dict-client.c Thu Feb 18 08:20:22 2010 +0200
+++ b/src/lib-dict/dict-client.c Thu Feb 18 08:43:35 2010 +0200
@@ -468,7 +468,7 @@
}
static struct dict_iterate_context *
-client_dict_iterate_init(struct dict *_dict, const char *path,
+client_dict_iterate_init(struct dict *_dict, const char *const *paths,
enum dict_iterate_flags flags)
{
struct client_dict *dict = (struct client_dict *)_dict;
@@ -483,11 +483,16 @@
ctx->pool = pool_alloconly_create("client dict iteration", 512);
T_BEGIN {
- const char *query;
+ string_t *query = t_str_new(256);
+ unsigned int i;
- query = t_strdup_printf("%c%d\t%s\n", DICT_PROTOCOL_CMD_ITERATE,
- flags, dict_client_escape(path));
- if (client_dict_send_query(dict, query) < 0)
+ str_printfa(query, "%c%d", DICT_PROTOCOL_CMD_ITERATE, flags);
+ for (i = 0; paths[i] != NULL; i++) {
+ str_append_c(query, '\t');
+ str_append(query, dict_client_escape(paths[i]));
+ }
+ str_append_c(query, '\n');
+ if (client_dict_send_query(dict, str_c(query)) < 0)
ctx->failed = TRUE;
} T_END;
return &ctx->ctx;
diff -r 5ec28d7a5d13 -r 6aa76d89195d src/lib-dict/dict-file.c
--- a/src/lib-dict/dict-file.c Thu Feb 18 08:20:22 2010 +0200
+++ b/src/lib-dict/dict-file.c Thu Feb 18 08:43:35 2010 +0200
@@ -23,12 +23,17 @@
int fd;
};
+struct file_dict_iterate_path {
+ const char *path;
+ unsigned int len;
+};
+
struct file_dict_iterate_context {
struct dict_iterate_context ctx;
+ pool_t pool;
struct hash_iterate_context *iter;
- char *path;
- unsigned int path_len;
+ struct file_dict_iterate_path *paths;
enum dict_iterate_flags flags;
unsigned int failed:1;
@@ -163,16 +168,25 @@
}
static struct dict_iterate_context *
-file_dict_iterate_init(struct dict *_dict, const char *path,
+file_dict_iterate_init(struct dict *_dict, const char *const *paths,
enum dict_iterate_flags flags)
{
struct file_dict_iterate_context *ctx;
struct file_dict *dict = (struct file_dict *)_dict;
+ unsigned int i, path_count;
+ pool_t pool;
- ctx = i_new(struct file_dict_iterate_context, 1);
+ pool = pool_alloconly_create("file dict iterate", 256);
+ ctx = p_new(pool, struct file_dict_iterate_context, 1);
ctx->ctx.dict = _dict;
- ctx->path = i_strdup(path);
- ctx->path_len = strlen(path);
+ ctx->pool = pool;
+
+ for (path_count = 0; paths[path_count] != NULL; path_count++) ;
+ ctx->paths = p_new(pool, struct file_dict_iterate_path, path_count + 1);
+ for (i = 0; i < path_count; i++) {
+ ctx->paths[i].path = p_strdup(pool, paths[i]);
+ ctx->paths[i].len = strlen(paths[i]);
+ }
ctx->flags = flags;
ctx->iter = hash_table_iterate_init(dict->hash);
@@ -181,19 +195,34 @@
return &ctx->ctx;
}
+static const struct file_dict_iterate_path *
+file_dict_iterate_find_path(struct file_dict_iterate_context *ctx,
+ const char *key)
+{
+ unsigned int i;
+
+ for (i = 0; ctx->paths[i].path != NULL; i++) {
+ if (strncmp(ctx->paths[i].path, key, ctx->paths[i].len) == 0)
+ return &ctx->paths[i];
+ }
+ return NULL;
+}
+
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;
+ const struct file_dict_iterate_path *path;
void *key, *value;
while (hash_table_iterate(ctx->iter, &key, &value)) {
- if (strncmp(ctx->path, key, ctx->path_len) != 0)
+ path = file_dict_iterate_find_path(ctx, key);
+ if (path == NULL)
continue;
if ((ctx->flags & DICT_ITERATE_FLAG_RECURSE) == 0 &&
- strchr((char *)key + ctx->path_len, '/') != NULL)
+ strchr((char *)key + path->len, '/') != NULL)
continue;
*key_r = key;
@@ -210,8 +239,7 @@
int ret = ctx->failed ? -1 : 0;
hash_table_iterate_deinit(&ctx->iter);
- i_free(ctx->path);
- i_free(ctx);
+ pool_unref(&ctx->pool);
return ret;
}
diff -r 5ec28d7a5d13 -r 6aa76d89195d src/lib-dict/dict-private.h
--- a/src/lib-dict/dict-private.h Thu Feb 18 08:20:22 2010 +0200
+++ b/src/lib-dict/dict-private.h Thu Feb 18 08:43:35 2010 +0200
@@ -14,7 +14,7 @@
const char *key, const char **value_r);
struct dict_iterate_context *
- (*iterate_init)(struct dict *dict, const char *path,
+ (*iterate_init)(struct dict *dict, const char *const *paths,
enum dict_iterate_flags flags);
bool (*iterate)(struct dict_iterate_context *ctx,
const char **key_r, const char **value_r);
diff -r 5ec28d7a5d13 -r 6aa76d89195d src/lib-dict/dict-sql.c
--- a/src/lib-dict/dict-sql.c Thu Feb 18 08:20:22 2010 +0200
+++ b/src/lib-dict/dict-sql.c Thu Feb 18 08:43:35 2010 +0200
@@ -35,13 +35,16 @@
struct sql_dict_iterate_context {
struct dict_iterate_context ctx;
+ pool_t pool;
+
enum dict_iterate_flags flags;
- char *path;
+ const char **paths;
struct sql_result *result;
string_t *key;
const struct dict_sql_map *map;
unsigned int key_prefix_len, pattern_prefix_len, next_map_idx;
+ unsigned int path_idx;
bool failed;
};
@@ -313,16 +316,24 @@
t_array_init(values, dict->set->max_field_count);
maps = array_get(&dict->set->maps, &count);
for (i = ctx->next_map_idx; i < count; i++) {
- if (dict_sql_map_match(&maps[i], ctx->path,
+ if (dict_sql_map_match(&maps[i], ctx->paths[ctx->path_idx],
values, &pat_len, &path_len, TRUE) &&
((ctx->flags & DICT_ITERATE_FLAG_RECURSE) != 0 ||
array_count(values)+1 >= array_count(&maps[i].sql_fields))) {
ctx->key_prefix_len = path_len;
ctx->pattern_prefix_len = pat_len;
ctx->next_map_idx = i + 1;
+
+ str_truncate(ctx->key, 0);
+ str_append(ctx->key, ctx->paths[ctx->path_idx]);
return &maps[i];
}
}
+
+ /* try the next path, if there is any */
+ ctx->path_idx++;
+ if (ctx->paths[ctx->path_idx] != NULL)
+ return sql_dict_iterate_find_next_map(ctx, values);
return NULL;
}
@@ -358,7 +369,8 @@
recurse_type = (ctx->flags & DICT_ITERATE_FLAG_RECURSE) == 0 ?
SQL_DICT_RECURSE_ONE : SQL_DICT_RECURSE_FULL;
- sql_dict_where_build(dict, map, &values, ctx->path[0],
+ sql_dict_where_build(dict, map, &values,
+ ctx->paths[ctx->path_idx][0],
recurse_type, query);
if ((ctx->flags & DICT_ITERATE_FLAG_SORT_BY_KEY) != 0) {
@@ -378,20 +390,28 @@
}
static struct dict_iterate_context *
-sql_dict_iterate_init(struct dict *_dict, const char *path,
+sql_dict_iterate_init(struct dict *_dict, const char *const *paths,
enum dict_iterate_flags flags)
{
struct sql_dict_iterate_context *ctx;
+ unsigned int i, path_count;
+ pool_t pool;
- ctx = i_new(struct sql_dict_iterate_context, 1);
+ pool = pool_alloconly_create("sql dict iterate", 512);
+ ctx = p_new(pool, struct sql_dict_iterate_context, 1);
ctx->ctx.dict = _dict;
- ctx->path = i_strdup(path);
+ ctx->pool = pool;
ctx->flags = flags;
- ctx->key = str_new(default_pool, 256);
- str_append(ctx->key, ctx->path);
+ for (path_count = 0; paths[path_count] != NULL; path_count++) ;
+ ctx->paths = p_new(pool, const char *, path_count + 1);
+ for (i = 0; i < path_count; i++)
+ ctx->paths[i] = p_strdup(pool, paths[i]);
+
+ ctx->key = str_new(pool, 256);
if (!sql_dict_iterate_next_query(ctx)) {
- i_error("sql dict iterate: Invalid/unmapped path: %s", path);
+ i_error("sql dict iterate: Invalid/unmapped path: %s",
+ paths[0]);
ctx->result = NULL;
return &ctx->ctx;
}
@@ -457,9 +477,7 @@
if (ctx->result != NULL)
sql_result_unref(ctx->result);
- str_free(&ctx->key);
- i_free(ctx->path);
- i_free(ctx);
+ pool_unref(&ctx->pool);
return ret;
}
diff -r 5ec28d7a5d13 -r 6aa76d89195d src/lib-dict/dict.c
--- a/src/lib-dict/dict.c Thu Feb 18 08:20:22 2010 +0200
+++ b/src/lib-dict/dict.c Thu Feb 18 08:43:35 2010 +0200
@@ -118,8 +118,23 @@
dict_iterate_init(struct dict *dict, const char *path,
enum dict_iterate_flags flags)
{
- i_assert(dict_key_prefix_is_valid(path));
- return dict->v.iterate_init(dict, path, flags);
+ const char *paths[2];
+
+ paths[0] = path;
+ paths[1] = NULL;
+ return dict_iterate_init_multiple(dict, paths, flags);
+}
+
+struct dict_iterate_context *
+dict_iterate_init_multiple(struct dict *dict, const char *const *paths,
+ enum dict_iterate_flags flags)
+{
+ unsigned int i;
+
+ i_assert(paths[0] != NULL);
+ for (i = 0; paths[i] != NULL; i++)
+ i_assert(dict_key_prefix_is_valid(paths[i]));
+ return dict->v.iterate_init(dict, paths, flags);
}
bool dict_iterate(struct dict_iterate_context *ctx,
diff -r 5ec28d7a5d13 -r 6aa76d89195d src/lib-dict/dict.h
--- a/src/lib-dict/dict.h Thu Feb 18 08:20:22 2010 +0200
+++ b/src/lib-dict/dict.h Thu Feb 18 08:43:35 2010 +0200
More information about the dovecot-cvs
mailing list