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

Added BaseModel to allow tracking changes

This commit is contained in:
Laurent Cozic 2017-01-02 13:17:15 +01:00
parent bc6f419d1e
commit 0a08837ef0
23 changed files with 670 additions and 252 deletions

View File

@ -46,7 +46,7 @@ Item {
}
onCurrentItemChanged: {
currentItemId = model.idAtIndex(currentIndex);
currentItemId = model.indexToId(currentIndex);
}
id: listView

View File

@ -18,7 +18,8 @@ SOURCES += \
settings.cpp \
uuid.cpp \
dispatcher.cpp \
models/change.cpp
models/change.cpp \
models/basemodel.cpp
RESOURCES += qml.qrc \
database.qrc
@ -49,7 +50,9 @@ HEADERS += \
simpletypes.h \
uuid.h \
dispatcher.h \
models/change.h
models/change.h \
models/basemodel.h \
enum.h
DISTFILES +=

View File

@ -105,15 +105,15 @@ void Application::afterSessionInitialization() {
}
void Application::view_currentFolderChanged() {
QString folderId = selectedFolderId();
noteCollection_ = NoteCollection(db_, folderId, "title ASC");
noteModel_.setCollection(noteCollection_);
// QString folderId = selectedFolderId();
// noteCollection_ = NoteCollection(db_, folderId, "title ASC");
// noteModel_.setCollection(noteCollection_);
}
void Application::view_currentNoteChanged() {
QString noteId = selectedNoteId();
Note note = noteCollection_.byId(noteId);
selectedQmlNote_.setNote(note);
// QString noteId = selectedNoteId();
// Note note = noteCollection_.byId(noteId);
// selectedQmlNote_.setNote(note);
}
void Application::view_addNoteButtonClicked() {

View File

@ -2,23 +2,6 @@
using namespace jop;
Database::Database(const QString &path) {
// version_ = -1;
// // QFile::remove(path);
// db_ = QSqlDatabase::addDatabase("QSQLITE");
// db_.setDatabaseName(path);
// if (!db_.open()) {
// qDebug() << "Error: connection with database fail";
// } else {
// qDebug() << "Database: connection ok";
// }
// upgrade();
}
Database::Database() {}
void Database::initialize(const QString &path) {
@ -26,6 +9,8 @@ void Database::initialize(const QString &path) {
// QFile::remove(path);
//qDebug() << Select << Text;
db_ = QSqlDatabase::addDatabase("QSQLITE");
db_.setDatabaseName(path);
@ -41,6 +26,7 @@ void Database::initialize(const QString &path) {
QSqlQuery Database::query(const QString &sql) const {
QSqlQuery output(db_);
output.prepare(sql);
log(sql);
return output;
}
@ -101,6 +87,8 @@ QSqlQuery Database::buildSqlQuery(Database::QueryType type, const QString &table
}
}
log(sql, query);
// qDebug() <<"SQL:"<<sql;
// QMapIterator<QString, QVariant> i(query.boundValues());
@ -112,6 +100,16 @@ QSqlQuery Database::buildSqlQuery(Database::QueryType type, const QString &table
return query;
}
QSqlQuery Database::buildSqlQuery(Database::QueryType type, const QString &tableName, const QMap<QString, QVariant> &values, const QString &whereCondition) {
QStringList fields;
VariantVector fieldValues;
for (QMap<QString, QVariant>::const_iterator it = values.begin(); it != values.end(); ++it) {
fields.push_back(it.key());
fieldValues.push_back(it.value());
}
return buildSqlQuery(type, tableName, fields, fieldValues, whereCondition);
}
bool Database::errorCheck(const QSqlQuery& query) {
if (query.lastError().isValid()) {
qCritical().noquote() << "SQL query error: " << query.lastError().text().trimmed() << ". Query was: " << query.lastQuery();
@ -125,10 +123,15 @@ bool Database::errorCheck(const QSqlQuery& query) {
return true;
}
//Change Database::newChange() const {
// return Change(*this);
//}
void Database::log(const QString &sql, const QSqlQuery &query) const {
qDebug() <<"SQL:"<<sql;
QMapIterator<QString, QVariant> i(query.boundValues());
while (i.hasNext()) {
i.next();
qDebug() << i.key() << ":" << i.value().toString();
}
}
int Database::version() const {
if (version_ >= 0) return version_;

View File

@ -2,6 +2,7 @@
#define DATABASE_H
#include <stable.h>
#include "enum.h"
#include "simpletypes.h"
namespace jop {
@ -12,18 +13,18 @@ public:
enum QueryType { Select, Insert, Update, Delete };
Database(const QString& path);
Database();
void initialize(const QString& path);
QSqlQuery query(const QString& sql) const;
QSqlDatabase& database();
QSqlQuery buildSqlQuery(Database::QueryType type, const QString& tableName, const QStringList& fields, const VariantVector& values, const QString& whereCondition = "");
QSqlQuery buildSqlQuery(Database::QueryType type, const QString& tableName, const QMap<QString, QVariant>& values, const QString& whereCondition = "");
bool errorCheck(const QSqlQuery& query);
//Change newChange() const;
private:
void log(const QString& sql, const QSqlQuery& query = QSqlQuery()) const;
QSqlDatabase db_;
void upgrade();
int version() const;

View File

@ -0,0 +1,6 @@
#include "enum.h"
enum::enum()
{
}

14
QtClient/JoplinQtClient/enum.h Executable file
View File

@ -0,0 +1,14 @@
#ifndef ENUM_H
#define ENUM_H
#include <stable.h>
namespace jop {
enum ColType { UndefinedType, TextColType, IntColType };
enum Table { UndefinedTable, FoldersTable, NotesTable };
}
#endif // ENUM_H

View File

@ -0,0 +1,283 @@
#include "basemodel.h"
#include "database.h"
#include "uuid.h"
using namespace jop;
QMap<int, QVector<BaseModel::Field>> BaseModel::tableFields_;
QHash<QString, QVariant> BaseModel::cache_;
BaseModel::BaseModel() {
}
QStringList BaseModel::changedFields() const {
QStringList output;
for (QHash<QString, bool>::const_iterator it = changedFields_.begin(); it != changedFields_.end(); ++it) {
output.push_back(it.key());
}
return output;
}
int BaseModel::count(Table table) {
QString t = BaseModel::tableName(table);
QString k = QString("%1:count").arg(t);
QVariant r = BaseModel::cacheGet(k);
if (r.isValid()) return r.toInt();
QSqlQuery q = jop::db().query("SELECT count(*) as row_count FROM " + t);
q.exec();
q.next();
int output = q.value(0).toInt();
BaseModel::cacheSet(k, QVariant(output));
return output;
}
bool BaseModel::save() {
bool isNew = this->isNew();
if (!changedFields_.size() && !isNew) return true;
QStringList fields = changedFields();
QMap<QString, QVariant> values;
foreach (QString field, fields) {
values[field] = value(field).toQVariant();
}
if (isNew && primaryKeyIsUuid()) {
values[primaryKey()] = uuid::createUuid();
}
changedFields_.clear();
const QString& tableName = BaseModel::tableName(table());
if (isNew) {
cacheDelete(QString("%1:count").arg(tableName));
}
if (isNew) {
QSqlQuery q = jop::db().buildSqlQuery(Database::Insert, tableName, values);
q.exec();
return jop::db().errorCheck(q);
} else {
QSqlQuery q = jop::db().buildSqlQuery(Database::Update, tableName, values, QString("%1 = '%2'").arg(primaryKey()).arg(value("id").toString()));
q.exec();
return jop::db().errorCheck(q);
}
return false; // Unreachable
}
bool BaseModel::dispose() {
const QString& tableName = BaseModel::tableName(table());
QSqlQuery q(jop::db().database());
q.prepare("DELETE FROM " + tableName + " WHERE " + primaryKey() + " = :id");
q.bindValue(":id", id().toString());
q.exec();
cacheDelete(QString("%1:count").arg(tableName));
return jop::db().errorCheck(q);
}
Table BaseModel::table() const {
qCritical() << "BaseModel::table() must be overriden";
return jop::UndefinedTable;
}
QString BaseModel::primaryKey() const {
return "id";
}
bool BaseModel::primaryKeyIsUuid() const {
return false;
}
bool BaseModel::isNew() const {
return !valueIsSet(primaryKey());
}
BaseModel::Field createField(const QString& name, QMetaType::Type type) {
BaseModel::Field c;
c.name = name;
c.type = type;
return c;
}
QVector<BaseModel::Field> BaseModel::tableFields(jop::Table table) {
if (BaseModel::tableFields_.contains(table)) return BaseModel::tableFields_[table];
QVector<BaseModel::Field> output;
if (table == jop::FoldersTable) {
output.push_back(createField("id", QMetaType::QString ));
output.push_back(createField("title", QMetaType::QString ));
output.push_back(createField("created_time", QMetaType::Int ));
output.push_back(createField("updated_time", QMetaType::Int ));
}
BaseModel::tableFields_[table] = output;
return output;
}
QStringList BaseModel::tableFieldNames(Table table) {
QVector<BaseModel::Field> fields = BaseModel::tableFields(table);
QStringList output;
foreach (BaseModel::Field field, fields) {
output.push_back(field.name);
}
return output;
}
bool BaseModel::isValidFieldName(Table table, const QString &name) {
QVector<BaseModel::Field> fields = BaseModel::tableFields(table);
foreach (BaseModel::Field col, fields) {
if (col.name == name) return true;
}
return false;
}
void BaseModel::loadSqlQuery(const QSqlQuery &query) {
values_.clear();
QSqlRecord record = query.record();
QVector<BaseModel::Field> fields = BaseModel::tableFields(table());
foreach (BaseModel::Field field, fields) {
int idx = record.indexOf(field.name);
if (idx < 0) {
qCritical() << "Cannot find field" << field.name;
continue;
}
if (field.type == QMetaType::QString) {
values_.insert(field.name, Value(query.value(idx).toString()));
} else if (field.type == QMetaType::Int) {
values_.insert(field.name, Value(query.value(idx).toInt()));
} else {
qCritical() << "Unsupported value type" << field.name;
}
}
changedFields_.clear();
}
QHash<QString, BaseModel::Value> BaseModel::values() const {
return values_;
}
BaseModel::Value BaseModel::value(const QString &name) const {
if (!valueIsSet(name)) {
qCritical() << "Value does not exist" << name;
return Value();
}
return values_[name];
}
bool BaseModel::valueIsSet(const QString &name) const {
return values_.contains(name);
}
void BaseModel::setValue(const QString &name, const BaseModel::Value &value) {
if (!values_.contains(name)) {
values_.insert(name, value);
changedFields_.insert(name, true);
} else {
Value& v = values_[name];
if (v.isEqual(value)) return;
values_.insert(name, value);
changedFields_.insert(name, true);
}
}
void BaseModel::setValue(const QString &name, int value) {
setValue(name, Value(value));
}
BaseModel::Value BaseModel::id() const {
if (!valueIsSet(primaryKey())) return QVariant();
return value(primaryKey());
}
QString BaseModel::tableName(Table t) {
if (t == jop::FoldersTable) return "folders";
if (t == jop::NotesTable) return "notes";
return "UNDEFINED";
}
QVariant BaseModel::cacheGet(const QString &key) {
if (!BaseModel::cache_.contains(key)) return QVariant();
return cache_[key];
}
void BaseModel::cacheSet(const QString &key, const QVariant &value) {
BaseModel::cache_[key] = value;
}
void BaseModel::cacheDelete(const QString &key) {
BaseModel::cache_.remove(key);
}
void BaseModel::setValue(const QString &name, const QString &value) {
setValue(name, Value(value));
}
void BaseModel::setValue(const QString& name, const QVariant& value) {
setValue(name, Value(value));
}
BaseModel::Value::Value() {}
BaseModel::Value::Value(const QString &v) {
type_ = QMetaType::QString;
stringValue_ = v;
}
BaseModel::Value::Value(int v) {
type_ = QMetaType::Int;
intValue_ = v;
}
BaseModel::Value::Value(const QVariant &v) {
type_ = (QMetaType::Type)v.type();
if (type_ == QMetaType::QString) {
stringValue_ = v.toString();
} else if (type_ == QMetaType::Int) {
intValue_ = v.toInt();
} else {
// Creates an invalid Value
}
}
int BaseModel::Value::toInt() const {
return intValue_;
}
QString BaseModel::Value::toString() const {
return stringValue_;
}
QVariant BaseModel::Value::toQVariant() const {
QMetaType::Type t = type();
if (t == QMetaType::QString) return QVariant(toString());
if (t == QMetaType::Int) return QVariant(toInt());
return QVariant();
}
QMetaType::Type BaseModel::Value::type() const {
return type_;
}
bool BaseModel::Value::isValid() const {
return type_ > 0;
}
bool BaseModel::Value::isEqual(const BaseModel::Value &v) const {
QMetaType::Type type = v.type();
if (this->type() != type) return false;
if (type == QMetaType::QString) return toString() == v.toString();
if (type == QMetaType::Int) return toInt() == v.toInt();
qCritical() << "Unreachable";
return false;
}

View File

@ -0,0 +1,88 @@
#ifndef BASEMODEL_H
#define BASEMODEL_H
#include <stable.h>
#include "database.h"
#include "enum.h"
namespace jop {
class BaseModel {
public:
struct Field {
QString name;
QMetaType::Type type;
};
class Value {
public:
Value();
Value(const QString& v);
Value(int v);
Value(const QVariant& v);
int toInt() const;
QString toString() const;
QVariant toQVariant() const;
QMetaType::Type type() const;
bool isValid() const;
bool isEqual(const Value& v) const;
private:
QMetaType::Type type_;
QString stringValue_;
int intValue_;
};
BaseModel();
QStringList changedFields() const;
static int count(jop::Table table);
bool save();
bool dispose();
virtual Table table() const;
virtual QString primaryKey() const;
virtual bool primaryKeyIsUuid() const;
bool isNew() const;
static QVector<BaseModel::Field> tableFields(Table table);
static QStringList tableFieldNames(Table table);
static bool isValidFieldName(Table table, const QString& name);
void loadSqlQuery(const QSqlQuery& query);
QHash<QString, Value> values() const;
Value value(const QString& name) const;
bool valueIsSet(const QString& name) const;
void setValue(const QString& name, const Value& value);
void setValue(const QString& name, const QVariant& value);
void setValue(const QString& name, const QString& value);
void setValue(const QString& name, int value);
Value id() const;
static QString tableName(Table t);
protected:
QHash<QString, bool> changedFields_;
Table table_;
QHash<QString, Value> values_;
static QVariant cacheGet(const QString& key);
static void cacheSet(const QString& key, const QVariant& value);
static void cacheDelete(const QString& key);
static QMap<int, QVector<BaseModel::Field>> tableFields_;
static QHash<QString, QVariant> cache_;
};
}
#endif // BASEMODEL_H

View File

@ -5,64 +5,79 @@
using namespace jop;
Folder::Folder() {
Folder::Folder() : Item() {
}
bool Folder::isNew() const {
return id().isEmpty();
}
//bool Folder::isNew() const {
// return id().isEmpty();
//}
bool Folder::save() {
bool isNew = this->isNew();
//bool Folder::save() {
// bool isNew = this->isNew();
QStringList fields;
VariantVector values;
if (isNew) {
setId(uuid::createUuid());
fields << "id";
values << id();
}
fields << "title" << "synced";
values << title() << QVariant(0);
// QStringList fields;
// VariantVector values;
// if (isNew) {
// setId(uuid::createUuid());
// fields << "id";
// values << id();
// }
// fields << "title" << "synced";
// values << title() << QVariant(0);
if (isNew) {
QSqlQuery q = jop::db().buildSqlQuery(Database::Insert, "folders", fields, values);
q.exec();
return jop::db().errorCheck(q);
} else {
QSqlQuery q = jop::db().buildSqlQuery(Database::Update, "folders", fields, values, "id = \"" + id() + "\"");
q.exec();
return jop::db().errorCheck(q);
}
}
// if (isNew) {
// QSqlQuery q = jop::db().buildSqlQuery(Database::Insert, "folders", fields, values);
// q.exec();
// return jop::db().errorCheck(q);
// } else {
// QSqlQuery q = jop::db().buildSqlQuery(Database::Update, "folders", fields, values, "id = \"" + id() + "\"");
// q.exec();
// return jop::db().errorCheck(q);
// }
//}
bool Folder::dispose() {
QSqlQuery q(jop::db().database());
q.prepare("DELETE FROM folders WHERE id = :id");
q.bindValue(":id", id());
q.exec();
return jop::db().errorCheck(q);
}
//bool Folder::dispose() {
// return false;
//// QSqlQuery q(jop::db().database());
//// q.prepare("DELETE FROM folders WHERE id = :id");
//// q.bindValue(":id", id());
//// q.exec();
//// return jop::db().errorCheck(q);
//}
int Folder::count() {
QSqlQuery q = jop::db().query("SELECT count(*) as row_count FROM folders");
q.exec();
q.next();
return q.value(0).toInt();
return BaseModel::count(jop::FoldersTable);
}
QVector<Folder> Folder::all(const QString &orderBy) {
QSqlQuery q = jop::db().query("SELECT " + Folder::dbFields().join(",") + " FROM folders ORDER BY " + orderBy);
//QSqlQuery q = jop::db().query("SELECT " + Folder::dbFields().join(",") + " FROM folders ORDER BY " + orderBy);
QSqlQuery q = jop::db().query("SELECT " + BaseModel::tableFieldNames(jop::FoldersTable).join(",") + " FROM folders ORDER BY " + orderBy);
q.exec();
QVector<Folder> output;
while (q.next()) {
Folder folder;
folder.fromSqlQuery(q);
folder.loadSqlQuery(q);
output.push_back(folder);
// Folder folder;
// folder.fromSqlQuery(q);
// output.push_back(folder);
// Folder f2;
// f2.loadSqlQuery(q);
// qDebug() << "xxx" << f2.value("title").toString();
}
return output;
}
Table Folder::table() const {
return jop::FoldersTable;
}
bool Folder::primaryKeyIsUuid() const {
return true;
}

View File

@ -11,13 +11,13 @@ class Folder : public Item {
public:
Folder();
bool isNew() const;
bool save();
bool dispose();
static int count();
static QVector<Folder> all(const QString& orderBy);
Table table() const;
bool primaryKeyIsUuid() const;
private:
};

View File

@ -7,7 +7,7 @@ FolderModel::FolderModel(Database &database) : QAbstractListModel(), db_(databas
virtualItemShown_ = false;
}
int FolderModel::rowCount(const QModelIndex & parent) const {
int FolderModel::rowCount(const QModelIndex & parent) const { Q_UNUSED(parent);
return Folder::count() + (virtualItemShown_ ? 1 : 0);
}
@ -18,17 +18,17 @@ QVariant FolderModel::data(const QModelIndex & index, int role) const {
Folder folder;
if (virtualItemShown_ && index.row() == rowCount() - 1) {
folder.setTitle("Untitled");
folder.setValue("title", BaseModel::Value(QString("Untitled")));
} else {
folder = atIndex(index.row());
}
if (role == Qt::DisplayRole) {
return QVariant(folder.title());
return folder.value("title").toQVariant();
}
if (role == IdRole) {
return QVariant(folder.id());
return folder.id().toQVariant();
}
return QVariant();
@ -38,7 +38,7 @@ bool FolderModel::setData(const QModelIndex &index, const QVariant &value, int r
Folder folder = atIndex(index.row());
if (role == Qt::EditRole) {
folder.setTitle(value.toString());
folder.setValue("title", value);
if (!folder.save()) return false;
cache_.clear();
@ -90,7 +90,7 @@ void FolderModel::hideVirtualItem() {
endRemoveRows();
}
QString FolderModel::idAtIndex(int index) const {
QString FolderModel::indexToId(int index) const {
return data(this->index(index), IdRole).toString();
}
@ -98,7 +98,7 @@ int FolderModel::idToIndex(const QString &id) const {
int count = this->rowCount();
for (int i = 0; i < count; i++) {
Folder folder = atIndex(i);
if (folder.id() == id) return i;
if (folder.value("id").toString() == id) return i;
}
return -1;
}
@ -125,12 +125,12 @@ QHash<int, QByteArray> FolderModel::roleNames() const {
void FolderModel::addData(const QString &title) {
Folder folder;
folder.setTitle(title);
folder.setValue("title", title);
if (!folder.save()) return;
cache_.clear();
lastInsertId_ = folder.id();
lastInsertId_ = folder.id().toString();
QVector<int> roles;
roles << Qt::DisplayRole;

View File

@ -50,14 +50,10 @@ public slots:
void showVirtualItem();
bool virtualItemShown() const;
void hideVirtualItem();
QString idAtIndex(int index) const;
QString indexToId(int index) const;
int idToIndex(const QString& id) const;
QString lastInsertId() const;
signals:
void dataChanging();
};
}

View File

@ -3,56 +3,62 @@
using namespace jop;
Item::Item() {
synced_ = false;
}
Item::Item() {}
QString Item::id() const {
return id_;
}
//Item::Item() {
// synced_ = false;
//}
QString Item::title() const {
return title_;
}
////QString Item::id() const {
//// return id_;
////}
int Item::createdTime() const {
return createdTime_;
}
//QString Item::title() const {
// return title_;
//}
int Item::updatedTime() const {
return updatedTime_;
}
//int Item::createdTime() const {
// return createdTime_;
//}
bool Item::synced() const {
return synced_;
}
//int Item::updatedTime() const {
// return updatedTime_;
//}
void Item::setId(const QString& v) {
id_ = v;
}
//bool Item::synced() const {
// return synced_;
//}
void Item::setTitle(const QString &v) {
title_ = v;
}
//void Item::setId(const QString& v) {
//// if (id_ == v) return;
// id_ = v;
//// changedFields_.push_back("id");
//}
void Item::setCreatedTime(int v) {
createdTime_ = v;
}
//void Item::setTitle(const QString &v) {
//// if (title_ == v) return;
// title_ = v;
//// changedFields_.push_back("title");
//}
void Item::setSynced(bool v) {
synced_ = v;
}
//void Item::setCreatedTime(int v) {
// createdTime_ = v;
//}
QStringList Item::dbFields() {
QStringList output;
output << "id" << "title" << "created_time" << "updated_time" << "synced";
return output;
}
//void Item::setSynced(bool v) {
// synced_ = v;
//}
void Item::fromSqlQuery(const QSqlQuery &q) {
id_ = q.value(0).toString();
title_ = q.value(1).toString();
createdTime_ = q.value(2).toInt();
updatedTime_ = q.value(3).toInt();
synced_ = q.value(4).toBool();
}
//QStringList Item::dbFields() {
// QStringList output;
// output << "id" << "title" << "created_time" << "updated_time" << "synced";
// return output;
//}
//void Item::fromSqlQuery(const QSqlQuery &q) {
// id_ = q.value(0).toString();
// title_ = q.value(1).toString();
// createdTime_ = q.value(2).toInt();
// updatedTime_ = q.value(3).toInt();
// synced_ = q.value(4).toBool();
//}

View File

@ -3,35 +3,36 @@
#include <stable.h>
#include "models/basemodel.h"
namespace jop {
class Item {
class Item : public BaseModel {
public:
Item();
QString id() const;
QString title() const;
int createdTime() const;
int updatedTime() const;
bool synced() const;
static QStringList dbFields();
// QString title() const;
// int createdTime() const;
// int updatedTime() const;
// bool synced() const;
// static QStringList dbFields();
void setId(const QString &v);
void setTitle(const QString& v);
void setCreatedTime(int v);
void setSynced(bool v);
// void setId(const QString &v);
// void setTitle(const QString& v);
// void setCreatedTime(int v);
// void setSynced(bool v);
void fromSqlQuery(const QSqlQuery& query);
// void fromSqlQuery(const QSqlQuery& query);
private:
QString id_;
QString title_;
time_t createdTime_;
time_t updatedTime_;
bool synced_;
// QString id_;
// QString title_;
// time_t createdTime_;
// time_t updatedTime_;
// bool synced_;
};

View File

@ -7,22 +7,22 @@ Note::Note()
}
QString Note::body() const {
return body_;
}
//QString Note::body() const {
// return body_;
//}
void Note::setBody(const QString &v) {
body_ = v;
}
//void Note::setBody(const QString &v) {
// body_ = v;
//}
QStringList Note::dbFields() {
QStringList output = Item::dbFields();
output << "body";
return output;
}
//QStringList Note::dbFields() {
// QStringList output = Item::dbFields();
// output << "body";
// return output;
//}
void Note::fromSqlQuery(const QSqlQuery &q) {
Item::fromSqlQuery(q);
int idx = Item::dbFields().size();
body_ = q.value(idx).toString();
}
//void Note::fromSqlQuery(const QSqlQuery &q) {
// Item::fromSqlQuery(q);
// int idx = Item::dbFields().size();
// body_ = q.value(idx).toString();
//}

View File

@ -11,14 +11,14 @@ class Note : public Item {
public:
Note();
QString body() const;
void setBody(const QString& v);
static QStringList dbFields();
void fromSqlQuery(const QSqlQuery &q);
// QString body() const;
// void setBody(const QString& v);
// static QStringList dbFields();
// void fromSqlQuery(const QSqlQuery &q);
private:
//private:
QString body_;
// QString body_;
};

View File

@ -11,36 +11,37 @@ NoteCollection::NoteCollection(Database& db, const QString& parentId, const QStr
}
Note NoteCollection::at(int index) const {
if (parentId_ == "") return Note();
return Note();
// if (parentId_ == "") return Note();
if (cache_.isset(index)) return cache_.get(index);
// if (cache_.isset(index)) return cache_.get(index);
std::vector<int> indexes = cache_.availableBufferAround(index, 32);
if (!indexes.size()) {
qWarning() << "Couldn't acquire buffer"; // "Cannot happen"
return Note();
}
// std::vector<int> indexes = cache_.availableBufferAround(index, 32);
// if (!indexes.size()) {
// qWarning() << "Couldn't acquire buffer"; // "Cannot happen"
// return Note();
// }
int from = indexes[0];
int to = indexes[indexes.size() - 1];
// int from = indexes[0];
// int to = indexes[indexes.size() - 1];
QSqlQuery q = db_.query("SELECT id, title, body FROM notes WHERE parent_id = :parent_id ORDER BY " + orderBy_ + " LIMIT " + QString::number(to - from + 1) + " OFFSET " + QString::number(from));
q.bindValue(":parent_id", parentId_);
q.exec();
// QSqlQuery q = db_.query("SELECT id, title, body FROM notes WHERE parent_id = :parent_id ORDER BY " + orderBy_ + " LIMIT " + QString::number(to - from + 1) + " OFFSET " + QString::number(from));
// q.bindValue(":parent_id", parentId_);
// q.exec();
int noteIndex = from;
while (q.next()) {
Note note;
note.setId(q.value(0).toString());
note.setTitle(q.value(1).toString());
note.setBody(q.value(2).toString());
// int noteIndex = from;
// while (q.next()) {
// Note note;
// note.setId(q.value(0).toString());
// note.setTitle(q.value(1).toString());
// note.setBody(q.value(2).toString());
cache_.set(noteIndex, note);
// cache_.set(noteIndex, note);
noteIndex++;
}
// noteIndex++;
// }
return cache_.get(index);
// return cache_.get(index);
}
// TODO: cache result
@ -55,25 +56,26 @@ int NoteCollection::count() const {
}
Note NoteCollection::byId(const QString& id) const {
std::vector<int> indexes = cache_.indexes();
for (size_t i = 0; i < indexes.size(); i++) {
Note note = cache_.get(indexes[i]);
if (note.id() == id) return note;
}
return Note();
// std::vector<int> indexes = cache_.indexes();
// for (size_t i = 0; i < indexes.size(); i++) {
// Note note = cache_.get(indexes[i]);
// if (note.id() == id) return note;
// }
QSqlQuery q = db_.query("SELECT id, title, body FROM notes WHERE id = :id");
q.bindValue(":id", id);
q.exec();
q.next();
if (!q.isValid()) {
qWarning() << "Invalid note ID:" << id;
return Note();
}
// QSqlQuery q = db_.query("SELECT id, title, body FROM notes WHERE id = :id");
// q.bindValue(":id", id);
// q.exec();
// q.next();
// if (!q.isValid()) {
// qWarning() << "Invalid note ID:" << id;
// return Note();
// }
// TODO: refactor creation of note from SQL query object
Note note;
note.setId(q.value(0).toString());
note.setTitle(q.value(1).toString());
note.setBody(q.value(2).toString());
return note;
// // TODO: refactor creation of note from SQL query object
// Note note;
// note.setId(q.value(0).toString());
// note.setTitle(q.value(1).toString());
// note.setBody(q.value(2).toString());
// return note;
}

View File

@ -13,13 +13,13 @@ int jop::NoteModel::rowCount(const QModelIndex &parent) const {
QVariant jop::NoteModel::data(const QModelIndex &index, int role) const {
if (index.row() < 0 || index.row() >= rowCount()) return QVariant();
Note note = collection_.at(index.row());
// Note note = collection_.at(index.row());
if (role == IdRole) {
return QVariant(note.id());
}
// if (role == IdRole) {
// return QVariant(note.id());
// }
return QVariant(note.title());
// return QVariant(note.title());
}
void jop::NoteModel::setFolderId(const QString &v) {

View File

@ -5,11 +5,11 @@ using namespace jop;
QmlNote::QmlNote() {}
QString QmlNote::title() const {
return note_.title();
return note_.value("title").toString();
}
QString QmlNote::body() const {
return note_.body();
return note_.value("body").toString();
}
void QmlNote::setNote(const Note &note) {

View File

@ -14,48 +14,48 @@ void Synchronizer::start() {
QSqlQuery query;
std::vector<Folder> folders;
query = db_.query("SELECT " + Folder::dbFields().join(',') + " FROM folders WHERE synced = 0");
query.exec();
// std::vector<Folder> folders;
// query = db_.query("SELECT " + Folder::dbFields().join(',') + " FROM folders WHERE synced = 0");
// query.exec();
while (query.next()) {
Folder folder;
folder.fromSqlQuery(query);
folders.push_back(folder);
}
// while (query.next()) {
// Folder folder;
// folder.fromSqlQuery(query);
// folders.push_back(folder);
// }
QList<Note> notes;
query = db_.query("SELECT " + Note::dbFields().join(',') + " FROM notes WHERE synced = 0");
query.exec();
// QList<Note> notes;
// query = db_.query("SELECT " + Note::dbFields().join(',') + " FROM notes WHERE synced = 0");
// query.exec();
while (query.next()) {
Note note;
note.fromSqlQuery(query);
notes << note;
}
// while (query.next()) {
// Note note;
// note.fromSqlQuery(query);
// notes << note;
// }
for (size_t i = 0; i < folders.size(); i++) {
Folder folder = folders[i];
QUrlQuery data;
data.addQueryItem("id", folder.id());
data.addQueryItem("title", folder.title());
data.addQueryItem("created_time", QString::number(folder.createdTime()));
data.addQueryItem("updated_time", QString::number(folder.updatedTime()));
api_.put("folders/" + folder.id(), QUrlQuery(), data, "putFolder:" + folder.id());
}
// for (size_t i = 0; i < folders.size(); i++) {
// Folder folder = folders[i];
// QUrlQuery data;
// data.addQueryItem("id", folder.id());
// data.addQueryItem("title", folder.title());
// data.addQueryItem("created_time", QString::number(folder.createdTime()));
// data.addQueryItem("updated_time", QString::number(folder.updatedTime()));
// api_.put("folders/" + folder.id(), QUrlQuery(), data, "putFolder:" + folder.id());
// }
return;
// return;
for (int i = 0; i < notes.size(); i++) {
Note note = notes[i];
QUrlQuery data;
data.addQueryItem("id", note.id());
data.addQueryItem("title", note.title());
data.addQueryItem("body", note.body());
data.addQueryItem("created_time", QString::number(note.createdTime()));
data.addQueryItem("updated_time", QString::number(note.updatedTime()));
api_.put("notes/" + note.id(), QUrlQuery(), data, "putNote:" + note.id());
}
// for (int i = 0; i < notes.size(); i++) {
// Note note = notes[i];
// QUrlQuery data;
// data.addQueryItem("id", note.id());
// data.addQueryItem("title", note.title());
// data.addQueryItem("body", note.body());
// data.addQueryItem("created_time", QString::number(note.createdTime()));
// data.addQueryItem("updated_time", QString::number(note.updatedTime()));
// api_.put("notes/" + note.id(), QUrlQuery(), data, "putNote:" + note.id());
// }
}
void Synchronizer::api_requestDone(const QJsonObject& response, const QString& tag) {

Binary file not shown.

Binary file not shown.