Skip to content

Commit

Permalink
Improve multiple documents syncing
Browse files Browse the repository at this point in the history
  • Loading branch information
dimkanovikov committed Oct 10, 2023
1 parent f530d40 commit 50c2ff2
Show file tree
Hide file tree
Showing 12 changed files with 144 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/cloud
Submodule cloud updated from d314b2 to c758ac
4 changes: 3 additions & 1 deletion src/core/management_layer/application_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3121,6 +3121,7 @@ void ApplicationManager::initConnections()
if (documentsToSync.isEmpty()) {
return;
}
QVector<Domain::DocumentObject*> documentsToUpdate;
for (const auto& documentToSync : std::as_const(documentsToSync)) {
const auto document = d->projectManager->documentToSync(documentToSync);
//
Expand All @@ -3134,9 +3135,10 @@ void ApplicationManager::initConnections()
// А если есть, то значит его инстанс уже есть в базе и его надо обновить
//
else {
d->cloudServiceManager->openDocument(currentProject->id(), document);
documentsToUpdate.append(document);
}
}
d->cloudServiceManager->openDocuments(currentProject->id(), documentsToUpdate);
});
connect(d->cloudServiceManager.data(), &CloudServiceManager::documentReceived,
d->projectManager.data(), &ProjectManager::mergeDocumentInfo);
Expand Down
11 changes: 10 additions & 1 deletion src/core/management_layer/content/project/project_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3176,6 +3176,8 @@ QVector<Domain::DocumentObject*> ProjectManager::unsyncedDocuments() const

void ProjectManager::mergeDocumentInfo(const Domain::DocumentInfo& _documentInfo)
{
const auto syncDatetime = QDateTime::currentDateTimeUtc();

Domain::DocumentObject* document = nullptr;
const auto documentType = static_cast<Domain::DocumentObjectType>(_documentInfo.type);
switch (documentType) {
Expand Down Expand Up @@ -3359,8 +3361,9 @@ void ProjectManager::mergeDocumentInfo(const Domain::DocumentInfo& _documentInfo
}

//
// Сохраним документ
// Помечаем документ синхронизированным и сохраняем
//
document->setSyncedAt(syncDatetime);
DataStorageLayer::StorageFacade::documentStorage()->saveDocument(document);

//
Expand All @@ -3386,6 +3389,12 @@ void ProjectManager::mergeDocumentInfo(const Domain::DocumentInfo& _documentInfo
}
}
}

//
// TODO: Вынести в отдельный поток применение массовых изменений? либо как-то уведомлять
// пользователя о том, что сейчас идёт синхронизация данных проекта
//
QApplication::processEvents();
}

void ProjectManager::applyDocumentChanges(const Domain::DocumentInfo& _documentInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ TemplateOptionsManager::Implementation::Implementation(QWidget* _parent,
, viewToolBar(new Ui::ScreenplayTemplateViewToolBar(_parent))
, pluginsBuilder(_pluginsBuilder)
, titlePageDocument(Domain::ObjectsBuilder::createDocument(
{}, {}, Domain::DocumentObjectType::ScreenplayTitlePage, {}))
{}, {}, Domain::DocumentObjectType::ScreenplayTitlePage, {}, {}))
{
toolBar->hide();
navigator->hide();
Expand Down
85 changes: 74 additions & 11 deletions src/corelib/data_layer/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,8 @@ void Database::createTables(QSqlDatabase& _database)
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"uuid TEXT UNIQUE NOT NULL, "
"type INTEGER NOT NULL DEFAULT(0), "
"content BLOB DEFAULT(NULL) "
"content BLOB DEFAULT(NULL), "
"synced_at TEXT DEFAULT(NULL) "
")");

//
Expand Down Expand Up @@ -339,20 +340,60 @@ void Database::updateDatabase(QSqlDatabase& _database)
query.addBindValue(applicationVersionKey());
query.exec();
query.next();
const auto databaseVersion = query.record().value("version").toString();

