1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00

Syncing items

This commit is contained in:
Laurent Cozic 2017-01-05 23:54:13 +01:00
parent 96cd7d67b0
commit 9786786e7f
13 changed files with 148 additions and 21 deletions

View File

@ -19,7 +19,8 @@ SOURCES += \
uuid.cpp \ uuid.cpp \
dispatcher.cpp \ dispatcher.cpp \
models/change.cpp \ models/change.cpp \
models/basemodel.cpp models/basemodel.cpp \
models/setting.cpp
RESOURCES += qml.qrc \ RESOURCES += qml.qrc \
database.qrc database.qrc
@ -52,7 +53,8 @@ HEADERS += \
dispatcher.h \ dispatcher.h \
models/change.h \ models/change.h \
models/basemodel.h \ models/basemodel.h \
enum.h enum.h \
models/setting.h
DISTFILES += DISTFILES +=

View File

@ -29,6 +29,8 @@ Application::Application(int &argc, char **argv) :
QCoreApplication::setOrganizationDomain("cozic.net"); QCoreApplication::setOrganizationDomain("cozic.net");
QCoreApplication::setApplicationName("Joplin"); QCoreApplication::setApplicationName("Joplin");
Settings::initialize();
Settings settings; Settings settings;
view_.setResizeMode(QQuickView::SizeRootObjectToView); view_.setResizeMode(QQuickView::SizeRootObjectToView);

View File

@ -139,6 +139,11 @@ bool Database::execQuery(QSqlQuery &query) {
return query.exec(); return query.exec();
} }
bool Database::execQuery(const QString &sql) {
QSqlQuery query(sql, db_);
return execQuery(query);
}
QSqlQuery Database::prepare(const QString &sql) { QSqlQuery Database::prepare(const QString &sql) {
QSqlQuery query(db_); QSqlQuery query(db_);
query.prepare(sql); query.prepare(sql);

View File

@ -22,6 +22,7 @@ public:
bool transaction(); bool transaction();
bool commit(); bool commit();
bool execQuery(QSqlQuery &query); bool execQuery(QSqlQuery &query);
bool execQuery(const QString &query);
QSqlQuery prepare(const QString& sql); QSqlQuery prepare(const QString& sql);
private: private:

View File

@ -48,7 +48,7 @@ bool BaseModel::load(const QString &id) {
loadSqlQuery(q); loadSqlQuery(q);
} }
bool BaseModel::save() { bool BaseModel::save(bool trackChanges) {
bool isNew = this->isNew(); bool isNew = this->isNew();
if (!changedFields_.size() && !isNew) return true; if (!changedFields_.size() && !isNew) return true;
@ -106,7 +106,7 @@ bool BaseModel::save() {
isSaved = jop::db().errorCheck(q); isSaved = jop::db().errorCheck(q);
} }
if (isSaved && trackChanges()) { if (isSaved && this->trackChanges() && trackChanges) {
if (isNew) { if (isNew) {
Change change; Change change;
change.setValue("item_id", id()); change.setValue("item_id", id());

View File

@ -43,7 +43,7 @@ public:
QStringList changedFields() const; QStringList changedFields() const;
static int count(jop::Table table); static int count(jop::Table table);
bool load(const QString& id); bool load(const QString& id);
virtual bool save(); virtual bool save(bool trackChanges = true);
virtual bool dispose(); virtual bool dispose();
virtual Table table() const; virtual Table table() const;

View File

@ -0,0 +1,30 @@
#include "setting.h"
#include "database.h"
using namespace jop;
void Setting::setSettings(const QSettings::SettingsMap &map) {
jop::db().transaction();
QString sql = "INSERT OR REPLACE INTO settings (`key`, `value`, `type`) VALUES (:key, :value, :type)";
QSqlQuery query = jop::db().prepare(sql);
for (QSettings::SettingsMap::const_iterator it = map.begin(); it != map.end(); ++it) {
query.bindValue(":key", it.key());
query.bindValue(":value", it.value());
query.bindValue(":type", (int)it.value().type());
jop::db().execQuery(query);
}
jop::db().commit();
}
QSettings::SettingsMap Setting::settings() {
QSettings::SettingsMap output;
QSqlQuery query("SELECT key, value, type FROM settings");
jop::db().execQuery(query);
while (query.next()) {
QString key = query.value(0).toString();
QMetaType::Type type = (QMetaType::Type)query.value(2).toInt();
qDebug() << key << type;
}
return output;
}

View File

@ -0,0 +1,21 @@
#ifndef SETTING_H
#define SETTING_H
#include <stable.h>
#include "models/basemodel.h"
namespace jop {
class Setting : public BaseModel {
public:
static void setSettings(const QSettings::SettingsMap &map);
static QSettings::SettingsMap settings();
};
}
#endif // SETTING_H

View File

@ -66,6 +66,12 @@ CREATE TABLE changes (
item_field TEXT item_field TEXT
); );
CREATE TABLE settings (
`key` TEXT PRIMARY KEY,
`value` TEXT,
`type` INT
);
--CREATE TABLE mimetypes ( --CREATE TABLE mimetypes (
-- id INT, -- id INT,
-- mime TEXT -- mime TEXT

View File

@ -1,3 +1,34 @@
#include "settings.h" #include "settings.h"
#include "models/setting.h"
using namespace jop; using namespace jop;
Settings::Settings() : QSettings() {
}
bool readSqlite(QIODevice &device, QSettings::SettingsMap &map) {
//qDebug() << "XXXXXXXXXXXX";
// map = Setting::settings();
qDebug() << "Calling readSqlite";
return true;
}
bool writeSqlite(QIODevice &device, const QSettings::SettingsMap &map) {
//Setting::setSettings(map);
qDebug() << "Calling writeSqlite";
return true;
}
void Settings::initialize() {
// const QSettings::Format SqliteFormat = QSettings::registerFormat("sqlite", &readSqlite, &writeSqlite);
// QSettings::setDefaultFormat(SqliteFormat);
// QSettings settings;
// //qDebug() << settings.value("test");
// settings.setValue("test", 123456);
// QSettings s(SqliteFormat, QSettings::UserScope, "MySoft",
// "Star Runner");
// qDebug() << "IN" << s.value("test") << "test";
}

View File

@ -2,6 +2,7 @@
#define SETTINGS_H #define SETTINGS_H
#include <stable.h> #include <stable.h>
#include "database.h"
namespace jop { namespace jop {
@ -9,6 +10,12 @@ class Settings : public QSettings {
Q_OBJECT Q_OBJECT
public:
Settings();
static void initialize();
}; };
} }

View File

@ -1,6 +1,7 @@
#include "synchronizer.h" #include "synchronizer.h"
#include "models/folder.h" #include "models/folder.h"
#include "models/note.h" #include "models/note.h"
#include "settings.h"
using namespace jop; using namespace jop;
@ -80,40 +81,44 @@ QUrlQuery Synchronizer::valuesToUrlQuery(const QHash<QString, Change::Value>& va
} }
void Synchronizer::downloadChanges() { void Synchronizer::downloadChanges() {
Settings settings;
QString lastRevId = settings.value("lastRevId", "0").toString();
state_ = DownloadingChanges; state_ = DownloadingChanges;
//QUrlQuery data = valuesToUrlQuery(folder.values()); QUrlQuery query;
api_.get("synchronizer", QUrlQuery(), QUrlQuery(), "download:getSynchronizer"); query.addQueryItem("last_id", lastRevId);
api_.get("synchronizer", query, QUrlQuery(), "download:getSynchronizer");
} }
void Synchronizer::api_requestDone(const QJsonObject& response, const QString& tag) { void Synchronizer::api_requestDone(const QJsonObject& response, const QString& tag) {
QStringList parts = tag.split(':'); QStringList parts = tag.split(':');
QString category = parts[0]; QString category = parts[0];
QString action = parts[1]; QString action = parts[1];
QString id = ""; QString arg1 = "";
QString arg2 = "";
if (parts.size() == 3) { if (parts.size() == 3) arg1 = parts[2];
id = parts[2]; if (parts.size() == 4) arg2 = parts[3];
}
qDebug() << "WebApi: done" << category << action << id; qDebug() << "WebApi: done" << category << action << arg1 << arg2;
// TODO: check for error // TODO: check for error
if (category == "upload") { if (category == "upload") {
uploadsRemaining_--; uploadsRemaining_--;
qDebug() << "Synced folder" << id; qDebug() << "Synced folder" << arg1;
if (action == "putFolder") { if (action == "putFolder") {
Change::disposeByItemId(id); Change::disposeByItemId(arg1);
} }
if (action == "patchFolder") { if (action == "patchFolder") {
Change::disposeByItemId(id); Change::disposeByItemId(arg1);
} }
if (action == "deleteFolder") { if (action == "deleteFolder") {
Change::disposeByItemId(id); Change::disposeByItemId(arg1);
} }
if (uploadsRemaining_ < 0) { if (uploadsRemaining_ < 0) {
@ -132,11 +137,12 @@ void Synchronizer::api_requestDone(const QJsonObject& response, const QString& t
QString itemId = obj["item_id"].toString(); QString itemId = obj["item_id"].toString();
QString itemType = obj["item_type"].toString(); QString itemType = obj["item_type"].toString();
QString operationType = obj["type"].toString(); QString operationType = obj["type"].toString();
QString revId = QString::number(obj["id"].toInt());
QString path = itemType + "s"; // That should remain true QString path = itemType + "s";
if (operationType == "create") { if (operationType == "create") {
api_.get(path + "/" + itemId, QUrlQuery(), QUrlQuery(), "download:getFolder:" + itemId); api_.get(path + "/" + itemId, QUrlQuery(), QUrlQuery(), "download:getFolder:" + itemId + ":" + revId);
} }
downloadsRemaining_++; downloadsRemaining_++;
@ -144,12 +150,14 @@ void Synchronizer::api_requestDone(const QJsonObject& response, const QString& t
} else { } else {
downloadsRemaining_--; downloadsRemaining_--;
Settings settings;
if (action == "getFolder") { if (action == "getFolder") {
Folder folder; Folder folder;
folder.loadJsonObject(response); folder.loadJsonObject(response);
folder.save(); folder.save(false);
// TODO: save last rev ID settings.setValue("lastRevId", arg2);
} }
if (downloadsRemaining_ < 0) { if (downloadsRemaining_ < 0) {

View File

@ -57,15 +57,29 @@ class Change extends BaseModel {
$change->type = Change::enumId('type', 'create'); $change->type = Change::enumId('type', 'create');
} }
$output[] = $change; $output[] = $change->toSyncItem();
} }
usort($output, function($a, $b) {
return strnatcmp($a['id'], $b['id']);
});
return array( return array(
'has_more' => $hasMore, 'has_more' => $hasMore,
'items' => $output, 'items' => $output,
); );
} }
public function toSyncItem() {
return array(
'id' => (string)$this->id,
'type' => self::enumName('type', $this->type),
'item_id' => self::hex($this->item_id),
'item_type' => FolderItem::enumName('type', $this->item_type),
'item_field' => BaseModel::enumName('field', $this->item_field),
);
}
static public function itemFieldHistory($itemId, $itemField, $toId = null) { static public function itemFieldHistory($itemId, $itemField, $toId = null) {
$query = self::where('item_id', '=', $itemId); $query = self::where('item_id', '=', $itemId);
$query->where('item_field', '=', $itemField); $query->where('item_field', '=', $itemField);