• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • akonadi
transactionsequence.cpp
1/*
2 Copyright (c) 2006-2008 Volker Krause <vkrause@kde.org>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "transactionsequence.h"
21#include "transactionjobs.h"
22
23#include "job_p.h"
24
25#include <QtCore/QSet>
26#include <QtCore/QVariant>
27
28using namespace Akonadi;
29
30class Akonadi::TransactionSequencePrivate : public JobPrivate
31{
32public:
33 TransactionSequencePrivate(TransactionSequence *parent)
34 : JobPrivate(parent)
35 , mState(Idle)
36 , mAutoCommit(true)
37 {
38 }
39
40 enum TransactionState {
41 Idle,
42 Running,
43 WaitingForSubjobs,
44 RollingBack,
45 Committing
46 };
47
48 Q_DECLARE_PUBLIC(TransactionSequence)
49
50 TransactionState mState;
51 QSet<KJob *> mIgnoredErrorJobs;
52 bool mAutoCommit;
53
54 void commitResult(KJob *job)
55 {
56 Q_Q(TransactionSequence);
57
58 if (job->error()) {
59 q->setError(job->error());
60 q->setErrorText(job->errorText());
61 }
62 q->emitResult();
63 }
64
65 void rollbackResult(KJob *job)
66 {
67 Q_Q(TransactionSequence);
68
69 Q_UNUSED(job);
70 q->emitResult();
71 }
72};
73
74TransactionSequence::TransactionSequence(QObject *parent)
75 : Job(new TransactionSequencePrivate(this), parent)
76{
77}
78
79TransactionSequence::~TransactionSequence()
80{
81}
82
83bool TransactionSequence::addSubjob(KJob *job)
84{
85 Q_D(TransactionSequence);
86
87 //Don't abort the rollback job, while keeping the state set.
88 if (d->mState == TransactionSequencePrivate::RollingBack) {
89 return Job::addSubjob(job);
90 }
91
92 if (error()) {
93 //This can happen if a rollback is in progress, so make sure we don't set the state back to running.
94 job->kill(EmitResult);
95 return false;
96 }
97 // TODO KDE5: remove property hack once SpecialCollectionsRequestJob has been fixed
98 if (d->mState == TransactionSequencePrivate::Idle && !property("transactionsDisabled").toBool()) {
99 d->mState = TransactionSequencePrivate::Running; // needs to be set before creating the transaction job to avoid infinite recursion
100 new TransactionBeginJob(this);
101 } else {
102 d->mState = TransactionSequencePrivate::Running;
103 }
104 return Job::addSubjob(job);
105}
106
107void TransactionSequence::slotResult(KJob *job)
108{
109 Q_D(TransactionSequence);
110
111 if (!job->error() || d->mIgnoredErrorJobs.contains(job)) {
112 // If we have an error but want to ignore it, we can't call Job::slotResult
113 // because it would confuse the subjob queue processing logic. Just removing
114 // the subjob instead is fine.
115 if (!job->error()) {
116 Job::slotResult(job);
117 } else {
118 Job::removeSubjob(job);
119 }
120
121 if (!hasSubjobs() && d->mState == TransactionSequencePrivate::WaitingForSubjobs) {
122 if (property("transactionsDisabled").toBool()) {
123 emitResult();
124 return;
125 }
126 d->mState = TransactionSequencePrivate::Committing;
127 TransactionCommitJob *job = new TransactionCommitJob(this);
128 connect(job, SIGNAL(result(KJob*)), SLOT(commitResult(KJob*)));
129 }
130 } else {
131 setError(job->error());
132 setErrorText(job->errorText());
133 removeSubjob(job);
134
135 // cancel all subjobs in case someone else is listening (such as ItemSync), but without notifying ourselves again
136 foreach (KJob *job, subjobs()) {
137 disconnect(job, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*)));
138 job->kill(EmitResult);
139 }
140 clearSubjobs();
141
142 if (d->mState == TransactionSequencePrivate::Running || d->mState == TransactionSequencePrivate::WaitingForSubjobs) {
143 if (property("transactionsDisabled").toBool()) {
144 emitResult();
145 return;
146 }
147 d->mState = TransactionSequencePrivate::RollingBack;
148 TransactionRollbackJob *job = new TransactionRollbackJob(this);
149 connect(job, SIGNAL(result(KJob*)), SLOT(rollbackResult(KJob*)));
150 }
151 }
152}
153
154void TransactionSequence::commit()
155{
156 Q_D(TransactionSequence);
157
158 if (d->mState == TransactionSequencePrivate::Running) {
159 d->mState = TransactionSequencePrivate::WaitingForSubjobs;
160 } else {
161 // we never got any subjobs, that means we never started a transaction
162 // so we can just quit here
163 if (d->mState == TransactionSequencePrivate::Idle) {
164 emitResult();
165 }
166 return;
167 }
168
169 if (subjobs().isEmpty()) {
170 if (property("transactionsDisabled").toBool()) {
171 emitResult();
172 return;
173 }
174 if (!error()) {
175 d->mState = TransactionSequencePrivate::Committing;
176 TransactionCommitJob *job = new TransactionCommitJob(this);
177 connect(job, SIGNAL(result(KJob*)), SLOT(commitResult(KJob*)));
178 } else {
179 d->mState = TransactionSequencePrivate::RollingBack;
180 TransactionRollbackJob *job = new TransactionRollbackJob(this);
181 connect(job, SIGNAL(result(KJob*)), SLOT(rollbackResult(KJob*)));
182 }
183 }
184}
185
186void TransactionSequence::setIgnoreJobFailure(KJob *job)
187{
188 Q_D(TransactionSequence);
189
190 // make sure this is one of our sub jobs
191 Q_ASSERT(subjobs().contains(job));
192
193 d->mIgnoredErrorJobs.insert(job);
194}
195
196void TransactionSequence::doStart()
197{
198 Q_D(TransactionSequence);
199
200 if (d->mAutoCommit) {
201 if (d->mState == TransactionSequencePrivate::Idle) {
202 emitResult();
203 } else {
204 commit();
205 }
206 }
207}
208
209void TransactionSequence::setAutomaticCommittingEnabled(bool enable)
210{
211 Q_D(TransactionSequence);
212 d->mAutoCommit = enable;
213}
214
215void TransactionSequence::rollback()
216{
217 Q_D(TransactionSequence);
218
219 setError(UserCanceled);
220 // we never really started
221 if (d->mState == TransactionSequencePrivate::Idle) {
222 emitResult();
223 return;
224 }
225
226 // TODO cancel not yet executed sub-jobs here
227
228 d->mState = TransactionSequencePrivate::RollingBack;
229 TransactionRollbackJob *job = new TransactionRollbackJob(this);
230 connect(job, SIGNAL(result(KJob*)), SLOT(rollbackResult(KJob*)));
231}
232
233#include "moc_transactionsequence.cpp"
Akonadi::JobPrivate
Definition: job_p.h:32
Akonadi::Job
Base class for all actions in the Akonadi storage.
Definition: job.h:87
Akonadi::Job::UserCanceled
@ UserCanceled
The user canceld this job.
Definition: job.h:107
Akonadi::Job::removeSubjob
virtual bool removeSubjob(KJob *job)
Removes the given subjob of this job.
Definition: job.cpp:338
Akonadi::Job::addSubjob
virtual bool addSubjob(KJob *job)
Adds the given job as a subjob to this job.
Definition: job.cpp:328
Akonadi::TransactionBeginJob
Job that begins a session-global transaction.
Definition: transactionjobs.h:47
Akonadi::TransactionCommitJob
Job that commits a session-global transaction.
Definition: transactionjobs.h:114
Akonadi::TransactionRollbackJob
Job that aborts a session-global transaction.
Definition: transactionjobs.h:82
Akonadi::TransactionSequence
Base class for jobs that need to run a sequence of sub-jobs in a transaction.
Definition: transactionsequence.h:70
Akonadi::TransactionSequence::commit
void commit()
Commits the transaction as soon as all pending sub-jobs finished successfully.
Definition: transactionsequence.cpp:154
Akonadi::TransactionSequence::~TransactionSequence
~TransactionSequence()
Destroys the transaction sequence.
Definition: transactionsequence.cpp:79
Akonadi::TransactionSequence::addSubjob
bool addSubjob(KJob *job)
Adds the given job as a subjob to this job.
Definition: transactionsequence.cpp:83
Akonadi::TransactionSequence::doStart
void doStart()
This method must be reimplemented in the concrete jobs.
Definition: transactionsequence.cpp:196
Akonadi::TransactionSequence::setIgnoreJobFailure
void setIgnoreJobFailure(KJob *job)
Sets which job of the sequence might fail without rolling back the complete transaction.
Definition: transactionsequence.cpp:186
Akonadi::TransactionSequence::TransactionSequence
TransactionSequence(QObject *parent=0)
Creates a new transaction sequence.
Definition: transactionsequence.cpp:74
Akonadi::TransactionSequence::rollback
void rollback()
Rolls back the current transaction as soon as possible.
Definition: transactionsequence.cpp:215
Akonadi::TransactionSequence::setAutomaticCommittingEnabled
void setAutomaticCommittingEnabled(bool enable)
Disable automatic committing.
Definition: transactionsequence.cpp:209
Akonadi
FreeBusyManager::Singleton.
Definition: actionstatemanager_p.h:28
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jul 21 2022 00:00:00 by doxygen 1.9.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal