mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-25 03:12:49 +00:00
Merge branch 'master' of ssh://github.com/fluxer/kdelibs into devinfo
This commit is contained in:
commit
ce2fd320cc
14 changed files with 1 additions and 939 deletions
|
@ -104,8 +104,6 @@ set(plasma_LIB_SRCS
|
|||
private/packages.cpp
|
||||
private/plasmoidservice.cpp
|
||||
private/runnerjobs.cpp
|
||||
private/storage.cpp
|
||||
private/storagethread.cpp
|
||||
private/style.cpp
|
||||
private/themedwidgetinterface.cpp
|
||||
private/tooltip.cpp
|
||||
|
@ -166,7 +164,6 @@ target_link_libraries(plasma PUBLIC
|
|||
${QT_QTSCRIPT_LIBRARY}
|
||||
${QT_QTNETWORK_LIBRARY}
|
||||
${QT_QTXML_LIBRARY}
|
||||
${QT_QTSQL_LIBRARY}
|
||||
${QT_QTSVG_LIBRARY}
|
||||
${QT_QTDECLARATIVE_LIBRARY}
|
||||
${KDE4_KDECORE_LIBS}
|
||||
|
@ -320,7 +317,6 @@ install(
|
|||
FILES
|
||||
data/operations/dataengineservice.operations
|
||||
data/operations/plasmoidservice.operations
|
||||
data/operations/storage.operations
|
||||
DESTINATION ${KDE4_DATA_INSTALL_DIR}/plasma/services
|
||||
)
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
*/
|
||||
#include "datacontainer.h"
|
||||
#include "private/datacontainer_p.h"
|
||||
#include "private/storage_p.h"
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <QDateTime>
|
||||
|
@ -54,16 +53,6 @@ void DataContainer::setData(const QString &key, const QVariant &value)
|
|||
|
||||
d->dirty = true;
|
||||
d->updateTimer.start();
|
||||
|
||||
//check if storage is enabled and if storage is needed.
|
||||
//If it is not set to be stored,then this is the first
|
||||
//setData() since the last time it was stored. This
|
||||
//gives us only one singleShot timer.
|
||||
if (isStorageEnabled() || !needsToBeStored()) {
|
||||
d->storageTimer.start(180000, this);
|
||||
}
|
||||
|
||||
setNeedsToBeStored(true);
|
||||
}
|
||||
|
||||
void DataContainer::removeAllData()
|
||||
|
@ -145,29 +134,6 @@ void DataContainer::connectVisualization(QObject *visualization, uint pollingInt
|
|||
}
|
||||
}
|
||||
|
||||
void DataContainer::setStorageEnabled(bool store)
|
||||
{
|
||||
d->enableStorage = store;
|
||||
if (store) {
|
||||
QTimer::singleShot(qrand() % (2000 + 1) , this, SLOT(retrieve()));
|
||||
}
|
||||
}
|
||||
|
||||
bool DataContainer::isStorageEnabled() const
|
||||
{
|
||||
return d->enableStorage;
|
||||
}
|
||||
|
||||
bool DataContainer::needsToBeStored() const
|
||||
{
|
||||
return !d->isStored;
|
||||
}
|
||||
|
||||
void DataContainer::setNeedsToBeStored(bool store)
|
||||
{
|
||||
d->isStored = !store;
|
||||
}
|
||||
|
||||
DataEngine* DataContainer::getDataEngine()
|
||||
{
|
||||
QObject *o = this;
|
||||
|
@ -183,83 +149,6 @@ DataEngine* DataContainer::getDataEngine()
|
|||
return de;
|
||||
}
|
||||
|
||||
void DataContainerPrivate::store()
|
||||
{
|
||||
if (!q->needsToBeStored() || !q->isStorageEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DataEngine* de = q->getDataEngine();
|
||||
if (!de) {
|
||||
return;
|
||||
}
|
||||
|
||||
q->setNeedsToBeStored(false);
|
||||
|
||||
if (!storage) {
|
||||
storage = new Storage(q);
|
||||
}
|
||||
|
||||
KConfigGroup op = storage->operationDescription("save");
|
||||
op.writeEntry("group", q->objectName());
|
||||
StorageJob *job = static_cast<StorageJob *>(storage->startOperationCall(op));
|
||||
job->setData(data);
|
||||
storageCount++;
|
||||
QObject::connect(job, SIGNAL(finished(KJob*)), q, SLOT(storeJobFinished(KJob*)));
|
||||
}
|
||||
|
||||
void DataContainerPrivate::storeJobFinished(KJob* )
|
||||
{
|
||||
--storageCount;
|
||||
if (storageCount < 1) {
|
||||
storage->deleteLater();
|
||||
storage = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DataContainerPrivate::retrieve()
|
||||
{
|
||||
DataEngine* de = q->getDataEngine();
|
||||
if (de == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!storage) {
|
||||
storage = new Storage(q);
|
||||
}
|
||||
|
||||
KConfigGroup retrieveGroup = storage->operationDescription("retrieve");
|
||||
retrieveGroup.writeEntry("group", q->objectName());
|
||||
ServiceJob* retrieveJob = storage->startOperationCall(retrieveGroup);
|
||||
QObject::connect(retrieveJob, SIGNAL(result(KJob*)), q,
|
||||
SLOT(populateFromStoredData(KJob*)));
|
||||
}
|
||||
|
||||
void DataContainerPrivate::populateFromStoredData(KJob *job)
|
||||
{
|
||||
if (job->error()) {
|
||||
return;
|
||||
}
|
||||
|
||||
StorageJob *ret = dynamic_cast<StorageJob*>(job);
|
||||
if (!ret) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only fill the source with old stored
|
||||
// data if it is not already populated with new data.
|
||||
if (data.isEmpty() && !ret->data().isEmpty()) {
|
||||
data = ret->data();
|
||||
dirty = true;
|
||||
q->forceImmediateUpdate();
|
||||
}
|
||||
|
||||
KConfigGroup expireGroup = storage->operationDescription("expire");
|
||||
//expire things older than 4 days
|
||||
expireGroup.writeEntry("age", 345600);
|
||||
storage->startOperationCall(expireGroup);
|
||||
}
|
||||
|
||||
void DataContainer::disconnectVisualization(QObject *visualization)
|
||||
{
|
||||
QMap<QObject *, SignalRelay *>::iterator objIt = d->relayObjects.find(visualization);
|
||||
|
@ -339,9 +228,6 @@ void DataContainer::timerEvent(QTimerEvent * event)
|
|||
emit becameUnused(objectName());
|
||||
}
|
||||
d->checkUsageTimer.stop();
|
||||
} else if (event->timerId() == d->storageTimer.timerId()) {
|
||||
d->store();
|
||||
d->storageTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,30 +124,6 @@ class PLASMA_EXPORT DataContainer : public QObject
|
|||
void connectVisualization(QObject *visualization, uint pollingInterval,
|
||||
Plasma::IntervalAlignment alignment);
|
||||
|
||||
/**
|
||||
* sets this data container to be automatically stored.
|
||||
* @param whether this data container should be stored
|
||||
* @since 4.6
|
||||
*/
|
||||
void setStorageEnabled(bool store);
|
||||
|
||||
/**
|
||||
* @return true if the data container has been marked for storage
|
||||
* @since 4.6
|
||||
*/
|
||||
bool isStorageEnabled() const;
|
||||
|
||||
/**
|
||||
* @return true if the data container has been updated, but not stored
|
||||
*/
|
||||
bool needsToBeStored() const;
|
||||
|
||||
/**
|
||||
* sets that the data container needs to be stored or not.
|
||||
* @param whether the data container needs to be stored
|
||||
*/
|
||||
void setNeedsToBeStored(bool store);
|
||||
|
||||
/**
|
||||
* @return the DataEngine that the DataContainer is
|
||||
* a child of.
|
||||
|
@ -255,10 +231,6 @@ class PLASMA_EXPORT DataContainer : public QObject
|
|||
friend class DataContainerPrivate;
|
||||
friend class DataEngineManager;
|
||||
DataContainerPrivate *const d;
|
||||
|
||||
Q_PRIVATE_SLOT(d, void storeJobFinished(KJob *job))
|
||||
Q_PRIVATE_SLOT(d, void populateFromStoredData(KJob *job))
|
||||
Q_PRIVATE_SLOT(d, void retrieve())
|
||||
};
|
||||
|
||||
} // Plasma namespace
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "service.h"
|
||||
#include "private/dataengineservice_p.h"
|
||||
#include "private/service_p.h"
|
||||
#include "private/storage_p.h"
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
@ -289,7 +288,6 @@ void DataEngine::removeSource(const QString &source)
|
|||
}
|
||||
}
|
||||
|
||||
s->d->store();
|
||||
s->disconnect(this);
|
||||
s->deleteLater();
|
||||
d->sources.erase(it);
|
||||
|
@ -433,14 +431,6 @@ void DataEngine::setName(const QString &name)
|
|||
setObjectName(name);
|
||||
}
|
||||
|
||||
void DataEngine::setStorageEnabled(const QString &source, bool store)
|
||||
{
|
||||
DataContainer *s = d->source(source, false);
|
||||
if (s) {
|
||||
s->setStorageEnabled(store);
|
||||
}
|
||||
}
|
||||
|
||||
// Private class implementations
|
||||
DataEnginePrivate::DataEnginePrivate(DataEngine *e, const KPluginInfo &info)
|
||||
: q(e),
|
||||
|
|
|
@ -446,16 +446,6 @@ NoAlignment) const;
|
|||
*/
|
||||
void setDefaultService(const QString &serviceName);
|
||||
|
||||
/**
|
||||
* Sets a source to be stored for easy retrieval
|
||||
* when the real source of the data (usually a network connection)
|
||||
* is unavailable.
|
||||
* @param source the name of the source
|
||||
* @param store if source should be stored
|
||||
* @since 4.6
|
||||
*/
|
||||
void setStorageEnabled(const QString &source, bool store);
|
||||
|
||||
protected Q_SLOTS:
|
||||
/**
|
||||
* Call this method when you call setData directly on a DataContainer instead
|
||||
|
|
|
@ -221,7 +221,6 @@ void DataEngineManager::timerEvent(QTimerEvent *)
|
|||
foreach (DataContainer *dc, engine->containerDict()) {
|
||||
out << " * " << dc->objectName() << endl;
|
||||
out << " Data count: " << dc->d->data.count() << endl;
|
||||
out << " Stored: " << dc->isStorageEnabled() << ' ' << endl;
|
||||
const int directs = dc->receivers(SIGNAL(dataUpdated(QString,Plasma::DataEngine::Data)));
|
||||
if (directs > 0) {
|
||||
out << " Direction Connections: " << directs << ' ' << endl;
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "private/applet_p.h"
|
||||
#include "private/extenderapplet_p.h"
|
||||
#include "private/service_p.h" // for NullService
|
||||
#include "private/storage_p.h"
|
||||
|
||||
namespace Plasma {
|
||||
|
||||
|
@ -199,8 +198,6 @@ Service *PluginLoader::loadService(const QString &name, const QVariantList &args
|
|||
//TODO: scripting API support
|
||||
if (name.isEmpty()) {
|
||||
return new NullService(QString(), parent);
|
||||
} else if (name == "org.kde.servicestorage") {
|
||||
return new Storage(parent);
|
||||
}
|
||||
|
||||
QString constraint = QString("[X-KDE-PluginInfo-Name] == '%1'").arg(name);
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#define PLASMA_DATACONTAINER_P_H
|
||||
|
||||
#include "servicejob.h"
|
||||
#include "storage_p.h"
|
||||
|
||||
#include <QtCore/qcoreevent.h>
|
||||
#include <QtCore/QElapsedTimer>
|
||||
|
@ -39,12 +38,8 @@ class DataContainerPrivate
|
|||
public:
|
||||
DataContainerPrivate(DataContainer *container)
|
||||
: q(container),
|
||||
storage(NULL),
|
||||
storageCount(0),
|
||||
dirty(false),
|
||||
cached(false),
|
||||
enableStorage(false),
|
||||
isStored(true)
|
||||
cached(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -54,34 +49,14 @@ public:
|
|||
|
||||
bool hasUpdates();
|
||||
|
||||
/**
|
||||
* Deletes the store member of DataContainerPrivate if
|
||||
* there are no more references to it.
|
||||
*/
|
||||
void storeJobFinished(KJob *job);
|
||||
|
||||
/**
|
||||
* Does the work of putting the data from disk into the DataContainer
|
||||
* after retrieve() sets it up.
|
||||
*/
|
||||
void populateFromStoredData(KJob *job);
|
||||
|
||||
void store();
|
||||
void retrieve();
|
||||
|
||||
DataContainer *q;
|
||||
DataEngine::Data data;
|
||||
QMap<QObject *, SignalRelay *> relayObjects;
|
||||
QMap<uint, SignalRelay *> relays;
|
||||
QElapsedTimer updateTimer;
|
||||
Storage* storage;
|
||||
QBasicTimer storageTimer;
|
||||
QBasicTimer checkUsageTimer;
|
||||
int storageCount;
|
||||
bool dirty : 1;
|
||||
bool cached : 1;
|
||||
bool enableStorage : 1;
|
||||
bool isStored : 1;
|
||||
};
|
||||
|
||||
class SignalRelay : public QObject
|
||||
|
|
|
@ -1,158 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////////
|
||||
// storage.cpp //
|
||||
// //
|
||||
// Copyright (C) 2010 Brian Pritchett <batenkaitos@gmail.com> //
|
||||
// Copyright (C) 2010 Marco Martin <mart@kde.org> //
|
||||
// //
|
||||
// This library is free software; you can redistribute it and/or //
|
||||
// modify it under the terms of the GNU Lesser General Public //
|
||||
// License as published by the Free Software Foundation; either //
|
||||
// version 2.1 of the License, or (at your option) any later version. //
|
||||
// //
|
||||
// This library is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
|
||||
// Lesser General Public License for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU Lesser General Public //
|
||||
// License along with this library; if not, write to the Free Software //
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA //
|
||||
// 02110-1301 USA //
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "private/storage_p.h"
|
||||
|
||||
//Qt
|
||||
#include <QSqlDriver>
|
||||
#include <QSqlError>
|
||||
#include <QSqlField>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlRecord>
|
||||
|
||||
//KDE
|
||||
#include <kdebug.h>
|
||||
#include <kstandarddirs.h>
|
||||
|
||||
//Plasma
|
||||
#include "applet.h"
|
||||
#include "dataengine.h"
|
||||
#include "abstractrunner.h"
|
||||
#include "storagethread_p.h"
|
||||
|
||||
|
||||
StorageJob::StorageJob(const QString& destination,
|
||||
const QString& operation,
|
||||
const QMap<QString, QVariant>& parameters,
|
||||
QObject *parent)
|
||||
: ServiceJob(destination, operation, parameters, parent),
|
||||
m_clientName(destination)
|
||||
{
|
||||
Plasma::StorageThread::self()->start();
|
||||
connect(Plasma::StorageThread::self(), SIGNAL(newResult(StorageJob*,QVariant)), this, SLOT(resultSlot(StorageJob*,QVariant)));
|
||||
qRegisterMetaType<StorageJob *>();
|
||||
qRegisterMetaType<QWeakPointer<StorageJob> >();
|
||||
}
|
||||
|
||||
StorageJob::~StorageJob()
|
||||
{
|
||||
}
|
||||
|
||||
void StorageJob::setData(const QVariantHash &data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
|
||||
QVariantHash StorageJob::data() const
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
||||
QString StorageJob::clientName() const
|
||||
{
|
||||
return m_clientName;
|
||||
}
|
||||
|
||||
|
||||
void StorageJob::start()
|
||||
{
|
||||
//FIXME: QHASH
|
||||
QMap<QString, QVariant> params = parameters();
|
||||
|
||||
QString valueGroup = params["group"].toString();
|
||||
if (valueGroup.isEmpty()) {
|
||||
valueGroup = "default";
|
||||
}
|
||||
|
||||
QWeakPointer<StorageJob> me(this);
|
||||
if (operationName() == "save") {
|
||||
QMetaObject::invokeMethod(Plasma::StorageThread::self(), "save", Qt::QueuedConnection, Q_ARG(QWeakPointer<StorageJob>, me), Q_ARG(const QVariantMap&, params));
|
||||
} else if (operationName() == "retrieve") {
|
||||
QMetaObject::invokeMethod(Plasma::StorageThread::self(), "retrieve", Qt::QueuedConnection, Q_ARG(QWeakPointer<StorageJob>, me), Q_ARG(const QVariantMap&, params));
|
||||
} else if (operationName() == "delete") {
|
||||
QMetaObject::invokeMethod(Plasma::StorageThread::self(), "deleteEntry", Qt::QueuedConnection, Q_ARG(QWeakPointer<StorageJob>, me), Q_ARG(const QVariantMap&, params));
|
||||
} else if (operationName() == "expire") {
|
||||
QMetaObject::invokeMethod(Plasma::StorageThread::self(), "expire", Qt::QueuedConnection, Q_ARG(QWeakPointer<StorageJob>, me), Q_ARG(const QVariantMap&, params));
|
||||
} else {
|
||||
setError(true);
|
||||
setResult(false);
|
||||
}
|
||||
}
|
||||
|
||||
void StorageJob::resultSlot(StorageJob *job, const QVariant &result)
|
||||
{
|
||||
if (job == this) {
|
||||
if (result.type() == QVariant::Hash) {
|
||||
m_data = result.toHash();
|
||||
}
|
||||
setResult(result);
|
||||
}
|
||||
}
|
||||
|
||||
Plasma::ServiceJob* Storage::createJob(const QString &operation, QMap<QString, QVariant> ¶meters)
|
||||
{
|
||||
if (m_clientName.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return new StorageJob(m_clientName, operation, parameters, this);
|
||||
}
|
||||
|
||||
//Storage implementation
|
||||
Storage::Storage(QObject* parent)
|
||||
: Plasma::Service(parent),
|
||||
m_clientName("data")
|
||||
{
|
||||
//search among parents for an applet or dataengine: if found call the table as its plugin name
|
||||
QObject *parentObject = this;
|
||||
|
||||
while ((parentObject = parentObject->parent())) {
|
||||
Plasma::Applet *applet = qobject_cast<Plasma::Applet *>(parentObject);
|
||||
if (applet) {
|
||||
m_clientName = applet->pluginName();
|
||||
break;
|
||||
}
|
||||
|
||||
Plasma::DataEngine *engine = qobject_cast<Plasma::DataEngine *>(parentObject);
|
||||
if (engine) {
|
||||
m_clientName = engine->pluginName();
|
||||
break;
|
||||
}
|
||||
|
||||
Plasma::AbstractRunner *runner = qobject_cast<Plasma::AbstractRunner *>(parentObject);
|
||||
if (runner) {
|
||||
m_clientName = runner->id();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_clientName = m_clientName.replace('.', "_");
|
||||
m_clientName = m_clientName.replace('-', "_");
|
||||
|
||||
setName("storage");
|
||||
}
|
||||
|
||||
Storage::~Storage()
|
||||
{
|
||||
}
|
||||
|
||||
#include "moc_storage_p.cpp"
|
|
@ -1,76 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////////
|
||||
// storage.h //
|
||||
// //
|
||||
// Copyright (C) 2010 Brian Pritchett <batenkaitos@gmail.com> //
|
||||
// Copyright (C) 2010 Marco Martin <mart@kde.org> //
|
||||
// //
|
||||
// This library is free software; you can redistribute it and/or //
|
||||
// modify it under the terms of the GNU Lesser General Public //
|
||||
// License as published by the Free Software Foundation; either //
|
||||
// version 2.1 of the License, or (at your option) any later version. //
|
||||
// //
|
||||
// This library is distributed in the hope that it will be useful, //
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
|
||||
// Lesser General Public License for more details. //
|
||||
// //
|
||||
// You should have received a copy of the GNU Lesser General Public //
|
||||
// License along with this library; if not, write to the Free Software //
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA //
|
||||
// 02110-1301 USA //
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PLASMA_STORAGE_H
|
||||
#define PLASMA_STORAGE_H
|
||||
|
||||
#include <QSqlDatabase>
|
||||
|
||||
#include <plasma/service.h>
|
||||
#include <plasma/servicejob.h>
|
||||
|
||||
//Begin StorageJob
|
||||
class StorageJob : public Plasma::ServiceJob
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QVariantHash data READ data WRITE setData)
|
||||
|
||||
public:
|
||||
StorageJob(const QString& destination,
|
||||
const QString& operation,
|
||||
const QMap<QString, QVariant>& parameters,
|
||||
QObject *parent = 0);
|
||||
~StorageJob();
|
||||
void setData(const QVariantHash &data);
|
||||
QVariantHash data() const;
|
||||
void start();
|
||||
QString clientName() const;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void resultSlot(StorageJob *job, const QVariant &result);
|
||||
|
||||
private:
|
||||
QString m_clientName;
|
||||
QVariantHash m_data;
|
||||
};
|
||||
//End StorageJob
|
||||
|
||||
Q_DECLARE_METATYPE(StorageJob *)
|
||||
Q_DECLARE_METATYPE(QWeakPointer<StorageJob>)
|
||||
|
||||
class Storage : public Plasma::Service
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Storage(QObject *parent = 0);
|
||||
~Storage();
|
||||
|
||||
protected:
|
||||
Plasma::ServiceJob* createJob(const QString &operation, QMap<QString, QVariant> ¶meters);
|
||||
|
||||
private:
|
||||
QString m_clientName;
|
||||
};
|
||||
|
||||
|
||||
#endif //PLASMA_STORAGE_H
|
|
@ -1,338 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "storagethread_p.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlField>
|
||||
#include <QSqlDriver>
|
||||
#include <QSqlRecord>
|
||||
#include <QDateTime>
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <kstandarddirs.h>
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class StorageThreadSingleton
|
||||
{
|
||||
public:
|
||||
StorageThreadSingleton()
|
||||
{
|
||||
}
|
||||
|
||||
StorageThread self;
|
||||
};
|
||||
|
||||
K_GLOBAL_STATIC(StorageThreadSingleton, privateStorageThreadSelf)
|
||||
|
||||
|
||||
StorageThread::StorageThread(QObject *parent)
|
||||
: QThread(parent)
|
||||
{
|
||||
}
|
||||
|
||||
StorageThread::~StorageThread()
|
||||
{
|
||||
if (!QCoreApplication::closingDown()) {
|
||||
QString name = m_db.connectionName();
|
||||
QSqlDatabase::removeDatabase(name);
|
||||
}
|
||||
}
|
||||
|
||||
Plasma::StorageThread *StorageThread::self()
|
||||
{
|
||||
return &privateStorageThreadSelf->self;
|
||||
}
|
||||
|
||||
void StorageThread::initializeDb(StorageJob *caller)
|
||||
{
|
||||
if (!m_db.open()) {
|
||||
m_db = QSqlDatabase::addDatabase("QSQLITE", QString("plasma-storage-%1").arg((quintptr)this));
|
||||
m_db.setDatabaseName(KStandardDirs::locateLocal("appdata", "plasma-storage2.db"));
|
||||
}
|
||||
|
||||
if (!m_db.open()) {
|
||||
kWarning() << "Unable to open the plasma storage cache database: " << m_db.lastError();
|
||||
} else if (!m_db.tables().contains(caller->clientName())) {
|
||||
QSqlQuery query(m_db);
|
||||
query.prepare(QString("create table ") + caller->clientName() + " (valueGroup varchar(256), id varchar(256), txt TEXT, int INTEGER, float REAL, binary BLOB, creationTime datetime, accessTime datetime, primary key (valueGroup, id))");
|
||||
if (!query.exec()) {
|
||||
kWarning() << "Unable to create table for" << caller->clientName();
|
||||
m_db.close();
|
||||
}
|
||||
}
|
||||
m_db.transaction();
|
||||
}
|
||||
|
||||
void StorageThread::save(QWeakPointer<StorageJob> wcaller, const QVariantMap ¶ms)
|
||||
{
|
||||
StorageJob *caller = wcaller.data();
|
||||
if (!caller) {
|
||||
return;
|
||||
}
|
||||
|
||||
initializeDb(caller);
|
||||
QString valueGroup = params["group"].toString();
|
||||
if (valueGroup.isEmpty()) {
|
||||
valueGroup = "default";
|
||||
}
|
||||
QSqlQuery query(m_db);
|
||||
if (params.value("key").toString().isNull()) {
|
||||
caller->data().insert(params.value("key").toString(), params.value("data"));
|
||||
}
|
||||
|
||||
QHashIterator<QString, QVariant> it(caller->data());
|
||||
|
||||
QString ids;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
QSqlField field(":id", QVariant::String);
|
||||
field.setValue(it.key());
|
||||
if (!ids.isEmpty()) {
|
||||
ids.append(", ");
|
||||
}
|
||||
ids.append(m_db.driver()->formatValue(field));
|
||||
}
|
||||
|
||||
query.prepare("delete from " + caller->clientName() + " where valueGroup = :valueGroup and id in (" + ids + ");");
|
||||
query.bindValue(":valueGroup", valueGroup);
|
||||
|
||||
if (!query.exec()) {
|
||||
m_db.commit();
|
||||
emit newResult(caller, false);
|
||||
return;
|
||||
}
|
||||
|
||||
query.prepare("insert into " + caller->clientName() + " values(:valueGroup, :id, :txt, :int, :float, :binary, date('now'), date('now'))");
|
||||
query.bindValue(":valueGroup", valueGroup);
|
||||
query.bindValue(":txt", QVariant());
|
||||
query.bindValue(":int", QVariant());
|
||||
query.bindValue(":float", QVariant());
|
||||
query.bindValue(":binary", QVariant());
|
||||
|
||||
const QString key = params.value("key").toString();
|
||||
if (!key.isEmpty()) {
|
||||
caller->data().insert(key, params["data"]);
|
||||
}
|
||||
|
||||
it.toFront();
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
//kDebug() << "going to insert" << valueGroup << it.key();
|
||||
query.bindValue(":id", it.key());
|
||||
|
||||
QString field;
|
||||
bool binary = false;
|
||||
switch (it.value().type()) {
|
||||
case QVariant::String: {
|
||||
field = ":txt";
|
||||
break;
|
||||
}
|
||||
case QVariant::Int: {
|
||||
field = ":int";
|
||||
break;
|
||||
}
|
||||
case QVariant::Double:
|
||||
case QVariant::Float: {
|
||||
field = ":float";
|
||||
break;
|
||||
}
|
||||
case QVariant::ByteArray: {
|
||||
binary = true;
|
||||
field = ":binary";
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (binary) {
|
||||
QByteArray b;
|
||||
QDataStream ds(&b, QIODevice::WriteOnly);
|
||||
ds << it.value();
|
||||
query.bindValue(field, b);
|
||||
} else {
|
||||
query.bindValue(field, it.value());
|
||||
}
|
||||
|
||||
if (!query.exec()) {
|
||||
//kDebug() << "query failed:" << query.lastQuery() << query.lastError().text();
|
||||
m_db.commit();
|
||||
emit newResult(caller, false);
|
||||
return;
|
||||
}
|
||||
|
||||
query.bindValue(field, QVariant());
|
||||
}
|
||||
m_db.commit();
|
||||
|
||||
emit newResult(caller, true);
|
||||
}
|
||||
|
||||
void StorageThread::retrieve(QWeakPointer<StorageJob> wcaller, const QVariantMap ¶ms)
|
||||
{
|
||||
StorageJob *caller = wcaller.data();
|
||||
if (!caller) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QString clientName = caller->clientName();
|
||||
initializeDb(caller);
|
||||
QString valueGroup = params["group"].toString();
|
||||
if (valueGroup.isEmpty()) {
|
||||
valueGroup = "default";
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
|
||||
//a bit redundant but should be the faster way with less string concatenation as possible
|
||||
if (params["key"].toString().isEmpty()) {
|
||||
//update modification time
|
||||
query.prepare("update " + clientName + " set accessTime=date('now') where valueGroup=:valueGroup");
|
||||
query.bindValue(":valueGroup", valueGroup);
|
||||
query.exec();
|
||||
|
||||
query.prepare("select * from " + clientName + " where valueGroup=:valueGroup");
|
||||
query.bindValue(":valueGroup", valueGroup);
|
||||
} else {
|
||||
//update modification time
|
||||
query.prepare("update " + clientName + " set accessTime=date('now') where valueGroup=:valueGroup and id=:key");
|
||||
query.bindValue(":valueGroup", valueGroup);
|
||||
query.bindValue(":key", params["key"].toString());
|
||||
query.exec();
|
||||
|
||||
query.prepare("select * from " + clientName + " where valueGroup=:valueGroup and id=:key");
|
||||
query.bindValue(":valueGroup", valueGroup);
|
||||
query.bindValue(":key", params["key"].toString());
|
||||
}
|
||||
|
||||
const bool success = query.exec();
|
||||
|
||||
QVariant result;
|
||||
|
||||
if (success) {
|
||||
QSqlRecord rec = query.record();
|
||||
const int keyColumn = rec.indexOf("id");
|
||||
const int textColumn = rec.indexOf("txt");
|
||||
const int intColumn = rec.indexOf("int");
|
||||
const int floatColumn = rec.indexOf("float");
|
||||
const int binaryColumn = rec.indexOf("binary");
|
||||
|
||||
QVariantHash data;
|
||||
data.reserve(query.size());
|
||||
while (query.next()) {
|
||||
const QString key = query.value(keyColumn).toString();
|
||||
if (!query.value(textColumn).isNull()) {
|
||||
data.insert(key, query.value(textColumn));
|
||||
} else if (!query.value(intColumn).isNull()) {
|
||||
data.insert(key, query.value(intColumn));
|
||||
} else if (!query.value(floatColumn).isNull()) {
|
||||
data.insert(key, query.value(floatColumn));
|
||||
} else if (!query.value(binaryColumn).isNull()) {
|
||||
QByteArray bytes = query.value(binaryColumn).toByteArray();
|
||||
QDataStream in(bytes);
|
||||
QVariant v(in);
|
||||
data.insert(key, v);
|
||||
}
|
||||
}
|
||||
|
||||
result = data;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
|
||||
emit newResult(caller, result);
|
||||
}
|
||||
|
||||
void StorageThread::deleteEntry(QWeakPointer<StorageJob> wcaller, const QVariantMap ¶ms)
|
||||
{
|
||||
StorageJob *caller = wcaller.data();
|
||||
if (!caller) {
|
||||
return;
|
||||
}
|
||||
|
||||
initializeDb(caller);
|
||||
QString valueGroup = params["group"].toString();
|
||||
if (valueGroup.isEmpty()) {
|
||||
valueGroup = "default";
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
|
||||
if (params["key"].toString().isEmpty()) {
|
||||
query.prepare("delete from " + caller->clientName() + " where valueGroup=:valueGroup");
|
||||
query.bindValue(":valueGroup", valueGroup);
|
||||
} else {
|
||||
query.prepare("delete from " + caller->clientName() + " where valueGroup=:valueGroup and id=:key");
|
||||
query.bindValue(":valueGroup", valueGroup);
|
||||
query.bindValue(":key", params["key"].toString());
|
||||
}
|
||||
|
||||
const bool success = query.exec();
|
||||
m_db.commit();
|
||||
|
||||
emit newResult(caller, success);
|
||||
}
|
||||
|
||||
void StorageThread::expire(QWeakPointer<StorageJob> wcaller, const QVariantMap ¶ms)
|
||||
{
|
||||
StorageJob *caller = wcaller.data();
|
||||
if (!caller) {
|
||||
return;
|
||||
}
|
||||
|
||||
initializeDb(caller);
|
||||
QString valueGroup = params["group"].toString();
|
||||
if (valueGroup.isEmpty()) {
|
||||
valueGroup = "default";
|
||||
}
|
||||
|
||||
QSqlQuery query(m_db);
|
||||
if (valueGroup.isEmpty()) {
|
||||
query.prepare("delete from " + caller->clientName() + " where accessTime < :date");
|
||||
QDateTime time(QDateTime::currentDateTime());
|
||||
time.addSecs(-params["age"].toUInt());
|
||||
query.bindValue(":date", time.toTime_t());
|
||||
} else {
|
||||
query.prepare("delete from " + caller->clientName() + " where valueGroup=:valueGroup and accessTime < :date");
|
||||
query.bindValue(":valueGroup", valueGroup);
|
||||
QDateTime time(QDateTime::currentDateTime());
|
||||
time.addSecs(-params["age"].toUInt());
|
||||
query.bindValue(":date", time.toTime_t());
|
||||
}
|
||||
|
||||
const bool success = query.exec();
|
||||
|
||||
emit newResult(caller, success);
|
||||
}
|
||||
|
||||
void StorageThread::run()
|
||||
{
|
||||
exec();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "moc_storagethread_p.cpp"
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef STORAGETHREAD_H
|
||||
#define STORAGETHREAD_H
|
||||
|
||||
|
||||
#include <QThread>
|
||||
#include <QSqlDatabase>
|
||||
#include <QtCore/qsharedpointer.h>
|
||||
|
||||
#include "storage_p.h"
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class StorageThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StorageThread(QObject *parent = 0);
|
||||
~StorageThread();
|
||||
|
||||
void run();
|
||||
|
||||
static Plasma::StorageThread *self();
|
||||
|
||||
public Q_SLOTS:
|
||||
void save(QWeakPointer<StorageJob> caller, const QVariantMap ¶meters);
|
||||
void retrieve(QWeakPointer<StorageJob> caller, const QVariantMap ¶meters);
|
||||
void deleteEntry(QWeakPointer<StorageJob> caller, const QVariantMap ¶meters);
|
||||
void expire(QWeakPointer<StorageJob> caller, const QVariantMap ¶meters);
|
||||
|
||||
Q_SIGNALS:
|
||||
void newResult(StorageJob* caller, const QVariant &result);
|
||||
|
||||
private:
|
||||
void initializeDb(StorageJob* caller);
|
||||
QSqlDatabase m_db;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -18,18 +18,3 @@ PLASMA_UNIT_TESTS(
|
|||
runnercontexttest
|
||||
configloadertest
|
||||
)
|
||||
|
||||
set(storatetest_SRCS
|
||||
storagetest.cpp
|
||||
../private/storage.cpp
|
||||
../private/storagethread.cpp
|
||||
)
|
||||
|
||||
kde4_add_test(plasma-storagetest ${storatetest_SRCS})
|
||||
target_link_libraries(plasma-storagetest
|
||||
${KDE4_KIO_LIBS}
|
||||
${KDE4_PLASMA_LIBS}
|
||||
${QT_QTTEST_LIBRARY}
|
||||
${QT_QTDECLARATIVE_LIBRARY}
|
||||
${QT_QTSQL_LIBRARY}
|
||||
)
|
||||
|
|
|
@ -1,96 +0,0 @@
|
|||
/********************************************************************************
|
||||
* Copyright 2010 by Martin Blumenstingl <darklight.xdarklight@googlemail.com> *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public License *
|
||||
* along with this library; see the file COPYING.LIB. If not, write to *
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
||||
* Boston, MA 02110-1301, USA. *
|
||||
*********************************************************************************/
|
||||
|
||||
#include "storagetest.h"
|
||||
|
||||
#include "../private/storage_p.h"
|
||||
|
||||
void StorageTest::init()
|
||||
{
|
||||
m_data.insert("String 1", "Fork");
|
||||
m_data.insert("String 2", "Spoon");
|
||||
m_data.insert("String 3", "Knife");
|
||||
m_data.insert("Int 1", 3141);
|
||||
m_data.insert("Int 2", 60);
|
||||
QByteArray bytes("yadda yadda yadda");
|
||||
m_data.insert("Binary Data", bytes);
|
||||
}
|
||||
|
||||
void StorageTest::store()
|
||||
{
|
||||
Storage storage;
|
||||
KConfigGroup op = storage.operationDescription("save");
|
||||
op.writeEntry("group", "Test");
|
||||
Plasma::ServiceJob *job = storage.startOperationCall(op);
|
||||
StorageJob *storageJob = qobject_cast<StorageJob *>(job);
|
||||
|
||||
QVERIFY(storageJob);
|
||||
storageJob->setAutoDelete(false);
|
||||
storageJob->setData(m_data);
|
||||
QVERIFY(storageJob->exec());
|
||||
QVERIFY(storageJob->result().toBool());
|
||||
storageJob->deleteLater();
|
||||
}
|
||||
|
||||
void StorageTest::retrieve()
|
||||
{
|
||||
Storage storage;
|
||||
KConfigGroup op = storage.operationDescription("retrieve");
|
||||
op.writeEntry("group", "Test");
|
||||
Plasma::ServiceJob *job = storage.startOperationCall(op);
|
||||
StorageJob *storageJob = qobject_cast<StorageJob *>(job);
|
||||
|
||||
QVERIFY(storageJob);
|
||||
storageJob->setAutoDelete(false);
|
||||
QVERIFY(storageJob->exec());
|
||||
QVERIFY(storageJob->result().type() != QVariant::Bool);
|
||||
QCOMPARE(storageJob->data(), m_data);
|
||||
storageJob->deleteLater();
|
||||
}
|
||||
|
||||
void StorageTest::deleteEntry()
|
||||
{
|
||||
Storage storage;
|
||||
KConfigGroup op = storage.operationDescription("delete");
|
||||
op.writeEntry("group", "Test");
|
||||
Plasma::ServiceJob *job = storage.startOperationCall(op);
|
||||
StorageJob *storageJob = qobject_cast<StorageJob *>(job);
|
||||
|
||||
QVERIFY(storageJob);
|
||||
storageJob->setAutoDelete(false);
|
||||
storageJob->setData(m_data);
|
||||
QVERIFY(storageJob->exec());
|
||||
QVERIFY(storageJob->result().toBool());
|
||||
storageJob->deleteLater();
|
||||
|
||||
op = storage.operationDescription("retrieve");
|
||||
op.writeEntry("group", "Test");
|
||||
job = storage.startOperationCall(op);
|
||||
storageJob = qobject_cast<StorageJob *>(job);
|
||||
|
||||
QVERIFY(storageJob);
|
||||
storageJob->setAutoDelete(false);
|
||||
QVERIFY(storageJob->exec());
|
||||
QVERIFY(storageJob->result().type() != QVariant::Bool);
|
||||
QVERIFY(storageJob->data().isEmpty());
|
||||
storageJob->deleteLater();
|
||||
}
|
||||
|
||||
QTEST_KDEMAIN(StorageTest, NoGUI)
|
||||
|
Loading…
Add table
Reference in a new issue