Mercurial > dovecot > core-2.2
changeset 10752:6aa76d89195d HEAD
dict: Added dict_iterate_init_multiple().
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 18 Feb 2010 08:43:35 +0200 |
parents | 5ec28d7a5d13 |
children | 80a11f8650a4 |
files | src/dict/dict-commands.c src/lib-dict/dict-client.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 |
diffstat | 7 files changed, 102 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- 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);
--- 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;
--- 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; }
--- 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);
--- 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; }
--- 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,
--- 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 @@ -48,6 +48,9 @@ struct dict_iterate_context * dict_iterate_init(struct dict *dict, const char *path, enum dict_iterate_flags flags); +struct dict_iterate_context * +dict_iterate_init_multiple(struct dict *dict, const char *const *paths, + enum dict_iterate_flags flags); bool dict_iterate(struct dict_iterate_context *ctx, const char **key_r, const char **value_r); /* Returns 0 = ok, -1 = iteration failed */