Commit b8987622 authored by Dario Freddi's avatar Dario Freddi

Make validator compile (but it's not finished yet)

Signed-off-by: default avatarDario Freddi <drf@kde.org>
parent 4a878fa1
......@@ -14,6 +14,7 @@ akabeioperation.cpp
akabeioperationrunner.cpp
akabeipackage.cpp
akabeirunnerthread_p.cpp
akabeivalidatorthread_p.cpp
)
set(AKABEI_OPERATION_SRCS
......@@ -23,7 +24,10 @@ operations/akabeiplaininstalloperation.cpp
qt4_automoc(${AKABEI_CORE_SRCS})
qt4_automoc(${AKABEI_OPERATION_SRCS})
# There are some files which are not detected by automoc, add them
qt4_wrap_cpp(AKABEI_MISSING_MOCS akabeibackend_p.h)
qt4_wrap_cpp(AKABEI_MISSING_MOCS
akabeibackend_p.h
akabeivalidatorthread_p.h
)
add_library(akabeicore SHARED ${AKABEI_CORE_SRCS} ${AKABEI_OPERATION_SRCS} ${AKABEI_MISSING_MOCS})
......
......@@ -13,14 +13,24 @@
namespace Akabei {
OperationPrivate::OperationPrivate(const QString &tN)
: targetName(tN)
OperationPrivate::OperationPrivate(Operation *op, const QString &tN)
: q_ptr(op)
, targetName(tN)
, uuid(QUuid::createUuid())
{
}
void OperationPrivate::concurrentValidate()
{
Q_Q(Operation);
validateLoop = new QEventLoop;
q->validate();
validateLoop.data()->exec();
validateLoop.data()->deleteLater();
}
Operation::Operation(const QString &targetName)
: d_ptr(new OperationPrivate(targetName))
: d_ptr(new OperationPrivate(this, targetName))
{
}
......@@ -107,6 +117,12 @@ QStringList Operation::targetDependencies() const
return d->deps;
}
QString Operation::targetVersion() const
{
Q_D(const Operation);
d->targetVersion;
}
void Operation::setCanBeConcurrent(bool concurrent)
{
Q_D(Operation);
......@@ -198,13 +214,10 @@ void Operation::setValidationFinished(bool result)
}
}
void Operation::concurrentValidate()
void Operation::setTargetVersion(const QString& version)
{
Q_D(Operation);
d->validateLoop = new QEventLoop;
validate();
d->validateLoop.data()->exec();
d->validateLoop.data()->deleteLater();
d->targetVersion = version;
}
}
......@@ -48,7 +48,10 @@ public:
virtual ~Operation();
QUuid uuid() const;
QString targetName() const;
QString targetVersion() const;
bool canBeConcurrent() const;
QStringList conflictingTargets() const;
......@@ -69,7 +72,6 @@ public:
List subOperations() const;
//OperationRunner *runner();
void concurrentValidate();
protected:
explicit Operation(const QString &targetName);
......@@ -77,6 +79,8 @@ protected:
virtual void validate() = 0;
virtual void run() = 0;
void setTargetVersion(const QString &version);
void setCanBeConcurrent(bool concurrent);
void setPhase(Phase phase);
......@@ -104,6 +108,7 @@ private:
friend class OperationRunner;
friend class RunnerThread;
friend class ValidatorThread;
};
}
......
......@@ -18,11 +18,14 @@ class QEventLoop;
namespace Akabei {
class OperationPrivate {
Q_DECLARE_PUBLIC(Operation)
Operation * const q_ptr;
public:
OperationPrivate(const QString &tn);
OperationPrivate(Operation *op, const QString &tn);
virtual ~OperationPrivate() {};
QString targetName;
QString targetVersion;
QUuid uuid;
bool canBeConcurrent;
QStringList conflictingTargets;
......@@ -42,6 +45,8 @@ public:
Operation::List children;
QWeakPointer<QEventLoop> validateLoop;
void concurrentValidate();
};
}
......
......@@ -21,6 +21,7 @@
#include "akabeidatabase.h"
#include "akabeihelpers_p.h"
#include "akabeipackage.h"
#include "akabeioperation_p.h"
using namespace Akabei;
......@@ -40,6 +41,35 @@ ValidatorThread::~ValidatorThread()
}
QHash< QString, QString > ValidatorThread::versionedTargets(const QStringList &targets) const
{
QHash< QString, QString > rethash;
foreach (const QString &target, targets) {
if (target.contains('<')) {
rethash.insert(target.split('<').first(), '<' + target.split('<').last());
} else if (target.contains('>')) {
rethash.insert(target.split('>').first(), '>' + target.split('>').last());
} else if (target.contains('=')) {
rethash.insert(target.split('=').first(), target.split('=').last());
} else {
// No version costraint.
rethash.insert(target, QString());
}
}
return rethash;
}
OperationPrivate* ValidatorThread::operationPrivateProxy(Operation* op)
{
return op->d_func();
}
void concurrentValidate(Operation* op)
{
ValidatorThread::operationPrivateProxy(op)->concurrentValidate();
}
void ValidatorThread::requestCancel()
{
......@@ -51,7 +81,7 @@ void ValidatorThread::run()
processNextPhase();
}
QList<Operation*> ValidatorThread::joinOperations(Operation* op, bool shouldBeReady)
QList< Operation* > ValidatorThread::joinOperations(Operation* op, bool shouldBeReady)
{
QList<Operation*> retlist;
if (op->status() != Operation::StatusReady) {
......@@ -63,7 +93,7 @@ QList<Operation*> ValidatorThread::joinOperations(Operation* op, bool shouldBeRe
retlist << joinOperations(child, shouldBeReady);
}
return;
return retlist;
}
void ValidatorThread::processNextPhase()
......@@ -87,7 +117,7 @@ void ValidatorThread::processNextPhase()
QFutureWatcher< void > watcher(this);
connect(&watcher, SIGNAL(finished()), &e, SLOT(quit()));
connect(&watcher, SIGNAL(progressValueChanged(int)), this, SLOT(streamValidationProgress(int)));
QFuture< void > future = QtConcurrent::map(processOps, &Operation::concurrentValidate);
QFuture< void > future = QtConcurrent::map(processOps, concurrentValidate);
watcher.setFuture(future);
e.exec();
......@@ -106,7 +136,7 @@ void ValidatorThread::processNextPhase()
// Check dependencies
dependTargets.removeDuplicates();
Package *missingDeps;
QList< Package* > missingDeps;
QStringList unresolvableDeps;
foreach (const QString &dep, dependTargets) {
......@@ -184,7 +214,7 @@ void ValidatorThread::processNextPhase()
}
// Check if we are breaking dependencies somehow
foreach (const QString &target, op->targetRemovals()) {
foreach (const QString &target, targetRemovals) {
QString sql = "SELECT * FROM packages WHERE Depends LIKE \"%u;" + target + "%u\"";
QList<Package*> ret = Backend::instance()->localDatabase()->queryPackages(sql);
// Iterate: we might have found targets that are not the ones we're looking for (due to version handling)
......@@ -199,4 +229,3 @@ void ValidatorThread::processNextPhase()
// Good. The phase appears to be fully valid.
}
......@@ -17,7 +17,15 @@
#include <QtCore/QHash>
namespace Akabei {
class OperationPrivate;
/*
Hey, brave man looking at this code, I salute you.
Before starting, keep this in mind: what you see here is what decides if a transaction is valid or not.
It is the most complex part in the whole AkabeiCore, and the most delicate as well, since
this decides if your system will be fucked up by a wrong transaction or be spared.
Be careful.
*/
class ValidatorThread : public QThread
{
Q_OBJECT
......@@ -27,19 +35,24 @@ class ValidatorThread : public QThread
void requestCancel();
QHash< QString, QString > versionedTargets(const QStringList &targets) const;
static OperationPrivate *operationPrivateProxy(Operation *op);
protected:
virtual void run();
private:
void processNextPhase();
void joinOperations(Operation *op);
QList< Operation* > joinOperations(Operation *op, bool shouldBeReady);
private:
QHash<Operation::Phase, QList< Operation* > > m_operations;
Operation::Phase m_currentPhase;
friend class OperationRunner;
public slots:
public slots:
void streamValidationProgress(int);
};
......
......@@ -35,6 +35,7 @@ PlainInstallOperation::PlainInstallOperation(Package *package)
setPhase(Phase3); // Installation happens in phase 3.
setPriority(50); // Installation has a low priority.
setCanBeConcurrent(false); // And of course, it can not be concurrent.
setTargetVersion(package->version().toString());
}
PlainInstallOperation::~PlainInstallOperation()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment