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