dict.c revision eddd9bf1a1369aea4a2715f6be1137da6d17d293
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen/* Copyright (c) 2005-2007 Dovecot authors, see the included COPYING file */
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen#include "lib.h"
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen#include "array.h"
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen#include "dict-sql.h"
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen#include "dict-private.h"
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenstatic ARRAY_DEFINE(dict_drivers, struct dict *);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenstatic struct dict *dict_driver_lookup(const char *name)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen struct dict *const *dicts;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen unsigned int i, count;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen dicts = array_get(&dict_drivers, &count);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen for (i = 0; i < count; i++) {
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen if (strcmp(dicts[i]->name, name) == 0)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen return dicts[i];
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen }
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen return NULL;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenvoid dict_driver_register(struct dict *driver)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen if (!array_is_created(&dict_drivers))
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen i_array_init(&dict_drivers, 8);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen if (dict_driver_lookup(driver->name) != NULL) {
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen i_fatal("dict_driver_register(%s): Already registered",
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen driver->name);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen }
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen array_append(&dict_drivers, &driver, 1);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenvoid dict_driver_unregister(struct dict *driver)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen struct dict *const *dicts;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen unsigned int i, count;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen dicts = array_get(&dict_drivers, &count);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen for (i = 0; i < count; i++) {
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen if (dicts[i] == driver) {
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen array_delete(&dict_drivers, i, 1);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen break;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen }
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen }
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen i_assert(i < count);
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov if (array_count(&dict_drivers) == 0)
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov array_free(&dict_drivers);
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov}
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitovstruct dict *dict_init(const char *uri, enum dict_data_type value_type,
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov const char *username)
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov{
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov struct dict *dict;
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov const char *p, *name;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen p = strchr(uri, ':');
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen if (p == NULL) {
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen i_error("Dictionary URI is missing ':': %s", uri);
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov return NULL;
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov }
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov T_FRAME(
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov name = t_strdup_until(uri, p);
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov dict = dict_driver_lookup(name);
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov if (dict == NULL)
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov i_error("Unknown dict module: %s", name);
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov );
bbd51f171bb2f4abd437910c720579a4eaf65c85Sergey Kitov
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen return dict == NULL ? NULL :
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen dict->v.init(dict, p+1, value_type, username);
3abc26e06e053228d283503a8583657dfca0f2e0Timo Sirainen}
3abc26e06e053228d283503a8583657dfca0f2e0Timo Sirainen
3abc26e06e053228d283503a8583657dfca0f2e0Timo Sirainenvoid dict_deinit(struct dict **_dict)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen struct dict *dict = *_dict;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen *_dict = NULL;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen dict->v.deinit(dict);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenint dict_lookup(struct dict *dict, pool_t pool, const char *key,
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen const char **value_r)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen return dict->v.lookup(dict, pool, key, value_r);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenstruct dict_iterate_context *
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainendict_iterate_init(struct dict *dict, const char *path,
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen enum dict_iterate_flags flags)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen return dict->v.iterate_init(dict, path, flags);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenint dict_iterate(struct dict_iterate_context *ctx,
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen const char **key_r, const char **value_r)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen return ctx->dict->v.iterate(ctx, key_r, value_r);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenvoid dict_iterate_deinit(struct dict_iterate_context *ctx)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen ctx->dict->v.iterate_deinit(ctx);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenstruct dict_transaction_context *dict_transaction_begin(struct dict *dict)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen return dict->v.transaction_init(dict);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenint dict_transaction_commit(struct dict_transaction_context *ctx)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen return ctx->dict->v.transaction_commit(ctx);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenvoid dict_transaction_rollback(struct dict_transaction_context *ctx)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen ctx->dict->v.transaction_rollback(ctx);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenvoid dict_set(struct dict_transaction_context *ctx,
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen const char *key, const char *value)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen ctx->dict->v.set(ctx, key, value);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen ctx->changed = TRUE;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenvoid dict_unset(struct dict_transaction_context *ctx,
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen const char *key)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen ctx->dict->v.unset(ctx, key);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen ctx->changed = TRUE;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainenvoid dict_atomic_inc(struct dict_transaction_context *ctx,
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen const char *key, long long diff)
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen{
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen if (diff != 0) {
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen ctx->dict->v.atomic_inc(ctx, key, diff);
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen ctx->changed = TRUE;
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen }
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen}
654c60f1741fd195878d74a30df90bf130649d64Timo Sirainen