diff options
author | Marco Bubke <marco.bubke@qt.io> | 2021-11-29 17:52:46 +0100 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2021-12-08 15:01:05 +0000 |
commit | 08275566214f6dc29a13785c2c80fc026f21c2ff (patch) | |
tree | c1e03331b974eb62787b69492d54d88b89182b34 /src | |
parent | 56af8b905e17254b86bad73a02c023b043039a31 (diff) |
QmlDesigner: Synchronize ProjectData to the Storage
Task-number: QDS-5644
Change-Id: Icede506974e88dd64fc866b65f4fa9d64a05aea0
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Diffstat (limited to 'src')
6 files changed, 165 insertions, 12 deletions
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 83131404de..c1bfb244ff 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -110,6 +110,8 @@ public: linkAliases(insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations); + synchronizeProjectDatas(package.projectDatas, package.updatedProjectSourceIds); + transaction.commit(); } @@ -306,9 +308,20 @@ public: &sourceId); } - Storage::ProjectDatas fetchProjectDatas(SourceId sourceId) const override + Storage::ProjectDatas fetchProjectDatas(SourceId projectSourceId) const override { - return Storage::ProjectDatas{}; + return selectProjectDatasForModuleIdStatement + .template valuesWithTransaction<Storage::ProjectData>(64, &projectSourceId); + } + + Storage::ProjectDatas fetchProjectDatas(const SourceIds &projectSourceIds) const + { + auto projectSourceIdValues = Utils::transform<std::vector>(projectSourceIds, + [](SourceId id) { return &id; }); + + return selectProjectDatasForModuleIdsStatement + .template valuesWithTransaction<Storage::ProjectData>(64, + Utils::span(projectSourceIdValues)); } private: @@ -533,6 +546,65 @@ private: relinkablePropertyDeclarations); } + void synchronizeProjectDatas(Storage::ProjectDatas &projectDatas, + const SourceIds &updatedProjectSourceIds) + { + auto updatedProjectSourceIdValues = Utils::transform<std::vector>(updatedProjectSourceIds, + [](SourceId id) { + return &id; + }); + + auto compareKey = [](auto &&first, auto &&second) { + auto projectSourceIdDifference = first.projectSourceId.id - second.projectSourceId.id; + if (projectSourceIdDifference != 0) + return projectSourceIdDifference; + + return first.sourceId.id - second.sourceId.id; + }; + + std::sort(projectDatas.begin(), projectDatas.end(), [&](auto &&first, auto &&second) { + return std::tie(first.projectSourceId, first.sourceId) + < std::tie(second.projectSourceId, second.sourceId); + }); + + auto range = selectProjectDatasForModuleIdsStatement.template range<Storage::ProjectData>( + Utils::span(updatedProjectSourceIdValues)); + + auto insert = [&](const Storage::ProjectData &projectData) { + if (!projectData.projectSourceId) + throw ProjectDataHasInvalidProjectSourceId{}; + if (!projectData.sourceId) + throw ProjectDataHasInvalidSourceId{}; + if (!projectData.moduleId) + throw ProjectDataHasInvalidModuleId{}; + + insertProjectDataStatement.write(&projectData.projectSourceId, + &projectData.sourceId, + &projectData.moduleId, + static_cast<int>(projectData.fileType)); + }; + + auto update = [&](const Storage::ProjectData &projectDataFromDatabase, + const Storage::ProjectData &projectData) { + if (!projectData.moduleId) + throw ProjectDataHasInvalidModuleId{}; + + if (projectDataFromDatabase.fileType != projectData.fileType + || projectDataFromDatabase.moduleId != projectData.moduleId) { + updateProjectDataStatement.write(&projectData.projectSourceId, + &projectData.sourceId, + &projectData.moduleId, + static_cast<int>(projectData.fileType)); + } + }; + + auto remove = [&](const Storage::ProjectData &projectData) { + deleteProjectDataStatement.write(&projectData.projectSourceId, &projectData.sourceId); + }; + + Sqlite::insertUpdateDelete(range, projectDatas, compareKey, insert, update, remove); + } + void synchronizeFileStatuses(FileStatuses &fileStatuses, const SourceIds &updatedSourceIds) { auto updatedSourceIdValues = Utils::transform<std::vector>(updatedSourceIds, @@ -1766,6 +1838,7 @@ private: createSignalsTable(database); createDocumentImportsTable(database, moduleIdColumn); createFileStatusesTable(database); + createProjectDatasTable(database); transaction.commit(); @@ -2008,6 +2081,22 @@ private: table.initialize(database); } + + void createProjectDatasTable(Database &database) + { + Sqlite::Table table; + table.setUseIfNotExists(true); + table.setUseWithoutRowId(true); + table.setName("projectDatas"); + auto &projectSourceIdColumn = table.addColumn("projectSourceId"); + auto &sourceIdColumn = table.addColumn("sourceId"); + table.addColumn("moduleId"); + table.addColumn("fileType"); + + table.addPrimaryKeyContraint({projectSourceIdColumn, sourceIdColumn}); + + table.initialize(database); + } }; public: @@ -2448,6 +2537,22 @@ public: "DELETE FROM exportedTypeNames WHERE exportedTypeNameId=?", database}; WriteStatement updateExportedTypeNameTypeIdStatement{ "UPDATE exportedTypeNames SET typeId=?2 WHERE exportedTypeNameId=?1", database}; + mutable ReadStatement<4> selectProjectDatasForModuleIdsStatement{ + "SELECT projectSourceId, sourceId, moduleId, fileType FROM projectDatas WHERE " + "projectSourceId IN carray(?1) ORDER BY projectSourceId, sourceId", + database}; + WriteStatement insertProjectDataStatement{"INSERT INTO projectDatas(projectSourceId, sourceId, " + "moduleId, fileType) VALUES(?1, ?2, ?3, ?4)", + database}; + WriteStatement deleteProjectDataStatement{ + "DELETE FROM projectDatas WHERE projectSourceId=?1 AND sourceId=?2", database}; + WriteStatement updateProjectDataStatement{ + "UPDATE projectDatas SET moduleId=?3, fileType=?4 WHERE projectSourceId=?1 AND sourceId=?2", + database}; + mutable ReadStatement<4> selectProjectDatasForModuleIdStatement{ + "SELECT projectSourceId, sourceId, moduleId, fileType FROM projectDatas WHERE " + "projectSourceId=?1", + database}; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h index c95d3e00e2..9b22a6d197 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h @@ -113,4 +113,22 @@ public: const char *what() const noexcept override { return "Cannot parse qml types file!"; } }; +class ProjectDataHasInvalidProjectSourceId : std::exception +{ +public: + const char *what() const noexcept override { return "The project source id is invalid!"; } +}; + +class ProjectDataHasInvalidSourceId : std::exception +{ +public: + const char *what() const noexcept override { return "The source id is invalid!"; } +}; + +class ProjectDataHasInvalidModuleId : std::exception +{ +public: + const char *what() const noexcept override { return "The module id is invalid!"; } +}; + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h index b564372a86..927d429466 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h @@ -735,15 +735,30 @@ using Types = std::vector<Type>; class ProjectData { public: - ProjectData(ModuleId extraModuleId, SourceId sourceId, FileType fileType) - : extraModuleId{extraModuleId} + ProjectData(SourceId projectSourceId, SourceId sourceId, ModuleId moduleId, FileType fileType) + : projectSourceId{projectSourceId} , sourceId{sourceId} + , moduleId{moduleId} , fileType{fileType} {} + ProjectData(int projectSourceId, int sourceId, int moduleId, int fileType) + : projectSourceId{projectSourceId} + , sourceId{sourceId} + , moduleId{moduleId} + , fileType{static_cast<Storage::FileType>(fileType)} + {} + + friend bool operator==(const ProjectData &first, const ProjectData &second) + { + return first.projectSourceId == second.projectSourceId && first.sourceId == second.sourceId + && first.moduleId == second.moduleId && first.fileType == second.fileType; + } + public: - ModuleId extraModuleId; + SourceId projectSourceId; SourceId sourceId; + ModuleId moduleId; FileType fileType; }; @@ -767,18 +782,23 @@ public: : updatedSourceIds(std::move(updatedSourceIds)) {} - SynchronizationPackage(SourceIds updatedSourceIds, FileStatuses fileStatuses) - : updatedSourceIds(std::move(updatedSourceIds)) + SynchronizationPackage(SourceIds updatedFileStatusSourceIds, FileStatuses fileStatuses) + : updatedFileStatusSourceIds(std::move(updatedFileStatusSourceIds)) , fileStatuses(std::move(fileStatuses)) {} + SynchronizationPackage(SourceIds updatedProjectSourceIds, ProjectDatas projectDatas) + : projectDatas(std::move(projectDatas)) + , updatedProjectSourceIds(std::move(updatedProjectSourceIds)) + {} + public: Imports imports; Types types; SourceIds updatedSourceIds; FileStatuses fileStatuses; ProjectDatas projectDatas; - ModuleIds updatedProjectDataModuleIds; + SourceIds updatedProjectSourceIds; SourceIds updatedFileStatusSourceIds; }; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp index 3f3ac32166..62c5cfee8c 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp @@ -112,17 +112,19 @@ void ProjectUpdater::update() addSourceIds(package.updatedFileStatusSourceIds, qmlProjectDatas); parseTypeInfos(parser.typeInfos(), + qmlDirSourceId, directoryId, moduleId, package, notUpdatedFileStatusSourceIds, notUpdatedSourceIds); parseQmlComponents(createComponentReferences(parser.components()), + qmlDirSourceId, directoryId, moduleId, package, notUpdatedFileStatusSourceIds); - package.updatedProjectDataModuleIds.push_back(moduleId); + package.updatedProjectSourceIds.push_back(qmlDirSourceId); break; } case FileState::NotChanged: { @@ -154,6 +156,7 @@ void ProjectUpdater::update() void ProjectUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &idPaths) {} void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos, + SourceId qmldirSourceId, SourceContextId directoryId, ModuleId moduleId, Storage::SynchronizationPackage &package, @@ -166,8 +169,9 @@ void ProjectUpdater::parseTypeInfos(const QStringList &typeInfos, SourceId sourceId = m_pathCache.sourceId(directoryId, Utils::SmallString{typeInfo}); QString qmltypesPath = directory + "/" + typeInfo; - auto projectData = package.projectDatas.emplace_back(moduleId, + auto projectData = package.projectDatas.emplace_back(qmldirSourceId, sourceId, + moduleId, Storage::FileType::QmlTypes); parseTypeInfo(projectData, @@ -229,6 +233,7 @@ void ProjectUpdater::parseQmlComponent(Utils::SmallStringView fileName, Utils::SmallStringView typeName, Storage::Version version, ModuleId moduleId, + SourceId qmldirSourceId, SourceContextId directoryId, Storage::SynchronizationPackage &package, SourceIds ¬UpdatedFileStatusSourceIds) @@ -254,7 +259,7 @@ void ProjectUpdater::parseQmlComponent(Utils::SmallStringView fileName, break; } - package.projectDatas.emplace_back(moduleId, sourceId, Storage::FileType::QmlDocument); + package.projectDatas.emplace_back(qmldirSourceId, sourceId, moduleId, Storage::FileType::QmlDocument); package.updatedSourceIds.push_back(sourceId); @@ -293,6 +298,7 @@ void ProjectUpdater::parseQmlComponent(Utils::SmallStringView fileName, } void ProjectUpdater::parseQmlComponents(ComponentReferences components, + SourceId qmldirSourceId, SourceContextId directoryId, ModuleId moduleId, Storage::SynchronizationPackage &package, @@ -318,6 +324,7 @@ void ProjectUpdater::parseQmlComponents(ComponentReferences components, Utils::SmallString{component.typeName}, Storage::Version{component.majorVersion, component.minorVersion}, moduleId, + qmldirSourceId, directoryId, package, notUpdatedFileStatusSourceIds); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h index 237c75e5da..4ab75a5254 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h @@ -87,6 +87,7 @@ private: }; void parseTypeInfos(const QStringList &typeInfos, + SourceId qmldirSourceId, SourceContextId directoryId, ModuleId moduleId, Storage::SynchronizationPackage &package, @@ -102,6 +103,7 @@ private: SourceIds ¬UpdatedFileStatusSourceIds, SourceIds ¬UpdatedSourceIds); void parseQmlComponents(ComponentReferences components, + SourceId qmldirSourceId, SourceContextId directoryId, ModuleId moduleId, Storage::SynchronizationPackage &package, @@ -114,6 +116,7 @@ private: Utils::SmallStringView typeName, Storage::Version version, ModuleId moduleId, + SourceId qmldirSourceId, SourceContextId directoryId, Storage::SynchronizationPackage &package, SourceIds ¬UpdatedFileStatusSourceIds); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp index f5d09409aa..e1b66378e6 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp @@ -283,7 +283,7 @@ void addTypes(Storage::Types &types, types.reserve(Utils::usize(objects) + types.size()); for (const auto &object : objects) - addType(types, projectData.sourceId, projectData.extraModuleId, *object.get(), storage); + addType(types, projectData.sourceId, projectData.moduleId, *object.get(), storage); } } // namespace |