dovecot-2.2: lib-storage: Changed mailbox_attribute_get/set() AP...
dovecot at dovecot.org
dovecot at dovecot.org
Thu Mar 14 15:41:49 EET 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/f3cd9e5cbe99
changeset: 16024:f3cd9e5cbe99
user: Timo Sirainen <tss at iki.fi>
date: Thu Mar 14 15:32:14 2013 +0200
description:
lib-storage: Changed mailbox_attribute_get/set() APIs to have a transaction and update index.
The _get() doesn't currently actually use the transaction. It was mainly put
there for future use where it could be useful. It's also possible that
_iter() will need a transaction also. For now these decisions seem good
enough.
diffstat:
src/lib-imap-urlauth/imap-urlauth-backend.c | 60 +++++++++++++++++++++----
src/lib-storage/index/index-attribute.c | 69 ++++++++++++++++++++++------
src/lib-storage/index/index-storage.c | 49 ++++++++++---------
src/lib-storage/index/index-storage.h | 4 +-
src/lib-storage/index/index-transaction.c | 19 +++++++-
src/lib-storage/mail-storage-private.h | 9 ++-
src/lib-storage/mail-storage.c | 18 ++++---
src/lib-storage/mail-storage.h | 20 ++++++--
8 files changed, 180 insertions(+), 68 deletions(-)
diffs (truncated from 447 to 300 lines):
diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-imap-urlauth/imap-urlauth-backend.c
--- a/src/lib-imap-urlauth/imap-urlauth-backend.c Thu Mar 14 15:29:18 2013 +0200
+++ b/src/lib-imap-urlauth/imap-urlauth-backend.c Thu Mar 14 15:32:14 2013 +0200
@@ -12,11 +12,14 @@
#define IMAP_URLAUTH_KEY MAILBOX_ATTRIBUTE_PREFIX_DOVECOT"imap-urlauth"
-int imap_urlauth_backend_get_mailbox_key(struct mailbox *box, bool create,
- unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
- const char **error_r,
- enum mail_error *error_code_r)
+static int
+imap_urlauth_backend_trans_get_mailbox_key(struct mailbox_transaction_context *trans,
+ bool create,
+ unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
+ const char **error_r,
+ enum mail_error *error_code_r)
{
+ struct mailbox *box = mailbox_transaction_get_mailbox(trans);
struct mail_user *user = mail_storage_get_user(mailbox_get_storage(box));
struct mail_attribute_value urlauth_key;
const char *mailbox_key_hex = NULL;
@@ -26,7 +29,7 @@
*error_r = "Internal server error";
*error_code_r = MAIL_ERROR_TEMP;
- ret = mailbox_attribute_get(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+ ret = mailbox_attribute_get(trans, MAIL_ATTRIBUTE_TYPE_PRIVATE,
IMAP_URLAUTH_KEY, &urlauth_key);
if (ret < 0)
return -1;
@@ -44,7 +47,7 @@
random_fill(mailbox_key_r, IMAP_URLAUTH_KEY_LEN);
mailbox_key_hex = binary_to_hex(mailbox_key_r,
IMAP_URLAUTH_KEY_LEN);
- ret = mailbox_attribute_set(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+ ret = mailbox_attribute_set(trans, MAIL_ATTRIBUTE_TYPE_PRIVATE,
IMAP_URLAUTH_KEY, mailbox_key_hex);
if (ret < 0)
return -1;
@@ -69,10 +72,48 @@
return 1;
}
+int imap_urlauth_backend_get_mailbox_key(struct mailbox *box, bool create,
+ unsigned char mailbox_key_r[IMAP_URLAUTH_KEY_LEN],
+ const char **error_r,
+ enum mail_error *error_code_r)
+{
+ struct mailbox_transaction_context *t;
+ int ret;
+
+ t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
+ ret = imap_urlauth_backend_trans_get_mailbox_key(t, create, mailbox_key_r, error_r, error_code_r);
+ if (mailbox_transaction_commit(&t) < 0)
+ ret = -1;
+ return ret;
+}
+
int imap_urlauth_backend_reset_mailbox_key(struct mailbox *box)
{
- return mailbox_attribute_unset(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
- IMAP_URLAUTH_KEY) < 0 ? -1 : 1;
+ struct mailbox_transaction_context *t;
+ int ret;
+
+ t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL);
+ ret = mailbox_attribute_unset(t, MAIL_ATTRIBUTE_TYPE_PRIVATE,
+ IMAP_URLAUTH_KEY) < 0 ? -1 : 1;
+ if (mailbox_transaction_commit(&t) < 0)
+ ret = -1;
+ return ret;
+}
+
+static int imap_urlauth_backend_mailbox_reset_key(struct mailbox *box)
+{
+ const char *errstr;
+ enum mail_error error;
+
+ if (mailbox_open(box) < 0) {
+ errstr = mailbox_get_last_error(box, &error);
+ if (error == MAIL_ERROR_NOTFOUND || error == MAIL_ERROR_PERM)
+ return 0;
+ i_error("urlauth key reset: Couldn't open mailbox %s: %s",
+ mailbox_get_vname(box), errstr);
+ return -1;
+ }
+ return imap_urlauth_backend_reset_mailbox_key(box) < 0 ? -1 : 0;
}
int imap_urlauth_backend_reset_all_keys(struct mail_user *user)
@@ -90,8 +131,7 @@
MAILBOX_LIST_ITER_RETURN_NO_FLAGS);
while ((info = mailbox_list_iter_next(iter)) != NULL) {
box = mailbox_alloc(info->ns->list, info->vname, 0);
- if (mailbox_attribute_unset(box, MAIL_ATTRIBUTE_TYPE_PRIVATE,
- IMAP_URLAUTH_KEY) < 0)
+ if (imap_urlauth_backend_mailbox_reset_key(box) < 0)
ret = -1;
mailbox_free(&box);
}
diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-attribute.c
--- a/src/lib-storage/index/index-attribute.c Thu Mar 14 15:29:18 2013 +0200
+++ b/src/lib-storage/index/index-attribute.c Thu Mar 14 15:32:14 2013 +0200
@@ -147,33 +147,66 @@
i_unreached();
}
-int index_storage_attribute_set(struct mailbox *box,
+static int
+index_storage_attribute_get_dict_trans(struct mailbox_transaction_context *t,
+ enum mail_attribute_type type,
+ struct dict_transaction_context **dtrans_r,
+ const char **mailbox_prefix_r)
+{
+ struct dict_transaction_context **dtransp = NULL;
+ struct dict *dict;
+
+ switch (type) {
+ case MAIL_ATTRIBUTE_TYPE_PRIVATE:
+ dtransp = &t->attr_pvt_trans;
+ break;
+ case MAIL_ATTRIBUTE_TYPE_SHARED:
+ dtransp = &t->attr_shared_trans;
+ break;
+ }
+ i_assert(dtransp != NULL);
+
+ if (index_storage_get_dict(t->box, type, &dict, mailbox_prefix_r) < 0)
+ return -1;
+ *dtransp = *dtrans_r = dict_transaction_begin(dict);
+ return 0;
+}
+
+int index_storage_attribute_set(struct mailbox_transaction_context *t,
enum mail_attribute_type type,
const char *key, const char *value)
{
struct dict_transaction_context *dtrans;
- struct dict *dict;
const char *mailbox_prefix;
+ bool pvt = type == MAIL_ATTRIBUTE_TYPE_PRIVATE;
- if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0)
+ if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT,
+ strlen(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT)) == 0) {
+ mail_storage_set_error(t->box->storage, MAIL_ERROR_PARAMS,
+ "Internal attributes cannot be changed directly");
+ return -1;
+ }
+
+ if (index_storage_attribute_get_dict_trans(t, type, &dtrans,
+ &mailbox_prefix) < 0)
return -1;
T_BEGIN {
- key = key_get_prefixed(type, mailbox_prefix, key);
- dtrans = dict_transaction_begin(dict);
- if (value != NULL)
- dict_set(dtrans, key, value);
- else
- dict_unset(dtrans, key);
+ const char *prefixed_key =
+ key_get_prefixed(type, mailbox_prefix, key);
+
+ if (value != NULL) {
+ dict_set(dtrans, prefixed_key, value);
+ mail_index_attribute_set(t->itrans, pvt, key);
+ } else {
+ dict_unset(dtrans, prefixed_key);
+ mail_index_attribute_unset(t->itrans, pvt, key);
+ }
} T_END;
- if (dict_transaction_commit(&dtrans) < 0) {
- mail_storage_set_internal_error(box->storage);
- return -1;
- }
return 0;
}
-int index_storage_attribute_get(struct mailbox *box,
+int index_storage_attribute_get(struct mailbox_transaction_context *t,
enum mail_attribute_type type, const char *key,
struct mail_attribute_value *value_r)
{
@@ -183,14 +216,18 @@
memset(value_r, 0, sizeof(*value_r));
- if (index_storage_get_dict(box, type, &dict, &mailbox_prefix) < 0)
+ if (strncmp(key, MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT,
+ strlen(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT)) == 0)
+ return 0;
+
+ if (index_storage_get_dict(t->box, type, &dict, &mailbox_prefix) < 0)
return -1;
ret = dict_lookup(dict, pool_datastack_create(),
key_get_prefixed(type, mailbox_prefix, key),
&value_r->value);
if (ret < 0) {
- mail_storage_set_internal_error(box->storage);
+ mail_storage_set_internal_error(t->box->storage);
return -1;
}
return ret;
diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-storage.c
--- a/src/lib-storage/index/index-storage.c Thu Mar 14 15:29:18 2013 +0200
+++ b/src/lib-storage/index/index-storage.c Thu Mar 14 15:32:14 2013 +0200
@@ -601,7 +601,25 @@
return 0;
}
-static int mailbox_expunge_all_mails(struct mailbox *box)
+static int
+mailbox_delete_all_attributes(struct mailbox_transaction_context *t,
+ enum mail_attribute_type type)
+{
+ struct mailbox_attribute_iter *iter;
+ const char *key;
+ int ret = 0;
+
+ iter = mailbox_attribute_iter_init(t->box, type, "");
+ while ((key = mailbox_attribute_iter_next(iter)) != NULL) {
+ if (mailbox_attribute_unset(t, type, key) < 0)
+ ret = -1;
+ }
+ if (mailbox_attribute_iter_deinit(&iter) < 0)
+ ret = -1;
+ return ret;
+}
+
+static int mailbox_expunge_all_data(struct mailbox *box)
{
struct mail_search_context *ctx;
struct mailbox_transaction_context *t;
@@ -624,26 +642,15 @@
mailbox_transaction_rollback(&t);
return -1;
}
+
+ if (mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0 ||
+ mailbox_delete_all_attributes(t, MAIL_ATTRIBUTE_TYPE_SHARED) < 0) {
+ mailbox_transaction_rollback(&t);
+ return -1;
+ }
return mailbox_transaction_commit(&t);
}
-static int
-mailbox_delete_all_attributes(struct mailbox *box, enum mail_attribute_type type)
-{
- struct mailbox_attribute_iter *iter;
- const char *key;
- int ret = 0;
-
- iter = mailbox_attribute_iter_init(box, type, "");
- while ((key = mailbox_attribute_iter_next(iter)) != NULL) {
- if (mailbox_attribute_unset(box, type, key) < 0)
- ret = -1;
- }
- if (mailbox_attribute_iter_deinit(&iter) < 0)
- ret = -1;
- return ret;
-}
-
int index_storage_mailbox_delete(struct mailbox *box)
{
struct mailbox_metadata metadata;
@@ -672,11 +679,7 @@
*/
if (!box->deleting_must_be_empty) {
- if (mailbox_expunge_all_mails(box) < 0)
- return -1;
- if (mailbox_delete_all_attributes(box, MAIL_ATTRIBUTE_TYPE_PRIVATE) < 0)
- return -1;
- if (mailbox_delete_all_attributes(box, MAIL_ATTRIBUTE_TYPE_SHARED) < 0)
+ if (mailbox_expunge_all_data(box) < 0)
return -1;
}
if (mailbox_mark_index_deleted(box, TRUE) < 0)
diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-storage.h
--- a/src/lib-storage/index/index-storage.h Thu Mar 14 15:29:18 2013 +0200
+++ b/src/lib-storage/index/index-storage.h Thu Mar 14 15:32:14 2013 +0200
@@ -116,10 +116,10 @@
enum mailbox_metadata_items items,
struct mailbox_metadata *metadata_r);
-int index_storage_attribute_set(struct mailbox *box,
+int index_storage_attribute_set(struct mailbox_transaction_context *t,
enum mail_attribute_type type,
const char *key, const char *value);
-int index_storage_attribute_get(struct mailbox *box,
+int index_storage_attribute_get(struct mailbox_transaction_context *t,
enum mail_attribute_type type, const char *key,
struct mail_attribute_value *value_r);
struct mailbox_attribute_iter *
diff -r db0136374bb0 -r f3cd9e5cbe99 src/lib-storage/index/index-transaction.c
--- a/src/lib-storage/index/index-transaction.c Thu Mar 14 15:29:18 2013 +0200
More information about the dovecot-cvs
mailing list