auto databaseVersion = query.record().value("version").toString();
//
// Некоторые версии выходили с ошибками, их заменяем на предыдущие
// Извлекаем информацию о dev-версии
//
{
// if (databaseVersion.startsWith("X.X.X beta")) {
// databaseVersion = "Y.Y.Y";
// }
bool isDevVersion = false;
if (const auto devIndex = databaseVersion.indexOf(" dev "); devIndex > 0) {
isDevVersion = true;
databaseVersion = databaseVersion.left(devIndex);
}
const QStringList& versionParts = databaseVersion.split(".");
const int versionMajor = versionParts.value(0, "0").toInt();
const int versionMinor = versionParts.value(1, "0").toInt();
const int versionBuild = versionParts.value(2, "1").toInt();
int versionMajor = versionParts.value(0, "0").toInt();
int versionMinor = versionParts.value(1, "0").toInt();
int versionBuild = versionParts.value(2, "1").toInt();
//
// Корректируем номер версии если это dev-сборка
//
if (isDevVersion) {
//
// x.x.3 dev -> x.x.2
//
if (versionBuild > 0) {
--versionBuild;
}
//
// x.x.0 dev ->
//
else {
versionBuild = 999;
//
// x.3.0 dev -> x.2.999
//
if (versionMinor > 0) {
--versionMinor;
}
//
// x.0.0 dev ->
//
else {
versionMinor = 999;
//
// 1.0.0 dev -> 0.999.999
//
if (versionMajor > 0) {
--versionMajor;
}
//
// 0.0.0 dev - такого не может быть!
//
else {
Q_ASSERT(false);
}
}
}
}

//
// Вызываются необходимые процедуры обновления БД в зависимости от её версии
Expand Down Expand Up @@ -393,6 +434,17 @@ void Database::updateDatabase(QSqlDatabase& _database)
updateDatabaseTo_0_2_4(_database);
}
}
//
// 0.6.x
//
if (versionMajor < 0 || versionMinor <= 6) {
//
// 0.6.1
//
if (versionMajor < 0 || versionMinor < 6 || versionBuild <= 1) {
updateDatabaseTo_0_6_2(_database);
}
}
}

//
Expand Down Expand Up @@ -529,4 +581,15 @@ void Database::updateDatabaseTo_0_2_4(QSqlDatabase& _database)
_database.commit();
}

void Database::updateDatabaseTo_0_6_2(QSqlDatabase& _database)
{
QSqlQuery q_updater(_database);

_database.transaction();

q_updater.exec("ALTER TABLE documents ADD synced_at TEXT DEFAULT(NULL)");

_database.commit();
}

} // namespace DatabaseLayer
1 change: 1 addition & 0 deletions src/corelib/data_layer/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class CORE_LIBRARY_EXPORT Database
static void updateDatabaseTo_0_0_10(QSqlDatabase& _database);
static void updateDatabaseTo_0_1_3(QSqlDatabase& _database);
static void updateDatabaseTo_0_2_4(QSqlDatabase& _database);
static void updateDatabaseTo_0_6_2(QSqlDatabase& _database);
};

