Redid much of the storage capability and implemented many suggestions.
svn path=/trunk/KDE/kdelibs/; revision=1156347
This commit is contained in:
parent
fb56692aa8
commit
1259ea24cd
@ -16,13 +16,10 @@
|
||||
* Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "datacontainer.h"
|
||||
#include "private/datacontainer_p.h"
|
||||
#include "private/storage_p.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
#include "plasma.h"
|
||||
@ -57,7 +54,15 @@ void DataContainer::setData(const QString &key, const QVariant &value)
|
||||
d->dirty = true;
|
||||
d->updateTs.start();
|
||||
|
||||
d->isStored = false;
|
||||
//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()) {
|
||||
QTimer::singleShot(180000, this, SLOT(store()));
|
||||
}
|
||||
|
||||
setNeedsToBeStored(true);
|
||||
}
|
||||
|
||||
void DataContainer::removeAllData()
|
||||
@ -141,7 +146,12 @@ void DataContainer::connectVisualization(QObject *visualization, uint pollingInt
|
||||
|
||||
void DataContainer::setStorageEnable(bool store)
|
||||
{
|
||||
QTime time = QTime::currentTime();
|
||||
qsrand((uint)time.msec());
|
||||
d->enableStorage = store;
|
||||
if (store) {
|
||||
QTimer::singleShot(qrand() % (2000 + 1) , this, SLOT(retrieve()));
|
||||
}
|
||||
}
|
||||
|
||||
bool DataContainer::isStorageEnabled() const
|
||||
@ -151,7 +161,7 @@ bool DataContainer::isStorageEnabled() const
|
||||
|
||||
bool DataContainer::needsToBeStored() const
|
||||
{
|
||||
return (d->enableStorage && !d->isStored);
|
||||
return !d->isStored;
|
||||
}
|
||||
|
||||
void DataContainer::setNeedsToBeStored(bool store)
|
||||
@ -159,6 +169,103 @@ void DataContainer::setNeedsToBeStored(bool store)
|
||||
d->isStored = !store;
|
||||
}
|
||||
|
||||
DataEngine* DataContainer::getDataEngine()
|
||||
{
|
||||
QObject *o = NULL;
|
||||
DataEngine *de = NULL;
|
||||
o = this;
|
||||
while (de == NULL)
|
||||
{
|
||||
o = dynamic_cast<QObject *> (o->parent());
|
||||
if (o == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
de = dynamic_cast<DataEngine *> (o);
|
||||
}
|
||||
return de;
|
||||
}
|
||||
|
||||
void DataContainer::store()
|
||||
{
|
||||
if (!needsToBeStored()){
|
||||
return;
|
||||
}
|
||||
DataEngine* de = getDataEngine();
|
||||
if (de == NULL) {
|
||||
return;
|
||||
}
|
||||
setNeedsToBeStored(false);
|
||||
Storage* store = new Storage(de->name(), 0);
|
||||
KConfigGroup op = store->operationDescription("save");
|
||||
op.writeEntry("source", objectName());
|
||||
DataEngine::Data dataToStore = data();
|
||||
DataEngine::Data::const_iterator it = dataToStore.constBegin();
|
||||
while (it != dataToStore.constEnd() && dataToStore.constEnd() == data().constEnd()) {
|
||||
QVariant v = it.value();
|
||||
if ((it.value().type() == QVariant::String) || (it.value().type() == QVariant::Int)) {
|
||||
op.writeEntry("key", it.key());
|
||||
op.writeEntry("data", it.value());
|
||||
} else {
|
||||
QByteArray b;
|
||||
QDataStream ds(&b, QIODevice::WriteOnly);
|
||||
ds << it.value();
|
||||
op.writeEntry("key", "base64-" + it.key());
|
||||
op.writeEntry("data", b.toBase64());
|
||||
}
|
||||
++it;
|
||||
ServiceJob* job = store->startOperationCall(op);
|
||||
job->start();
|
||||
}
|
||||
|
||||
//FIXME: this may result in the service being deleted before the jobs ... resulting in the
|
||||
//jobs potentially being terminated prematurely
|
||||
store->deleteLater();
|
||||
}
|
||||
|
||||
void DataContainer::retrieve()
|
||||
{
|
||||
DataEngine* de = getDataEngine();
|
||||
if (de == NULL) {
|
||||
return;
|
||||
}
|
||||
Storage* store = new Storage(de->name(), 0);
|
||||
KConfigGroup retrieveGroup = store->operationDescription("retrieve");
|
||||
retrieveGroup.writeEntry("source", objectName());
|
||||
ServiceJob* retrieveJob = store->startOperationCall(retrieveGroup);
|
||||
connect(retrieveJob, SIGNAL(result(KJob*)), this,
|
||||
SLOT(populateFromStoredData(KJob*)));
|
||||
}
|
||||
|
||||
void DataContainer::populateFromStoredData(KJob *job)
|
||||
{
|
||||
if (job->error()) {
|
||||
return;
|
||||
}
|
||||
DataEngine::Data dataToInsert;
|
||||
ServiceJob* ret = dynamic_cast<ServiceJob*>(job);
|
||||
QHash<QString, QVariant> h = ret->result().toHash();
|
||||
foreach (QString key, h.keys()) {
|
||||
if (key.startsWith("base64-")) {
|
||||
QByteArray b = QByteArray::fromBase64(h[key].toString().toAscii());
|
||||
QDataStream ds(&b, QIODevice::ReadOnly);
|
||||
QVariant v(ds);
|
||||
key.remove(0, 7);
|
||||
dataToInsert.insert(key, v);
|
||||
} else {
|
||||
dataToInsert.insert(key, h[key]);
|
||||
}
|
||||
}
|
||||
if (!(d->data.isEmpty()))
|
||||
{
|
||||
//Do not fill the source with old stored
|
||||
//data if it is already populated with new data.
|
||||
return;
|
||||
}
|
||||
d->data = dataToInsert;
|
||||
d->dirty = true;
|
||||
checkForUpdate();
|
||||
}
|
||||
|
||||
void DataContainer::disconnectVisualization(QObject *visualization)
|
||||
{
|
||||
QMap<QObject *, SignalRelay *>::iterator objIt = d->relayObjects.find(visualization);
|
||||
|
@ -22,7 +22,9 @@
|
||||
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
#include <kjob.h>
|
||||
#include <plasma/plasma_export.h>
|
||||
#include <plasma/dataengine.h>
|
||||
|
||||
@ -144,6 +146,12 @@ class PLASMA_EXPORT DataContainer : public QObject
|
||||
*/
|
||||
void setNeedsToBeStored(bool store);
|
||||
|
||||
/**
|
||||
* @return the DataEngine that the DataContainer is
|
||||
* a child of.
|
||||
*/
|
||||
DataEngine* getDataEngine();
|
||||
|
||||
public Q_SLOTS:
|
||||
/**
|
||||
* Disconnects an object from this DataContainer.
|
||||
@ -159,6 +167,16 @@ class PLASMA_EXPORT DataContainer : public QObject
|
||||
*/
|
||||
void forceImmediateUpdate();
|
||||
|
||||
/**
|
||||
* Stores the DataContainer to disk.
|
||||
*/
|
||||
void store();
|
||||
|
||||
/**
|
||||
* Retrieves the DataContainer from disk.
|
||||
*/
|
||||
void retrieve();
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Emitted when the data has been updated, allowing visualizations to
|
||||
@ -235,6 +253,12 @@ class PLASMA_EXPORT DataContainer : public QObject
|
||||
**/
|
||||
void checkUsage();
|
||||
|
||||
/**
|
||||
* Does the work of putting the data from disk into the DataContainer
|
||||
* after retrieve() sets it up.
|
||||
*/
|
||||
void populateFromStoredData(KJob *job);
|
||||
|
||||
private:
|
||||
friend class SignalRelay;
|
||||
DataContainerPrivate *const d;
|
||||
|
@ -200,12 +200,6 @@ void DataEngine::setData(const QString &source, const QString &key, const QVaria
|
||||
emit sourceAdded(source);
|
||||
}
|
||||
|
||||
if (s->isStorageEnabled()) {
|
||||
//FIXME: broken. one can't pass in parameters to a slot like this.
|
||||
// this probably belongs in DataContainer in any case
|
||||
QTimer::singleShot(180000, this, SLOT(storeSource(objectName())));
|
||||
}
|
||||
|
||||
scheduleSourcesUpdated();
|
||||
}
|
||||
|
||||
@ -224,12 +218,6 @@ void DataEngine::setData(const QString &source, const Data &data)
|
||||
++it;
|
||||
}
|
||||
|
||||
if (s->isStorageEnabled()) {
|
||||
//FIXME: broken. one can't pass in parameters to a slot like this.
|
||||
// this probably belongs in DataContainer in any case
|
||||
QTimer::singleShot(180000, this, SLOT(storeSource(objectName())));
|
||||
}
|
||||
|
||||
if (isNew) {
|
||||
emit sourceAdded(source);
|
||||
}
|
||||
@ -333,7 +321,7 @@ void DataEngine::removeSource(const QString &source)
|
||||
}
|
||||
}
|
||||
|
||||
d->storeSource(s);
|
||||
s->store();
|
||||
s->disconnect(this);
|
||||
s->deleteLater();
|
||||
d->sources.erase(it);
|
||||
@ -680,7 +668,6 @@ void DataEnginePrivate::connectSource(DataContainer *s, QObject *visualization,
|
||||
!s->visualizationIsConnected(visualization);
|
||||
}
|
||||
|
||||
retrieveStoredData(s);
|
||||
s->connectVisualization(visualization, pollingInterval, align);
|
||||
|
||||
if (immediateCall) {
|
||||
@ -763,84 +750,6 @@ void DataEnginePrivate::setupScriptSupport()
|
||||
}
|
||||
}
|
||||
|
||||
void DataEnginePrivate::storeAllSources()
|
||||
{
|
||||
//kDebug() << "cache all sources";
|
||||
foreach (QString sourceName, q->sources()) {
|
||||
DataContainer *s = q->d->source(sourceName, false);
|
||||
storeSource(s);
|
||||
}
|
||||
}
|
||||
|
||||
void DataEnginePrivate::storeSource(DataContainer *s) const
|
||||
{
|
||||
return;
|
||||
if (!s || !s->needsToBeStored()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: this should probably be moved into DataContainer, e.g. DataContainer::store()
|
||||
s->setNeedsToBeStored(false);
|
||||
Storage* store = new Storage(q->name(), 0);
|
||||
KConfigGroup op = store->operationDescription("save");
|
||||
op.writeEntry("source", s->objectName());
|
||||
DataEngine::Data dataToStore = s->data();
|
||||
DataEngine::Data::const_iterator it = dataToStore.constBegin();
|
||||
//FIXME: this shouldn't be one job per key/value pair, but one job for the entire container
|
||||
while (it != dataToStore.constEnd() && dataToStore.constEnd() == s->data().constEnd()) {
|
||||
QVariant v = it.value();
|
||||
if ((it.value().type() == QVariant::String) || (it.value().type() == QVariant::Int)) {
|
||||
op.writeEntry("key", it.key());
|
||||
op.writeEntry("data", it.value());
|
||||
} else {
|
||||
QByteArray b;
|
||||
QDataStream ds(&b, QIODevice::WriteOnly);
|
||||
ds << it.value();
|
||||
op.writeEntry("key", "base64-" + it.key());
|
||||
op.writeEntry("data", b.toBase64());
|
||||
}
|
||||
++it;
|
||||
ServiceJob* job = store->startOperationCall(op);
|
||||
job->start();
|
||||
}
|
||||
|
||||
//FIXME: this may result in the service being deleted before the jobs ... resulting in the
|
||||
//jobs potentially being terminated prematurely
|
||||
store->deleteLater();
|
||||
}
|
||||
|
||||
void DataEnginePrivate::retrieveStoredData(DataContainer *s)
|
||||
{
|
||||
if (!s || !s->isStorageEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//FIXME: this should probably move into DataContainer, and be triggered in setStorageEnabled
|
||||
// when it is set to true
|
||||
Storage* store = new Storage(q->name(), 0);
|
||||
KConfigGroup ret = store->operationDescription("retrieve");
|
||||
ret.writeEntry("source", s->objectName());
|
||||
ServiceJob* retrieve = store->startOperationCall(ret);
|
||||
QVariant retrievedData;
|
||||
retrieve->start();
|
||||
while (!retrieve->error()) {
|
||||
QHash<QString, QVariant> h = retrieve->result().toHash();
|
||||
QString key = h["key"].value<QString>();
|
||||
if (key.startsWith("base64-")) {
|
||||
QByteArray b = QByteArray::fromBase64(h["data"].toString().toAscii());
|
||||
QDataStream ds(&b, QIODevice::ReadOnly);
|
||||
QVariant v(ds);
|
||||
key.remove(0, 7);
|
||||
retrievedData = v;
|
||||
} else {
|
||||
retrievedData = h["data"];
|
||||
}
|
||||
s->setData(key, retrievedData);
|
||||
retrieve->start();
|
||||
}
|
||||
s->checkForUpdate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "dataengine.moc"
|
||||
|
@ -500,8 +500,6 @@ NoAlignment) const;
|
||||
|
||||
Q_PRIVATE_SLOT(d, void internalUpdateSource(DataContainer *source))
|
||||
Q_PRIVATE_SLOT(d, void sourceDestroyed(QObject *object))
|
||||
Q_PRIVATE_SLOT(d, void storeAllSources())
|
||||
Q_PRIVATE_SLOT(d, void storeSource(DataContainer *source) const)
|
||||
|
||||
DataEnginePrivate *const d;
|
||||
};
|
||||
|
@ -22,10 +22,11 @@
|
||||
|
||||
#include <QtCore/QTimerEvent>
|
||||
#include <QtCore/QTime>
|
||||
#include "servicejob.h"
|
||||
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class ServiceJob;
|
||||
class SignalRelay;
|
||||
|
||||
class DataContainerPrivate
|
||||
@ -43,6 +44,7 @@ public:
|
||||
bool immediateUpdate);
|
||||
|
||||
bool hasUpdates();
|
||||
void populateFromStoredData(KJob *job);
|
||||
|
||||
DataEngine::Data data;
|
||||
QMap<QObject *, SignalRelay *> relayObjects;
|
||||
|
@ -18,7 +18,6 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA //
|
||||
// 02110-1301 USA //
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "private/storage_p.h"
|
||||
#include <kdebug.h>
|
||||
|
||||
@ -33,38 +32,25 @@ StorageJob::StorageJob(const QString& destination,
|
||||
|
||||
void StorageJob::start()
|
||||
{
|
||||
static QStringList* keyList = NULL;
|
||||
QMap<QString, QVariant> params = parameters();
|
||||
QString source = params["source"].toString();
|
||||
KConfig config("plasma-storagerc");
|
||||
KConfigGroup destinationGroup(&config, destination());
|
||||
KConfigGroup sourceGroup(&destinationGroup, source);
|
||||
KConfigGroup data(&sourceGroup, "Data");
|
||||
|
||||
KConfigGroup dataGroup(&sourceGroup, "Data");
|
||||
if (operationName() == "save") {
|
||||
// KConfigGroup metaData(&sourceGroup, "MetaData");
|
||||
// metaData.writeEntry("TimeStamp", QDateTime::currentDateTime());
|
||||
data.writeEntry(params["key"].toString(), params["data"]);
|
||||
setResult(true);
|
||||
dataGroup.writeEntry(params["key"].toString(), params["data"]);
|
||||
setResult(true);
|
||||
return;
|
||||
} else if (operationName() == "retrieve") {
|
||||
if (keyList == NULL) {
|
||||
kDebug() << "NULL";
|
||||
keyList = new QStringList;
|
||||
*keyList = data.keyList();
|
||||
QHash<QString, QVariant> h;
|
||||
foreach(QString key, dataGroup.keyList())
|
||||
{
|
||||
QVariant v(dataGroup.readEntry(key));
|
||||
h[key] = v;
|
||||
}
|
||||
if (keyList->isEmpty()) {
|
||||
setError(1);
|
||||
delete keyList;
|
||||
keyList = NULL;
|
||||
} else {
|
||||
QString key = keyList->first();
|
||||
QHash<QString, QVariant> h;
|
||||
QVariant v(data.readEntry(key));
|
||||
h["key"] = key;
|
||||
h["data"] = v;
|
||||
keyList->pop_front();
|
||||
setResult(h);
|
||||
}
|
||||
setResult(h);
|
||||
return;
|
||||
}
|
||||
setError(1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user