You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Added BaseModel to allow tracking changes
This commit is contained in:
		| @@ -46,7 +46,7 @@ Item { | ||||
| 		} | ||||
|  | ||||
| 		onCurrentItemChanged: { | ||||
| 			currentItemId = model.idAtIndex(currentIndex); | ||||
| 			currentItemId = model.indexToId(currentIndex); | ||||
| 		} | ||||
|  | ||||
| 		id: listView | ||||
|   | ||||
| @@ -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 += | ||||
|  | ||||
|   | ||||
| @@ -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() { | ||||
|   | ||||
| @@ -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_; | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
							
								
								
									
										6
									
								
								QtClient/JoplinQtClient/enum.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										6
									
								
								QtClient/JoplinQtClient/enum.cpp
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| #include "enum.h" | ||||
|  | ||||
| enum::enum() | ||||
| { | ||||
|  | ||||
| } | ||||
							
								
								
									
										14
									
								
								QtClient/JoplinQtClient/enum.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								QtClient/JoplinQtClient/enum.h
									
									
									
									
									
										Executable 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 | ||||
							
								
								
									
										283
									
								
								QtClient/JoplinQtClient/models/basemodel.cpp
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										283
									
								
								QtClient/JoplinQtClient/models/basemodel.cpp
									
									
									
									
									
										Executable 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; | ||||
| } | ||||
							
								
								
									
										88
									
								
								QtClient/JoplinQtClient/models/basemodel.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										88
									
								
								QtClient/JoplinQtClient/models/basemodel.h
									
									
									
									
									
										Executable 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 | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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: | ||||
|  | ||||
| }; | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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(); | ||||
|  | ||||
| }; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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(); | ||||
| //} | ||||
|   | ||||
| @@ -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_; | ||||
|  | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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(); | ||||
| //} | ||||
|   | ||||
| @@ -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_; | ||||
|  | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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 ¬e) { | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								QtClient/dependencies/dll-debug/libeay32.dll
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								QtClient/dependencies/dll-debug/libeay32.dll
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								QtClient/dependencies/dll-debug/libssl32.dll
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								QtClient/dependencies/dll-debug/libssl32.dll
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user