diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 8c71950d8e6..0e2602982aa 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -63,9 +63,24 @@ public: { Sqlite::ImmediateTransaction transaction{database}; - synchronizeImports(importDependencies); + std::vector insertedAliasPropertyDeclarations; + std::vector updatedAliasPropertyDeclarations; + + TypeIds updatedTypeIds; + updatedTypeIds.reserve(types.size()); + + TypeIds deletedTypeIds; + + synchronizeImports(importDependencies, deletedTypeIds); synchronizeDocuments(documents); - synchronizeTypes(types, sourceIds); + synchronizeTypes(types, + updatedTypeIds, + insertedAliasPropertyDeclarations, + updatedAliasPropertyDeclarations); + + deleteNotUpdatedTypes(updatedTypeIds, sourceIds, deletedTypeIds); + + linkAliases(insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations); transaction.commit(); } @@ -273,173 +288,6 @@ public: } private: - void synchronizeTypes(Storage::Types &types, SourceIds &sourceIds) - { - std::vector insertedAliasPropertyDeclarations; - std::vector updatedAliasPropertyDeclarations; - - TypeIds updatedTypeIds; - updatedTypeIds.reserve(types.size()); - - for (auto &&type : types) { - if (!type.sourceId) - throw TypeHasInvalidSourceId{}; - - updatedTypeIds.push_back(declareType(type)); - } - - for (auto &&type : types) - syncPrototypes(type); - - for (auto &&type : types) - resetRemovedAliasPropertyDeclarationsToNull(type.typeId, type.propertyDeclarations); - - for (auto &&type : types) - syncDeclarations(type, insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations); - - deleteNotUpdatedTypes(updatedTypeIds, sourceIds); - - linkAliases(insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations); - } - - void synchronizeImports(Storage::ImportDependencies &imports) - { - if (imports.empty()) - return; - - synchronizeImportsAndUpdatesImportIds(imports); - synchronizeImportDependencies(createSortedImportDependecies(imports)); - } - - void synchronizeDocuments(Storage::Documents &documents) - { - for (auto &&document : documents) - synchronizeDocumentImports(document.sourceId, document.imports); - } - - struct ImportDependency - { - ImportDependency(ImportId id, ImportId dependencyId) - : id{id} - , dependencyId{dependencyId} - {} - - ImportDependency(long long id, long long dependencyId) - : id{id} - , dependencyId{dependencyId} - {} - - ImportId id; - ImportId dependencyId; - - friend bool operator<(ImportDependency first, ImportDependency second) - { - return std::tie(first.id, first.dependencyId) < std::tie(second.id, second.dependencyId); - } - - friend bool operator==(ImportDependency first, ImportDependency second) - { - return first.id == second.id && first.dependencyId == second.dependencyId; - } - }; - - void synchronizeImportsAndUpdatesImportIds(Storage::ImportDependencies &imports) - { - auto compareKey = [](auto &&first, auto &&second) { - auto nameCompare = Sqlite::compare(first.name, second.name); - - if (nameCompare != 0) - return nameCompare; - - return first.version.version - second.version.version; - }; - - std::sort(imports.begin(), imports.end(), [&](auto &&first, auto &&second) { - return compareKey(first, second) < 0; - }); - - auto range = selectAllImportsStatement.template range(); - - auto insert = [&](Storage::ImportDependency &import) { - import.importId = insertImportStatement.template value(import.name, - import.version.version, - &import.sourceId); - }; - - auto update = [&](const Storage::ImportView &importView, Storage::ImportDependency &import) { - if (importView.sourceId.id != import.sourceId.id) - updateImportStatement.write(&importView.importId, &import.sourceId); - import.importId = importView.importId; - }; - - auto remove = [&](const Storage::ImportView &importView) { - deleteImportStatement.write(&importView.importId); - deleteTypesForImportId(importView.importId); - }; - - Sqlite::insertUpdateDelete(range, imports, compareKey, insert, update, remove); - } - - std::vector createSortedImportDependecies( - const Storage::ImportDependencies &imports) const - { - std::vector importDependecies; - importDependecies.reserve(imports.size() * 5); - - for (const Storage::ImportDependency &import : imports) { - for (const Storage::Import &importDependency : import.importDependencies) { - auto importIdForDependency = fetchImportId(importDependency); - - if (!importIdForDependency) - throw ImportDoesNotExists{}; - - importDependecies.emplace_back(import.importId, importIdForDependency); - } - } - - std::sort(importDependecies.begin(), importDependecies.end()); - importDependecies.erase(std::unique(importDependecies.begin(), importDependecies.end()), - importDependecies.end()); - - return importDependecies; - } - - void synchronizeImportDependencies(const std::vector &importDependecies) - { - auto compareKey = [](ImportDependency first, ImportDependency second) { - auto idCompare = first.id.id - second.id.id; - - if (idCompare != 0) - return idCompare; - - return first.dependencyId.id - second.dependencyId.id; - }; - - auto range = selectAllImportDependenciesStatement.template range(); - - auto insert = [&](ImportDependency dependency) { - insertImportDependencyStatement.write(&dependency.id, &dependency.dependencyId); - }; - - auto update = [](ImportDependency, ImportDependency) {}; - - auto remove = [&](ImportDependency dependency) { - deleteImportDependencyStatement.write(&dependency.id, &dependency.dependencyId); - }; - - Sqlite::insertUpdateDelete(range, importDependecies, compareKey, insert, update, remove); - } - - ImportId fetchImportId(const Storage::Import &import) const - { - if (import.version) { - return selectImportIdByNameAndVersionStatement - .template value(import.name, import.version.version); - } - - return selectImportIdByNameStatement.template value(import.name); - } - class AliasPropertyDeclaration { public: @@ -510,6 +358,168 @@ private: return typeName; } + struct ImportDependency + { + ImportDependency(ImportId id, ImportId dependencyId) + : id{id} + , dependencyId{dependencyId} + {} + + ImportDependency(long long id, long long dependencyId) + : id{id} + , dependencyId{dependencyId} + {} + + ImportId id; + ImportId dependencyId; + + friend bool operator<(ImportDependency first, ImportDependency second) + { + return std::tie(first.id, first.dependencyId) < std::tie(second.id, second.dependencyId); + } + + friend bool operator==(ImportDependency first, ImportDependency second) + { + return first.id == second.id && first.dependencyId == second.dependencyId; + } + }; + + void synchronizeTypes(Storage::Types &types, + TypeIds &updatedTypeIds, + std::vector &insertedAliasPropertyDeclarations, + std::vector &updatedAliasPropertyDeclarations) + { + + for (auto &&type : types) { + if (!type.sourceId) + throw TypeHasInvalidSourceId{}; + + updatedTypeIds.push_back(declareType(type)); + } + + for (auto &&type : types) + syncPrototypes(type); + + for (auto &&type : types) + resetRemovedAliasPropertyDeclarationsToNull(type.typeId, type.propertyDeclarations); + + for (auto &&type : types) + syncDeclarations(type, insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations); + } + + void synchronizeImports(Storage::ImportDependencies &imports, TypeIds &deletedTypeIds) + { + if (imports.empty()) + return; + + synchronizeImportsAndUpdatesImportIds(imports, deletedTypeIds); + synchronizeImportDependencies(createSortedImportDependecies(imports)); + } + + void synchronizeDocuments(Storage::Documents &documents) + { + for (auto &&document : documents) + synchronizeDocumentImports(document.sourceId, document.imports); + } + + void synchronizeImportsAndUpdatesImportIds(Storage::ImportDependencies &imports, + TypeIds &deletedTypeIds) + { + auto compareKey = [](auto &&first, auto &&second) { + auto nameCompare = Sqlite::compare(first.name, second.name); + + if (nameCompare != 0) + return nameCompare; + + return first.version.version - second.version.version; + }; + + std::sort(imports.begin(), imports.end(), [&](auto &&first, auto &&second) { + return compareKey(first, second) < 0; + }); + + auto range = selectAllImportsStatement.template range(); + + auto insert = [&](Storage::ImportDependency &import) { + import.importId = insertImportStatement.template value(import.name, + import.version.version, + &import.sourceId); + }; + + auto update = [&](const Storage::ImportView &importView, Storage::ImportDependency &import) { + if (importView.sourceId.id != import.sourceId.id) + updateImportStatement.write(&importView.importId, &import.sourceId); + import.importId = importView.importId; + }; + + auto remove = [&](const Storage::ImportView &importView) { + deleteImportStatement.write(&importView.importId); + selectTypeIdsForImportIdStatement.readTo(deletedTypeIds, &importView.importId); + }; + + Sqlite::insertUpdateDelete(range, imports, compareKey, insert, update, remove); + } + + std::vector createSortedImportDependecies( + const Storage::ImportDependencies &imports) const + { + std::vector importDependecies; + importDependecies.reserve(imports.size() * 5); + + for (const Storage::ImportDependency &import : imports) { + for (const Storage::Import &importDependency : import.importDependencies) { + auto importIdForDependency = fetchImportId(importDependency); + + if (!importIdForDependency) + throw ImportDoesNotExists{}; + + importDependecies.emplace_back(import.importId, importIdForDependency); + } + } + + std::sort(importDependecies.begin(), importDependecies.end()); + importDependecies.erase(std::unique(importDependecies.begin(), importDependecies.end()), + importDependecies.end()); + + return importDependecies; + } + + void synchronizeImportDependencies(const std::vector &importDependecies) + { + auto compareKey = [](ImportDependency first, ImportDependency second) { + auto idCompare = first.id.id - second.id.id; + + if (idCompare != 0) + return idCompare; + + return first.dependencyId.id - second.dependencyId.id; + }; + + auto range = selectAllImportDependenciesStatement.template range(); + + auto insert = [&](ImportDependency dependency) { + insertImportDependencyStatement.write(&dependency.id, &dependency.dependencyId); + }; + + auto update = [](ImportDependency, ImportDependency) {}; + + auto remove = [&](ImportDependency dependency) { + deleteImportDependencyStatement.write(&dependency.id, &dependency.dependencyId); + }; + + Sqlite::insertUpdateDelete(range, importDependecies, compareKey, insert, update, remove); + } + + ImportId fetchImportId(const Storage::Import &import) const + { + if (import.version) { + return selectImportIdByNameAndVersionStatement + .template value(import.name, import.version.version); + } + + return selectImportIdByNameStatement.template value(import.name); + } + void handleAliasPropertyDeclarationsWithPropertyType( TypeId typeId, std::vector &relinkableAliasPropertyDeclarations) { @@ -682,7 +692,9 @@ private: } } - void deleteNotUpdatedTypes(const TypeIds &updatedTypeIds, const SourceIds &sourceIds) + void deleteNotUpdatedTypes(const TypeIds &updatedTypeIds, + const SourceIds &sourceIds, + const TypeIds &deletedTypeIds) { std::vector relinkableAliasPropertyDeclarations; std::vector relinkablePropertyDeclarations; @@ -707,6 +719,8 @@ private: selectNotUpdatedTypesInSourcesStatement.readCallback(callback, Utils::span(sourceIdValues), Utils::span(updatedTypeIdValues)); + for (TypeId deletedTypeId : deletedTypeIds) + callback(&deletedTypeId); relinkPrototypes(relinkablePrototypes); relinkPropertyDeclarations(relinkablePropertyDeclarations); @@ -759,23 +773,6 @@ private: updateAliasPropertyDeclarationValues(updatedAliasPropertyDeclarations); } - void deleteTypesForImportId(ImportId importId) - { - std::vector aliasPropertyDeclarations; - std::vector relinkablePropertyDeclarations; - std::vector relinkablePrototypes; - - auto callback = [&](long long typeId) { - deleteType(TypeId{typeId}, - aliasPropertyDeclarations, - relinkablePropertyDeclarations, - relinkablePrototypes); - return Sqlite::CallbackControl::Continue; - }; - - selectTypeIdsForImportIdStatement.readCallback(callback, &importId); - } - void upsertExportedType(ImportId importId, Utils::SmallStringView name, TypeId typeId) { upsertTypeNamesStatement.write(&importId,