akonadi
transactionsequence.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "transactionsequence.h"
00021 #include "transactionjobs.h"
00022
00023 #include "job_p.h"
00024
00025 using namespace Akonadi;
00026
00027 class Akonadi::TransactionSequencePrivate : public JobPrivate
00028 {
00029 public:
00030 TransactionSequencePrivate( TransactionSequence *parent )
00031 : JobPrivate( parent ),
00032 mState( Idle )
00033 {
00034 }
00035
00036 enum TransactionState
00037 {
00038 Idle,
00039 Running,
00040 WaitingForSubjobs,
00041 RollingBack,
00042 Committing
00043 };
00044
00045 Q_DECLARE_PUBLIC( TransactionSequence )
00046
00047 TransactionState mState;
00048
00049 void commitResult( KJob *job )
00050 {
00051 Q_Q( TransactionSequence );
00052
00053 if ( job->error() ) {
00054 q->setError( job->error() );
00055 q->setErrorText( job->errorText() );
00056 }
00057 q->emitResult();
00058 }
00059
00060 void rollbackResult( KJob *job )
00061 {
00062 Q_Q( TransactionSequence );
00063
00064 Q_UNUSED( job );
00065 q->emitResult();
00066 }
00067 };
00068
00069 TransactionSequence::TransactionSequence( QObject * parent )
00070 : Job( new TransactionSequencePrivate( this ), parent )
00071 {
00072 }
00073
00074 TransactionSequence::~TransactionSequence()
00075 {
00076 }
00077
00078 bool TransactionSequence::addSubjob(KJob * job)
00079 {
00080 Q_D( TransactionSequence );
00081
00082 if ( d->mState == TransactionSequencePrivate::Idle ) {
00083 d->mState = TransactionSequencePrivate::Running;
00084 new TransactionBeginJob( this );
00085 }
00086 return Job::addSubjob( job );
00087 }
00088
00089 void TransactionSequence::slotResult(KJob * job)
00090 {
00091 Q_D( TransactionSequence );
00092
00093 if ( !job->error() ) {
00094 Job::slotResult( job );
00095 if ( subjobs().isEmpty() && d->mState == TransactionSequencePrivate::WaitingForSubjobs ) {
00096 d->mState = TransactionSequencePrivate::Committing;
00097 TransactionCommitJob *job = new TransactionCommitJob( this );
00098 connect( job, SIGNAL(result(KJob*)), SLOT(commitResult(KJob*)) );
00099 }
00100 } else {
00101 setError( job->error() );
00102 setErrorText( job->errorText() );
00103 removeSubjob( job );
00104 clearSubjobs();
00105 if ( d->mState == TransactionSequencePrivate::Running || d->mState == TransactionSequencePrivate::WaitingForSubjobs ) {
00106 d->mState = TransactionSequencePrivate::RollingBack;
00107 TransactionRollbackJob *job = new TransactionRollbackJob( this );
00108 connect( job, SIGNAL(result(KJob*)), SLOT(rollbackResult(KJob*)) );
00109 }
00110 }
00111 }
00112
00113 void TransactionSequence::commit()
00114 {
00115 Q_D( TransactionSequence );
00116
00117 if ( d->mState == TransactionSequencePrivate::Running )
00118 d->mState = TransactionSequencePrivate::WaitingForSubjobs;
00119 else
00120 return;
00121
00122 if ( subjobs().isEmpty() ) {
00123 if ( !error() ) {
00124 d->mState = TransactionSequencePrivate::Committing;
00125 TransactionCommitJob *job = new TransactionCommitJob( this );
00126 connect( job, SIGNAL(result(KJob*)), SLOT(commitResult(KJob*)) );
00127 } else {
00128 d->mState = TransactionSequencePrivate::RollingBack;
00129 TransactionRollbackJob *job = new TransactionRollbackJob( this );
00130 connect( job, SIGNAL(result(KJob*)), SLOT(rollbackResult(KJob*)) );
00131 }
00132 }
00133 }
00134
00135 void TransactionSequence::doStart()
00136 {
00137 Q_D( TransactionSequence );
00138
00139 if ( d->mState == TransactionSequencePrivate::Idle )
00140 emitResult();
00141 else
00142 commit();
00143 }
00144
00145 #include "transactionsequence.moc"