5a580c3a38ced62d4bcc95b8ac7c4f2935b5d294Timo Sirainen/* Copyright (c) 2008-2018 Dovecot authors, see the included COPYING file */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "lib.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "array.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch#include "virtual-storage.h"
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen#include "virtual-transaction.h"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstruct mailbox_transaction_context *
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvirtual_transaction_get(struct mailbox_transaction_context *trans,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mailbox *backend_box)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct virtual_transaction_context *vt =
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (struct virtual_transaction_context *)trans;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mailbox_transaction_context *const *bt, *new_bt;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int i, count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch bt = array_get(&vt->backend_transactions, &count);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (i = 0; i < count; i++) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (bt[i]->box == backend_box)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return bt[i];
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch new_bt = mailbox_transaction_begin(backend_box, trans->flags, __func__);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen array_append(&vt->backend_transactions, &new_bt, 1);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return new_bt;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Boschstruct mailbox_transaction_context *
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvirtual_transaction_begin(struct mailbox *box,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch enum mailbox_transaction_flags flags,
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch const char *reason)
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch{
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct virtual_transaction_context *vt;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch vt = i_new(struct virtual_transaction_context, 1);
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch i_array_init(&vt->backend_transactions,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch array_count(&mbox->backend_boxes));
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch index_transaction_init(&vt->t, box, flags, reason);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return &vt->t;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Boschint virtual_transaction_commit(struct mailbox_transaction_context *t,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mail_transaction_commit_changes *changes_r)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct virtual_transaction_context *vt =
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen (struct virtual_transaction_context *)t;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mailbox_transaction_context **bt;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int i, count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch int ret = 0;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (t->save_ctx != NULL) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch virtual_save_free(t->save_ctx);
6dad0888fcec8372f230941c70d8940b8c203b32Stephan Bosch t->save_ctx = NULL;
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch }
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch bt = array_get_modifiable(&vt->backend_transactions, &count);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (i = 0; i < count; i++) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mailbox_transaction_commit(&bt[i]) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ret = -1;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen }
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen array_free(&vt->backend_transactions);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (index_transaction_commit(t, changes_r) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ret = -1;
1bc12a53ddc6696bb209fb79d7cc66262d2ea621Timo Sirainen return ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
1bc12a53ddc6696bb209fb79d7cc66262d2ea621Timo Sirainen
7384b4e78eaab44693c985192276e31322155e32Stephan Boschvoid virtual_transaction_rollback(struct mailbox_transaction_context *t)
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch{
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct virtual_transaction_context *vt =
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen (struct virtual_transaction_context *)t;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch struct mailbox_transaction_context **bt;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int i, count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (t->save_ctx != NULL) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch virtual_save_free(t->save_ctx);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen t->save_ctx = NULL;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch bt = array_get_modifiable(&vt->backend_transactions, &count);
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch for (i = 0; i < count; i++)
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen mailbox_transaction_rollback(&bt[i]);
1bc12a53ddc6696bb209fb79d7cc66262d2ea621Timo Sirainen array_free(&vt->backend_transactions);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen index_transaction_rollback(t);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch}
6a90041707f1290c8970a3bacb0f8f928aeaaba6Stephan Bosch