1
/* Copyright (c) 2008-2009 Dovecot authors, see the included COPYING file */
5
#include "virtual-storage.h"
6
#include "virtual-transaction.h"
8
static void (*next_hook_mail_index_transaction_created)
9
(struct mail_index_transaction *t) = NULL;
11
struct mailbox_transaction_context *
12
virtual_transaction_get(struct mailbox_transaction_context *trans,
13
struct mailbox *backend_box)
15
struct virtual_transaction_context *dt =
16
(struct virtual_transaction_context *)trans;
17
struct mailbox_transaction_context *const *bt, *new_bt;
18
unsigned int i, count;
20
bt = array_get(&dt->backend_transactions, &count);
21
for (i = 0; i < count; i++) {
22
if (bt[i]->box == backend_box)
26
new_bt = mailbox_transaction_begin(backend_box, trans->flags);
27
array_append(&dt->backend_transactions, &new_bt, 1);
31
static int virtual_transaction_commit(struct mail_index_transaction *t,
32
uint32_t *log_file_seq_r,
33
uoff_t *log_file_offset_r)
35
struct virtual_transaction_context *dt = MAIL_STORAGE_CONTEXT(t);
36
struct mailbox_transaction_context **bt;
37
unsigned int i, count;
40
if (dt->save_ctx != NULL)
41
virtual_save_free(dt->save_ctx);
43
bt = array_get_modifiable(&dt->backend_transactions, &count);
44
for (i = 0; i < count; i++) {
45
if (mailbox_transaction_commit(&bt[i]) < 0)
48
array_free(&dt->backend_transactions);
50
if (index_transaction_finish_commit(&dt->ictx, log_file_seq_r,
51
log_file_offset_r) < 0)
56
static void virtual_transaction_rollback(struct mail_index_transaction *t)
58
struct virtual_transaction_context *dt = MAIL_STORAGE_CONTEXT(t);
59
struct mailbox_transaction_context **bt;
60
unsigned int i, count;
62
if (dt->save_ctx != NULL)
63
virtual_save_free(dt->save_ctx);
65
bt = array_get_modifiable(&dt->backend_transactions, &count);
66
for (i = 0; i < count; i++)
67
mailbox_transaction_rollback(&bt[i]);
68
array_free(&dt->backend_transactions);
70
index_transaction_finish_rollback(&dt->ictx);
73
static void virtual_transaction_created(struct mail_index_transaction *t)
75
struct mailbox *box = MAIL_STORAGE_CONTEXT(t->view);
77
/* index can be for mailbox list index, in which case box=NULL */
79
strcmp(box->storage->name, VIRTUAL_STORAGE_NAME) == 0) {
80
struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
81
struct virtual_transaction_context *mt;
83
mt = i_new(struct virtual_transaction_context, 1);
85
mt->ictx.super = t->v;
87
t->v.commit = virtual_transaction_commit;
88
t->v.rollback = virtual_transaction_rollback;
89
MODULE_CONTEXT_SET(t, mail_storage_mail_index_module, mt);
91
i_array_init(&mt->backend_transactions,
92
array_count(&mbox->backend_boxes));
93
index_transaction_init(&mt->ictx, &mbox->ibox);
96
if (next_hook_mail_index_transaction_created != NULL)
97
next_hook_mail_index_transaction_created(t);
100
void virtual_transaction_class_init(void)
102
next_hook_mail_index_transaction_created =
103
hook_mail_index_transaction_created;
104
hook_mail_index_transaction_created = virtual_transaction_created;
107
void virtual_transaction_class_deinit(void)
109
i_assert(hook_mail_index_transaction_created ==
110
virtual_transaction_created);
111
hook_mail_index_transaction_created =
112
next_hook_mail_index_transaction_created;