Q_DECLARE_OPERATORS_FOR_FLAGS(Database::States)
Expand Down
22 changes: 18 additions & 4 deletions src/corelib/data_layer/mapper/document_mapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ using Domain::Identifier;
namespace DataMappingLayer {

namespace {
const QString kColumns = " id, uuid, type, content ";
const QString kColumns = " id, uuid, type, content, synced_at ";
const QString kTableName = " documents ";
const QString kDateTimeFormat = "yyyy-MM-dd hh:mm:ss:zzz";
QString uuidFilter(const QUuid& _uuid)
{
return QString(" WHERE uuid = '%1' ").arg(_uuid.toString());
Expand Down Expand Up @@ -121,14 +122,17 @@ QString DocumentMapper::insertStatement(DomainObject* _object, QVariantList& _in
{
const QString insertStatement = QString("INSERT INTO " + kTableName + " (" + kColumns
+ ") "
" VALUES(?, ?, ?, ?) ");
" VALUES(?, ?, ?, ?, ?) ");

const auto documentObject = static_cast<DocumentObject*>(_object);
_insertValues.clear();
_insertValues.append(documentObject->id().value());
_insertValues.append(documentObject->uuid().toString());
_insertValues.append(static_cast<int>(documentObject->type()));
_insertValues.append(documentObject->content());
_insertValues.append(documentObject->syncedAt().isValid()
? documentObject->syncedAt().toString(kDateTimeFormat)
: QVariant());

return insertStatement;
}
Expand All @@ -138,14 +142,18 @@ QString DocumentMapper::updateStatement(DomainObject* _object, QVariantList& _up
const QString updateStatement = QString("UPDATE " + kTableName
+ " SET uuid = ?, "
" type = ?, "
" content = ? "
" content = ?, "
" synced_at = ? "
" WHERE id = ? ");

const auto documentObject = static_cast<DocumentObject*>(_object);
_updateValues.clear();
_updateValues.append(documentObject->uuid().toString());
_updateValues.append(static_cast<int>(documentObject->type()));
_updateValues.append(documentObject->content());
_updateValues.append(documentObject->syncedAt().isValid()
? documentObject->syncedAt().toString(kDateTimeFormat)
: QVariant());
_updateValues.append(documentObject->id().value());

return updateStatement;
Expand All @@ -166,8 +174,10 @@ DomainObject* DocumentMapper::doLoad(const Identifier& _id, const QSqlRecord& _r
const auto uuid = QUuid::fromString(_record.value("uuid").toString());
const auto type = static_cast<DocumentObjectType>(_record.value("type").toInt());
const auto content = _record.value("content").toByteArray();
const auto syncedAt
= QDateTime::fromString(_record.value("synced_at").toString(), kDateTimeFormat);

return Domain::ObjectsBuilder::createDocument(_id, uuid, type, content);
return Domain::ObjectsBuilder::createDocument(_id, uuid, type, content, syncedAt);
}

void DocumentMapper::doLoad(DomainObject* _object, const QSqlRecord& _record)
Expand All @@ -185,6 +195,10 @@ void DocumentMapper::doLoad(DomainObject* _object, const QSqlRecord& _record)

const auto content = _record.value("content").toByteArray();
documentObject->setContent(content);

const auto syncedAt
= QDateTime::fromString(_record.value("synced_at").toString(), kDateTimeFormat);
documentObject->setSyncedAt(syncedAt);
}

} // namespace DataMappingLayer
2 changes: 1 addition & 1 deletion src/corelib/data_layer/storage/document_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ QVector<Domain::DocumentObject*> DocumentStorage::documents()
Domain::DocumentObject* DocumentStorage::createDocument(const QUuid& _uuid,
Domain::DocumentObjectType _type)
{
auto newDocument = Domain::ObjectsBuilder::createDocument({}, _uuid, _type, {});
auto newDocument = Domain::ObjectsBuilder::createDocument({}, _uuid, _type, {}, {});
d->notSavedDocuments.insert(_uuid, newDocument);
return newDocument;
}
Expand Down
18 changes: 17 additions & 1 deletion src/corelib/domain/document_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,28 @@ void DocumentObject::setContent(const QByteArray& _content)
markChangesNotStored();
}

const QDateTime& DocumentObject::syncedAt() const
{
return m_syncedAt;
}

void DocumentObject::setSyncedAt(const QDateTime& _syncedAt)
{
if (m_syncedAt == _syncedAt) {
return;
}

m_syncedAt = _syncedAt;
markChangesNotStored();
}

DocumentObject::DocumentObject(const Identifier& _id, const QUuid& _uuid, DocumentObjectType _type,
const QByteArray& _content)
const QByteArray& _content, const QDateTime& _syncedAt)
: DomainObject(_id)
, m_uuid(_uuid)
, m_type(_type)
, m_content(_content)
, m_syncedAt(_syncedAt)
{
}

Expand Down
14 changes: 13 additions & 1 deletion src/corelib/domain/document_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "domain_object.h"

#include <QDateTime>
#include <QPixmap>
#include <QUuid>

Expand Down Expand Up @@ -147,9 +148,15 @@ class CORE_LIBRARY_EXPORT DocumentObject : public DomainObject
const QByteArray& content() const;
void setContent(const QByteArray& _content);

/**
* @brief Дата и время последней синхронизации
*/
const QDateTime& syncedAt() const;
void setSyncedAt(const QDateTime& _syncedAt);

private:
explicit DocumentObject(const Identifier& _id, const QUuid& _uuid, DocumentObjectType _type,
const QByteArray& _content);
const QByteArray& _content, const QDateTime& _syncedAt);
friend class ObjectsBuilder;

/**
Expand All @@ -166,6 +173,11 @@ class CORE_LIBRARY_EXPORT DocumentObject : public DomainObject
* @brief Содержимое объекта
*/
QByteArray m_content;

/**
* @brief Дата время последней синхронизации содержимого документа
*/
QDateTime m_syncedAt;
};

} // namespace Domain
5 changes: 3 additions & 2 deletions src/corelib/domain/objects_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
namespace Domain {

DocumentObject* ObjectsBuilder::createDocument(const Identifier& _id, const QUuid& _uuid,
DocumentObjectType _type, const QByteArray& _content)
DocumentObjectType _type, const QByteArray& _content,
const QDateTime& _syncedAt)
{
return new DocumentObject(_id, _uuid, _type, _content);
return new DocumentObject(_id, _uuid, _type, _content, _syncedAt);
}

DocumentChangeObject* ObjectsBuilder::createDocumentChange(
Expand Down
3 changes: 2 additions & 1 deletion src/corelib/domain/objects_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ class CORE_LIBRARY_EXPORT ObjectsBuilder
* @brief Создать элемент
*/
static DocumentObject* createDocument(const Identifier& _id, const QUuid& _uuid,
DocumentObjectType _type, const QByteArray& _content);
DocumentObjectType _type, const QByteArray& _content,
const QDateTime& _syncedAt);

/**
* @brief Создать изменение
Expand Down

0 comments on commit 50c2ff2

Please sign in to comment.