OSDN Git Service

kget: replace SQL with JSON history backend
authorIvailo Monev <xakepa10@gmail.com>
Sat, 2 Oct 2021 01:12:57 +0000 (04:12 +0300)
committerIvailo Monev <xakepa10@gmail.com>
Sat, 2 Oct 2021 01:14:44 +0000 (04:14 +0300)
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
12 files changed:
kget/CMakeLists.txt
kget/conf/preferencesdialog.cpp
kget/core/transferhistorystore.cpp
kget/core/transferhistorystore.h
kget/core/transferhistorystore_json.cpp [new file with mode: 0644]
kget/core/transferhistorystore_json_p.h [new file with mode: 0644]
kget/core/transferhistorystore_sqlite_p.h [deleted file]
kget/core/transferhistorystore_xml.cpp [new file with mode: 0644]
kget/transfer-plugins/torrent/transferTorrent.cpp
kget/transfer-plugins/torrent/transferTorrent.h
kget/transfer-plugins/torrent/transferTorrentFactory.cpp
kget/transfer-plugins/torrent/transferTorrentFactory.h

index aafefa2..a05eaf2 100644 (file)
@@ -117,6 +117,8 @@ set(kgetcore_SRCS
    core/bitset.cpp
    core/download.cpp
    core/transferhistorystore.cpp
+   core/transferhistorystore_xml.cpp
+   core/transferhistorystore_json.cpp
    core/linkimporter.cpp
    dbus/dbustransferwrapper.cpp
    dbus/dbusverifierwrapper.cpp
@@ -144,7 +146,6 @@ add_library(kgetcore SHARED ${kgetcore_SRCS})
 target_link_libraries(kgetcore
     ${KDE4_KIO_LIBS}
     ${KDE4_SOLID_LIBS}
-    ${QT_QTSQL_LIBRARY}
 )
 
 if (KDE4WORKSPACE_FOUND)
index 6d265cb..ab042da 100644 (file)
@@ -20,8 +20,6 @@
 #include "pluginselector.h"
 #include "verificationpreferences.h"
 
-#include <QSqlDatabase>
-
 #include <klocale.h>
 #include <ktabwidget.h>
 
@@ -50,10 +48,8 @@ PreferencesDialog::PreferencesDialog(QWidget * parent, KConfigSkeleton * skeleto
     dlgAdv.setupUi(advanced);
 
     // history backend entries
+    dlgAdv.kcfg_HistoryBackend->addItem(i18n("Json"), QVariant(TransferHistoryStore::Json));
     dlgAdv.kcfg_HistoryBackend->addItem(i18n("Xml"), QVariant(TransferHistoryStore::Xml));
-    if (QSqlDatabase::isDriverAvailable("QSQLITE")) {
-        dlgAdv.kcfg_HistoryBackend->addItem(i18n("Sqlite"), QVariant(TransferHistoryStore::SQLite));
-    }
 
 #ifdef HAVE_KWORKSPACE
     dlgAdv.kcfg_AfterFinishAction->addItem(i18n("Turn Off Computer"), QVariant(KGet::Shutdown));
index ba62e3d..d175835 100644 (file)
@@ -10,7 +10,7 @@
 */
 #include "core/transferhistorystore.h"
 #include "core/transferhistorystore_xml_p.h"
-#include "core/transferhistorystore_sqlite_p.h"
+#include "core/transferhistorystore_json_p.h"
 #include "core/transfer.h"
 #include "settings.h"
 
 #include <QList>
 #include <QThread>
 #include <QTimer>
-#include <QSqlDatabase>
-#include <QSqlError>
-#include <QSqlQuery>
-#include <QSqlRecord>
 
 #include <KDebug>
-#include <kio/global.h>
 #include <KLocale>
-#include <KMessageBox>
 #include <KStandardDirs>
 
 TransferHistoryItem::TransferHistoryItem() : QObject()
@@ -137,383 +131,12 @@ TransferHistoryStore *TransferHistoryStore::getStore()
 {
     switch(Settings::historyBackend())
     {
-        case TransferHistoryStore::SQLite:
-            return new SQLiteStore(KStandardDirs::locateLocal("appdata", "transferhistory.db"));
         case TransferHistoryStore::Xml:
-        default:
             return new XmlStore(KStandardDirs::locateLocal("appdata", "transferhistory.kgt"));
-    }
-}
-
-XmlStore::SaveThread::SaveThread(QObject *parent, const QString &url, const QList<TransferHistoryItem> &list) : QThread(parent),
-    m_url(url),
-    m_items(list),
-    m_item()
-{
-}
-
-XmlStore::SaveThread::SaveThread(QObject *parent, const QString &url, const TransferHistoryItem &item) : QThread(parent),
-    m_url(url),
-    m_items(),
-    m_item(item)
-{
-}
-
-void XmlStore::SaveThread::run()
-{
-    QFile file(m_url);
-    QDomDocument *doc;
-    QDomElement root;
-
-    if (!file.exists())
-    {
-        doc = new QDomDocument("Transfers");
-        root = doc->createElement("Transfers");
-        doc->appendChild(root);
-    }
-    else
-    {
-        doc = new QDomDocument();
-        doc->setContent(&file);
-        file.close();
-        root = doc->documentElement();
-        doc->appendChild(root);
-    }
-
-    QDomElement e = doc->createElement("Transfer");
-    root.appendChild(e);
-
-    e.setAttribute("Source", m_item.source());
-    e.setAttribute("Dest", m_item.dest());
-    e.setAttribute("Time", QDateTime::currentDateTime().toTime_t());
-    e.setAttribute("Size", QString::number(m_item.size()));
-    e.setAttribute("State", QString::number(m_item.state()));
-
-    if (file.open(QFile::WriteOnly | QFile::Truncate)) {
-        QTextStream stream( &file );
-        doc->save( stream, 0 );
-        file.close();
-    }
-    delete doc;
-}
-
-XmlStore::DeleteThread::DeleteThread(QObject *parent, const QString &url, const TransferHistoryItem &item) : QThread(parent),
-    m_url(url),
-    m_item(item),
-    m_items()
-{
-}
-
-void XmlStore::DeleteThread::run()
-{
-    QDomDocument doc("tempHistory");
-    QFile file(m_url);
-
-    QString error;
-    int line;
-    int column;
-
-    if (!doc.setContent(&file, &error, &line, &column)) 
-    {
-        kDebug(5001) << "Error1" << error << line << column;
-        return;
-    }
-    file.close();
-
-    QDomElement root = doc.documentElement();
-
-    QDomNodeList list = root.elementsByTagName("Transfer");
-
-    int nItems = list.length();
-
-    for (int i = 0 ; i < nItems ; i++) {
-        QDomElement element = list.item(i).toElement();
-
-        if(QString::compare(element.attribute("Source"), m_item.source()) == 0) {
-            root.removeChild(element);
-        }
-        else {
-            TransferHistoryItem item;
-            item.setDest(element.attribute("Dest"));
-            item.setSource(element.attribute("Source"));
-            item.setSize(element.attribute("Size").toInt());
-            item.setDateTime(QDateTime::fromTime_t(element.attribute("Time").toUInt()));
-            item.setState(element.attribute("State").toInt());
-            m_items << item;
-        }
-    }
-
-    if (file.open(QFile::WriteOnly | QFile::Truncate)) {
-        QTextStream stream( &file );
-        doc.save(stream, 0);
-        file.close();
-        doc.clear();
-    }
-}
-
-XmlStore::LoadThread::LoadThread(QObject *parent, const QString &url) : QThread(parent),
-    m_url(url)
-{
-}
-
-void XmlStore::LoadThread::run()
-{
-    qRegisterMetaType<TransferHistoryItem>("TransferHistoryItem");
-    QDomDocument doc("tempHistory");
-    QFile file(m_url);
-
-    QString error;
-    int line;
-    int column;
-    int total;
-
-    if (!doc.setContent(&file, &error, &line, &column)) 
-    {
-        kDebug(5001) << "Error1" << error << line << column;
-        file.close();
-        return;
-    }
-
-    QDomElement root = doc.documentElement();
-    total = root.childNodes().size();
-
-    QDomNodeList list = root.elementsByTagName("Transfer");
-
-    int nItems = list.length();
-
-    for (int i = 0 ; i < nItems ; i++)
-    {
-        QDomElement dom = list.item(i).toElement();
-        
-        TransferHistoryItem item;
-        item.setDest(dom.attribute("Dest"));
-        item.setSource(dom.attribute("Source"));
-        item.setSize(dom.attribute("Size").toInt());
-        item.setDateTime(QDateTime::fromTime_t(dom.attribute("Time").toUInt()));
-        item.setState(dom.attribute("State").toInt());
-
-        emit elementLoaded(i, total, item);
-    }
-    doc.clear();
-    file.close();
-}
-
-XmlStore::XmlStore(const QString &url) : TransferHistoryStore(),
-    m_storeUrl(url),
-    m_loadThread(0),
-    m_saveThread(0),
-    m_deleteThread(0)
-{
-}
-
-XmlStore::~XmlStore()
-{
-    if(m_loadThread && m_loadThread->isRunning()) {
-        m_loadThread->terminate();
-    }
-
-    if(m_saveThread && m_saveThread->isRunning()) {
-        m_saveThread->terminate();
-    }
-
-    if(m_deleteThread && m_deleteThread->isRunning()) {
-        m_deleteThread->terminate();
-    }
-
-    delete m_loadThread;
-    delete m_saveThread;
-    delete m_deleteThread;
-}
-
-void XmlStore::load()
-{
-    m_items.clear();
-    // TODO: only load if necessary
-    m_loadThread = new XmlStore::LoadThread(this, m_storeUrl);
-
-    connect(m_loadThread, SIGNAL(finished()), SIGNAL(loadFinished()));
-    connect(m_loadThread, SIGNAL(elementLoaded(int,int,TransferHistoryItem)),
-                        SIGNAL(elementLoaded(int,int,TransferHistoryItem)));
-    connect(m_loadThread, SIGNAL(elementLoaded(int,int,TransferHistoryItem)),
-                        SLOT(slotLoadElement(int,int,TransferHistoryItem)));
-    m_loadThread->start();
-}
-
-void XmlStore::clear()
-{
-    QFile::remove(m_storeUrl);
-}
-
-void XmlStore::saveItem(const TransferHistoryItem &item)
-{
-    m_saveThread = new XmlStore::SaveThread(this, m_storeUrl, item);
-
-    connect(m_saveThread, SIGNAL(finished()), SIGNAL(saveFinished()));
-    connect(m_saveThread, SIGNAL(elementLoaded(int,int,TransferHistoryItem)),
-                        SIGNAL(elementLoaded(int,int,TransferHistoryItem)));
-    m_saveThread->start();
-}
-
-void XmlStore::deleteItem(const TransferHistoryItem &item)
-{
-    Q_UNUSED(item)
-
-    m_deleteThread = new XmlStore::DeleteThread(this, m_storeUrl, item);
-
-    connect(m_deleteThread, SIGNAL(finished()), SLOT(slotDeleteElement()));
-
-    m_deleteThread->start();
-}
-
-void XmlStore::slotLoadElement(int number, int total, const TransferHistoryItem &item)
-{
-    Q_UNUSED(number)
-    Q_UNUSED(total)
-    m_items.append(item);
-}
-
-void XmlStore::slotDeleteElement()
-{
-    m_items.clear();
-    m_items << m_deleteThread->items();
-
-    emit loadFinished();
-}
-
-SQLiteStore::SQLiteStore(const QString &database) : TransferHistoryStore(),
-    m_dbName(database),
-    m_sql()
-{
-}
-
-SQLiteStore::~SQLiteStore()
-{
-    if (m_sql.isOpen()) {
-        m_sql.close();
-    }
-}
-
-void SQLiteStore::load()
-{
-    m_items.clear();
-    if (sql().open()) {
-        if (!sql().tables().contains("transfer_history_item")) {
-            createTables();
-        }
-
-        QSqlQuery query = sql().exec("SELECT * FROM transfer_history_item");
-
-        if (query.lastError().isValid()) {
-            kDebug(5001) << query.lastError().text();
-        }
-        else {
-            QSqlRecord rec = query.record();
-
-            while (query.next()) {
-                TransferHistoryItem item;
-                item.setDest(query.value(rec.indexOf("dest")).toString());
-                item.setSource(query.value(rec.indexOf("source")).toString());
-                item.setState(query.value(rec.indexOf("state")).toInt());
-                item.setDateTime(QDateTime::fromTime_t(query.value(rec.indexOf("time")).toUInt()));
-                item.setSize(query.value(rec.indexOf("size")).toInt());
-
-                m_items << item;
-                emit elementLoaded(query.at(), query.size(), item);
-            }
-        }
-    }
-
-    sql().close();
-
-    emit loadFinished();
-}
-
-void SQLiteStore::clear()
-{
-    QFile::remove(m_dbName);
-}
-
-void SQLiteStore::saveItem(const TransferHistoryItem &item)
-{
-    saveItems(QList<TransferHistoryItem>() << item);
-}
-
-void SQLiteStore::saveItems(const QList<TransferHistoryItem> &items)
-{
-    if (sql().open()) {
-        if (!sql().tables().contains("transfer_history_item")) {
-            createTables();
-        }
-
-        if (!sql().transaction()) {
-            kWarning(5001) << "Could not establish a transaction, might be slow.";
-        }
-
-        foreach (const TransferHistoryItem &item, items) {
-            QSqlQuery query = sql().exec("insert into transfer_history_item(source, dest, size, time, state)"
-                                "values ('"+item.source()+"', '"+item.dest()+"', "
-                                + QString::number(item.size()) + ", "
-                                + QString::number(item.dateTime().toTime_t()) + ", '"
-                                + QString::number(item.state())+"')");
-
-            if (query.lastError().isValid()) {
-                kDebug(5001) << query.lastError().text();
-            }
-            m_items << item;
-        }
-
-        if (!sql().commit()) {
-            kWarning(5001) << "Could not commit changes.";
-        }
-    }
-    sql().close();
-
-    emit saveFinished();
-}
-
-void SQLiteStore::deleteItem(const TransferHistoryItem &item)
-{
-    if (sql().open()) {
-        if (!sql().tables().contains("transfer_history_item")) {
-            createTables();
-        }
-
-        QSqlQuery query = sql().exec("delete from transfer_history_item where "
-                                            " source = '" + item.source() + "';");
-
-        if (query.lastError().isValid()) {
-            kDebug(5001) << query.lastError().text();
-        }
-
-        sql().commit();
-        m_items.removeAll(item);
-    }
-    sql().close();
-
-    emit deleteFinished();
-}
-
-QSqlDatabase SQLiteStore::sql()
-{
-    if (!m_sql.isValid()) {
-        m_sql = QSqlDatabase::addDatabase("QSQLITE");
-        m_sql.setDatabaseName(m_dbName);
-    }
-
-    return m_sql;
-}
-
-void SQLiteStore::createTables()
-{
-    QSqlQuery query = sql().exec("CREATE TABLE transfer_history_item(dest VARCHAR NOT NULL, "
-                                "source VARCHAR NOT NULL, size int NOT NULL, time int not null, "
-                                "state int, PRIMARY KEY(dest, source));");
-
-    if (query.lastError().isValid()) {
-        kDebug(5001) << query.lastError().text();
+        case TransferHistoryStore::Json:
+        default:
+            return new JsonStore(KStandardDirs::locateLocal("appdata", "transferhistory.json"));
     }
 }
 
 #include "moc_transferhistorystore.cpp"
-#include "moc_transferhistorystore_xml_p.cpp"
-#include "moc_transferhistorystore_sqlite_p.cpp"
index 4d919eb..0e4320d 100644 (file)
@@ -55,8 +55,8 @@ class KGET_EXPORT TransferHistoryStore : public QObject
     Q_OBJECT
 public:
     enum Backend {
-        Xml = 0,
-        SQLite = 1
+        Json = 0,
+        Xml = 1
     };
 
     TransferHistoryStore();
diff --git a/kget/core/transferhistorystore_json.cpp b/kget/core/transferhistorystore_json.cpp
new file mode 100644 (file)
index 0000000..95dd7d8
--- /dev/null
@@ -0,0 +1,130 @@
+/*  This file is part of the KDE project
+
+    Copyright (C) 2021 Ivailo Monev <xakepa10@gmail.com>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License version 2, as published by the Free Software Foundation.
+
+    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 "core/transferhistorystore.h"
+#include "core/transferhistorystore_json_p.h"
+
+#include <QDateTime>
+#include <QFile>
+#include <KDebug>
+
+JsonStore::JsonStore(const QString &database)
+    : TransferHistoryStore(),
+    m_dbName(database)
+{
+}
+
+JsonStore::~JsonStore()
+{
+}
+
+void JsonStore::load()
+{
+    m_items.clear();
+    QFile dbFile(m_dbName);
+    if (dbFile.open(QFile::ReadOnly)) {
+        const QByteArray dbData = dbFile.readAll();
+
+        m_dbDoc = QJsonDocument::fromJson(dbData);
+        if (m_dbDoc.isNull()) {
+            kWarning(5001) << m_dbDoc.errorString();
+        } else {
+            const QVariantMap dbMap = m_dbDoc.toVariant().toMap();
+            const QStringList dbKeys = dbMap.keys();
+
+            int counter = 1;
+            foreach (const QString key, dbKeys) {
+                const QVariantMap keyMap = dbMap.value(key).toMap();
+
+                TransferHistoryItem item;
+                item.setSource(key);
+                item.setDest(keyMap.value("dest").toString());
+                item.setState(keyMap.value("state").toInt());
+                item.setDateTime(QDateTime::fromTime_t(keyMap.value("time").toUInt()));
+                item.setSize(keyMap.value("size").toInt());
+
+                m_items << item;
+                emit elementLoaded(counter, dbKeys.size(), item);
+                counter++;
+            }
+        }
+
+        dbFile.close();
+    } else {
+        // may not exist yet
+        kDebug(5001) << "could not open" << m_dbName;
+    }
+
+    emit loadFinished();
+}
+
+void JsonStore::clear()
+{
+    QFile::remove(m_dbName);
+}
+
+void JsonStore::saveItem(const TransferHistoryItem &item)
+{
+    saveItems(QList<TransferHistoryItem>() << item);
+}
+
+void JsonStore::saveItems(const QList<TransferHistoryItem> &items)
+{
+    QFile dbFile(m_dbName);
+    if (dbFile.open(QFile::WriteOnly)) {
+        QVariantMap dbMap = m_dbDoc.toVariant().toMap();
+
+        foreach (const TransferHistoryItem &item, items) {
+            QVariantMap itemMap;
+            itemMap.insert("dest", item.dest());
+            itemMap.insert("state", QString::number(item.state()));
+            itemMap.insert("time", QString::number(item.dateTime().toTime_t()));
+            itemMap.insert("size", QString::number(item.size()));
+
+            dbMap.insert(item.source(), itemMap);
+            m_dbDoc = QJsonDocument::fromVariant(dbMap);
+
+            m_items << item;
+        }
+
+        const QByteArray dbData = m_dbDoc.toJson();
+        if (dbFile.write(dbData.constData(), dbData.size()) != dbData.size()) {
+            kWarning(5001) << "could not write data to" << m_dbName;;
+        }
+        dbFile.close();
+    } else {
+        kWarning(5001) << "could not open" << m_dbName;
+    }
+
+    emit saveFinished();
+}
+
+void JsonStore::deleteItem(const TransferHistoryItem &item)
+{
+    QVariantMap dbMap = m_dbDoc.toVariant().toMap();
+
+    dbMap.remove(item.source());
+    m_dbDoc = QJsonDocument::fromVariant(dbMap);
+
+    m_items.removeAll(item);
+
+    emit deleteFinished();
+}
+
+#include "moc_transferhistorystore_json_p.cpp"
diff --git a/kget/core/transferhistorystore_json_p.h b/kget/core/transferhistorystore_json_p.h
new file mode 100644 (file)
index 0000000..e71e088
--- /dev/null
@@ -0,0 +1,48 @@
+/*  This file is part of the KDE project
+
+    Copyright (C) 2021 Ivailo Monev <xakepa10@gmail.com>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License version 2, as published by the Free Software Foundation.
+
+    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.
+*/
+
+#ifndef TRANSFERHISTORYSTORE_JSON_P_H
+#define TRANSFERHISTORYSTORE_JSON_P_H
+
+#include "transferhistorystore.h"
+
+#include <QList>
+#include <QJsonDocument>
+
+class TransferHistoryItem;
+class JsonStore : public TransferHistoryStore
+{
+    Q_OBJECT
+public:
+    JsonStore(const QString &database);
+    ~JsonStore();
+
+public slots:
+    void load();
+    void clear();
+    void saveItem(const TransferHistoryItem &item);
+    void saveItems(const QList<TransferHistoryItem> &items);
+    void deleteItem(const TransferHistoryItem &item);
+
+private:
+    QString m_dbName;
+    QJsonDocument m_dbDoc;
+};
+
+#endif
diff --git a/kget/core/transferhistorystore_sqlite_p.h b/kget/core/transferhistorystore_sqlite_p.h
deleted file mode 100644 (file)
index 33a7668..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* This file is part of the KDE project
-
-   Copyright (C) 2007 by Lukas Appelhans <l.appelhans@gmx.de>
-   Copyright (C) 2008 by Javier Goday <jgoday@gmail.com>
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-*/
-#ifndef TRANSFERHISTORYSTORE_SQLITE_P_H
-#define TRANSFERHISTORYSTORE_SQLITE_P_H
-
-#include "transferhistorystore.h"
-
-#include <QList>
-#include <QSqlDatabase>
-
-class TransferHistoryItem;
-class SQLiteStore : public TransferHistoryStore
-{
-    Q_OBJECT
-public:
-    SQLiteStore(const QString &database);
-    ~SQLiteStore();
-
-public slots:
-    void load();
-    void clear();
-    void saveItem(const TransferHistoryItem &item);
-    void saveItems(const QList<TransferHistoryItem> &items);
-    void deleteItem(const TransferHistoryItem &item);
-
-private:
-    QSqlDatabase sql();
-    void createTables();
-
-private:
-    QString m_dbName;
-    QSqlDatabase m_sql;
-};
-#endif
diff --git a/kget/core/transferhistorystore_xml.cpp b/kget/core/transferhistorystore_xml.cpp
new file mode 100644 (file)
index 0000000..7f73deb
--- /dev/null
@@ -0,0 +1,257 @@
+/* This file is part of the KDE project
+
+   Copyright (C) 2007 by Lukas Appelhans <l.appelhans@gmx.de>
+   Copyright (C) 2008 by Javier Goday <jgoday@gmail.com>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public
+   License as published by the Free Software Foundation; either
+   version 2 of the License, or (at your option) any later version.
+*/
+
+#include "core/transferhistorystore.h"
+#include "core/transferhistorystore_xml_p.h"
+
+#include <QDateTime>
+#include <QtXml/qdom.h>
+#include <QFile>
+#include <QThread>
+#include <KDebug>
+#include <KLocale>
+
+XmlStore::SaveThread::SaveThread(QObject *parent, const QString &url, const QList<TransferHistoryItem> &list) : QThread(parent),
+    m_url(url),
+    m_items(list),
+    m_item()
+{
+}
+
+XmlStore::SaveThread::SaveThread(QObject *parent, const QString &url, const TransferHistoryItem &item) : QThread(parent),
+    m_url(url),
+    m_items(),
+    m_item(item)
+{
+}
+
+void XmlStore::SaveThread::run()
+{
+    QFile file(m_url);
+    QDomDocument *doc;
+    QDomElement root;
+
+    if (!file.exists())
+    {
+        doc = new QDomDocument("Transfers");
+        root = doc->createElement("Transfers");
+        doc->appendChild(root);
+    }
+    else
+    {
+        doc = new QDomDocument();
+        doc->setContent(&file);
+        file.close();
+        root = doc->documentElement();
+        doc->appendChild(root);
+    }
+
+    QDomElement e = doc->createElement("Transfer");
+    root.appendChild(e);
+
+    e.setAttribute("Source", m_item.source());
+    e.setAttribute("Dest", m_item.dest());
+    e.setAttribute("Time", QDateTime::currentDateTime().toTime_t());
+    e.setAttribute("Size", QString::number(m_item.size()));
+    e.setAttribute("State", QString::number(m_item.state()));
+
+    if (file.open(QFile::WriteOnly | QFile::Truncate)) {
+        QTextStream stream( &file );
+        doc->save( stream, 0 );
+        file.close();
+    }
+    delete doc;
+}
+
+XmlStore::DeleteThread::DeleteThread(QObject *parent, const QString &url, const TransferHistoryItem &item) : QThread(parent),
+    m_url(url),
+    m_item(item),
+    m_items()
+{
+}
+
+void XmlStore::DeleteThread::run()
+{
+    QDomDocument doc("tempHistory");
+    QFile file(m_url);
+
+    QString error;
+    int line;
+    int column;
+
+    if (!doc.setContent(&file, &error, &line, &column)) 
+    {
+        kDebug(5001) << "Error1" << error << line << column;
+        return;
+    }
+    file.close();
+
+    QDomElement root = doc.documentElement();
+
+    QDomNodeList list = root.elementsByTagName("Transfer");
+
+    int nItems = list.length();
+
+    for (int i = 0 ; i < nItems ; i++) {
+        QDomElement element = list.item(i).toElement();
+
+        if(QString::compare(element.attribute("Source"), m_item.source()) == 0) {
+            root.removeChild(element);
+        }
+        else {
+            TransferHistoryItem item;
+            item.setDest(element.attribute("Dest"));
+            item.setSource(element.attribute("Source"));
+            item.setSize(element.attribute("Size").toInt());
+            item.setDateTime(QDateTime::fromTime_t(element.attribute("Time").toUInt()));
+            item.setState(element.attribute("State").toInt());
+            m_items << item;
+        }
+    }
+
+    if (file.open(QFile::WriteOnly | QFile::Truncate)) {
+        QTextStream stream( &file );
+        doc.save(stream, 0);
+        file.close();
+        doc.clear();
+    }
+}
+
+XmlStore::LoadThread::LoadThread(QObject *parent, const QString &url) : QThread(parent),
+    m_url(url)
+{
+}
+
+void XmlStore::LoadThread::run()
+{
+    qRegisterMetaType<TransferHistoryItem>("TransferHistoryItem");
+    QDomDocument doc("tempHistory");
+    QFile file(m_url);
+
+    QString error;
+    int line;
+    int column;
+    int total;
+
+    if (!doc.setContent(&file, &error, &line, &column)) 
+    {
+        kDebug(5001) << "Error1" << error << line << column;
+        file.close();
+        return;
+    }
+
+    QDomElement root = doc.documentElement();
+    total = root.childNodes().size();
+
+    QDomNodeList list = root.elementsByTagName("Transfer");
+
+    int nItems = list.length();
+
+    for (int i = 0 ; i < nItems ; i++)
+    {
+        QDomElement dom = list.item(i).toElement();
+        
+        TransferHistoryItem item;
+        item.setDest(dom.attribute("Dest"));
+        item.setSource(dom.attribute("Source"));
+        item.setSize(dom.attribute("Size").toInt());
+        item.setDateTime(QDateTime::fromTime_t(dom.attribute("Time").toUInt()));
+        item.setState(dom.attribute("State").toInt());
+
+        emit elementLoaded(i, total, item);
+    }
+    doc.clear();
+    file.close();
+}
+
+XmlStore::XmlStore(const QString &url) : TransferHistoryStore(),
+    m_storeUrl(url),
+    m_loadThread(0),
+    m_saveThread(0),
+    m_deleteThread(0)
+{
+}
+
+XmlStore::~XmlStore()
+{
+    if(m_loadThread && m_loadThread->isRunning()) {
+        m_loadThread->terminate();
+    }
+
+    if(m_saveThread && m_saveThread->isRunning()) {
+        m_saveThread->terminate();
+    }
+
+    if(m_deleteThread && m_deleteThread->isRunning()) {
+        m_deleteThread->terminate();
+    }
+
+    delete m_loadThread;
+    delete m_saveThread;
+    delete m_deleteThread;
+}
+
+void XmlStore::load()
+{
+    m_items.clear();
+    // TODO: only load if necessary
+    m_loadThread = new XmlStore::LoadThread(this, m_storeUrl);
+
+    connect(m_loadThread, SIGNAL(finished()), SIGNAL(loadFinished()));
+    connect(m_loadThread, SIGNAL(elementLoaded(int,int,TransferHistoryItem)),
+                        SIGNAL(elementLoaded(int,int,TransferHistoryItem)));
+    connect(m_loadThread, SIGNAL(elementLoaded(int,int,TransferHistoryItem)),
+                        SLOT(slotLoadElement(int,int,TransferHistoryItem)));
+    m_loadThread->start();
+}
+
+void XmlStore::clear()
+{
+    QFile::remove(m_storeUrl);
+}
+
+void XmlStore::saveItem(const TransferHistoryItem &item)
+{
+    m_saveThread = new XmlStore::SaveThread(this, m_storeUrl, item);
+
+    connect(m_saveThread, SIGNAL(finished()), SIGNAL(saveFinished()));
+    connect(m_saveThread, SIGNAL(elementLoaded(int,int,TransferHistoryItem)),
+                        SIGNAL(elementLoaded(int,int,TransferHistoryItem)));
+    m_saveThread->start();
+}
+
+void XmlStore::deleteItem(const TransferHistoryItem &item)
+{
+    Q_UNUSED(item)
+
+    m_deleteThread = new XmlStore::DeleteThread(this, m_storeUrl, item);
+
+    connect(m_deleteThread, SIGNAL(finished()), SLOT(slotDeleteElement()));
+
+    m_deleteThread->start();
+}
+
+void XmlStore::slotLoadElement(int number, int total, const TransferHistoryItem &item)
+{
+    Q_UNUSED(number)
+    Q_UNUSED(total)
+    m_items.append(item);
+}
+
+void XmlStore::slotDeleteElement()
+{
+    m_items.clear();
+    m_items << m_deleteThread->items();
+
+    emit loadFinished();
+}
+
+#include "moc_transferhistorystore_xml_p.cpp"
index 62441fc..51ff68e 100644 (file)
@@ -1,4 +1,5 @@
-/*  This file is part of the KDE libraries
+/*  This file is part of the KDE project
+
     Copyright (C) 2021 Ivailo Monev <xakepa10@gmail.com>
 
     This library is free software; you can redistribute it and/or
index e4e2a66..11e5bb9 100644 (file)
@@ -1,4 +1,5 @@
-/*  This file is part of the KDE libraries
+/*  This file is part of the KDE project
+
     Copyright (C) 2021 Ivailo Monev <xakepa10@gmail.com>
 
     This library is free software; you can redistribute it and/or
index dba34bf..09e7f86 100644 (file)
@@ -1,4 +1,5 @@
-/*  This file is part of the KDE libraries
+/*  This file is part of the KDE project
+
     Copyright (C) 2021 Ivailo Monev <xakepa10@gmail.com>
 
     This library is free software; you can redistribute it and/or
index d0e6427..855c3b3 100644 (file)
@@ -1,4 +1,5 @@
-/*  This file is part of the KDE libraries
+/*  This file is part of the KDE project
+
     Copyright (C) 2021 Ivailo Monev <xakepa10@gmail.com>
 
     This library is free software; you can redistribute it and/or