This requires changes to all dict drivers.
bool synchronous_result;
bool iter_query_sent;
bool allow_null_map; /* allow next map to be NULL */
+ const char *values[2];
const char *error;
};
}
static bool sql_dict_iterate(struct dict_iterate_context *_ctx,
- const char **key_r, const char **value_r)
+ const char **key_r, const char *const **values_r)
{
struct sql_dict_iterate_context *ctx =
(struct sql_dict_iterate_context *)_ctx;
/* we have gotten *SOME* results, so can allow
unmapped next key now. */
ctx->allow_null_map = TRUE;
- return sql_dict_iterate(_ctx, key_r, value_r);
+ return sql_dict_iterate(_ctx, key_r, values_r);
}
if (ret < 0) {
ctx->error = p_strdup_printf(ctx->pool,
*key_r = str_c(ctx->key);
if ((ctx->flags & DICT_ITERATE_FLAG_NO_VALUE) == 0) {
- *value_r = sql_dict_result_unescape_value(ctx->map,
+ ctx->values[0] = sql_dict_result_unescape_value(ctx->map,
pool_datastack_create(), ctx->result);
+ *values_r = ctx->values;
}
return TRUE;
}
enum dict_iterate_flags flags;
pool_t value_pool;
struct fs_iter *fs_iter;
+ const char *values[2];
char *error;
};
}
static bool fs_dict_iterate(struct dict_iterate_context *ctx,
- const char **key_r, const char **value_r)
+ const char **key_r, const char *const **values_r)
{
struct fs_dict_iterate_context *iter =
(struct fs_dict_iterate_context *)ctx;
return FALSE;
path = fs_dict_get_full_key(dict, iter->paths[iter->path_idx]);
iter->fs_iter = fs_iter_init(dict->fs, path, 0);
- return fs_dict_iterate(ctx, key_r, value_r);
+ return fs_dict_iterate(ctx, key_r, values_r);
}
path = t_strconcat(iter->paths[iter->path_idx], *key_r, NULL);
if ((iter->flags & DICT_ITERATE_FLAG_NO_VALUE) != 0) {
+ iter->values[0] = NULL;
*key_r = path;
return TRUE;
}
p_clear(iter->value_pool);
- if ((ret = fs_dict_lookup(ctx->dict, iter->value_pool, path, value_r, &error)) < 0) {
+ ret = fs_dict_lookup(ctx->dict, iter->value_pool, path,
+ &iter->values[0], &error);
+ if (ret < 0) {
/* I/O error */
iter->error = i_strdup(error);
return FALSE;
} else if (ret == 0) {
/* file was just deleted, just skip to next one */
- return fs_dict_iterate(ctx, key_r, value_r);
+ return fs_dict_iterate(ctx, key_r, values_r);
}
*key_r = path;
+ *values_r = iter->values;
return TRUE;
}
pool_t results_pool;
ARRAY(struct client_dict_iter_result) results;
unsigned int result_idx;
+ const char *values[2];
bool cmd_sent;
bool seen_results;
}
static bool client_dict_iterate(struct dict_iterate_context *_ctx,
- const char **key_r, const char **value_r)
+ const char **key_r, const char *const **values_r)
{
struct client_dict_iterate_context *ctx =
(struct client_dict_iterate_context *)_ctx;
results = array_get(&ctx->results, &count);
if (ctx->result_idx < count) {
*key_r = results[ctx->result_idx].key;
- *value_r = results[ctx->result_idx].value;
+ ctx->values[0] = results[ctx->result_idx].value;
+ *values_r = ctx->values;
ctx->ctx.has_more = TRUE;
ctx->result_idx++;
ctx->seen_results = TRUE;
if (!ctx->cmd_sent) {
ctx->cmd_sent = TRUE;
client_dict_iterate_cmd_send(ctx);
- return client_dict_iterate(_ctx, key_r, value_r);
+ return client_dict_iterate(_ctx, key_r, values_r);
}
ctx->ctx.has_more = !ctx->finished;
ctx->result_idx = 0;
if ((ctx->flags & DICT_ITERATE_FLAG_ASYNC) == 0 && ctx->ctx.has_more) {
client_dict_wait(_ctx->dict);
- return client_dict_iterate(_ctx, key_r, value_r);
+ return client_dict_iterate(_ctx, key_r, values_r);
}
return FALSE;
}
}
static bool dict_fail_iterate(struct dict_iterate_context *ctx ATTR_UNUSED,
- const char **key_r ATTR_UNUSED, const char **value_r ATTR_UNUSED)
+ const char **key_r ATTR_UNUSED,
+ const char *const **values_r ATTR_UNUSED)
{
return FALSE;
}
struct file_dict_iterate_path *paths;
enum dict_iterate_flags flags;
+ const char *values[2];
const char *error;
};
}
static bool file_dict_iterate(struct dict_iterate_context *_ctx,
- const char **key_r, const char **value_r)
+ const char **key_r, const char *const **values_r)
{
struct file_dict_iterate_context *ctx =
(struct file_dict_iterate_context *)_ctx;
}
*key_r = key;
- *value_r = value;
+ ctx->values[0] = value;
+ *values_r = ctx->values;
return TRUE;
}
return FALSE;
(*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);
+ const char **key_r, const char *const **values_r);
int (*iterate_deinit)(struct dict_iterate_context *ctx,
const char **error_r);
bool dict_iterate(struct dict_iterate_context *ctx,
const char **key_r, const char **value_r)
{
+ const char *const *values;
+
if (ctx->max_rows > 0 && ctx->row_count >= ctx->max_rows) {
e_debug(ctx->event, "Maximum row count (%"PRIu64") reached",
ctx->max_rows);
ctx->has_more = FALSE;
return FALSE;
}
- if (!ctx->dict->v.iterate(ctx, key_r, value_r))
+ if (!ctx->dict->v.iterate(ctx, key_r, &values))
return FALSE;
if ((ctx->flags & DICT_ITERATE_FLAG_NO_VALUE) != 0) {
/* always return value as NULL to be consistent across
drivers */
*value_r = NULL;
+ } else {
+ i_assert(values[0] != NULL);
+ *value_r = values[0];
}
ctx->row_count++;
return TRUE;