aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmldesigner/designercore
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qmldesigner/designercore')
-rw-r--r--src/plugins/qmldesigner/designercore/include/modelfwd.h2
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/filesystem.h6
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp3774
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h3777
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h1
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h2
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h3
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h2
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h7
-rw-r--r--src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h2
10 files changed, 3966 insertions, 3610 deletions
diff --git a/src/plugins/qmldesigner/designercore/include/modelfwd.h b/src/plugins/qmldesigner/designercore/include/modelfwd.h
index 0a062289fd..91c533fe7b 100644
--- a/src/plugins/qmldesigner/designercore/include/modelfwd.h
+++ b/src/plugins/qmldesigner/designercore/include/modelfwd.h
@@ -77,7 +77,7 @@ constexpr bool useProjectStorage()
using ProjectStorageType = ProjectStorageInterface;
using PathCacheType = SourcePathCacheInterface;
#else
-using ProjectStorageType = ProjectStorage<Sqlite::Database>;
+using ProjectStorageType = ProjectStorage;
using PathCacheType = SourcePathCache<ProjectStorageType, NonLockingMutex>;
#endif
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h b/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h
index 078fd1ee98..28754a8560 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h
@@ -6,6 +6,7 @@
#include "filestatuscache.h"
#include "filesysteminterface.h"
#include "nonlockingmutex.h"
+#include "projectstoragefwd.h"
namespace Sqlite {
class Database;
@@ -16,12 +17,9 @@ namespace QmlDesigner {
template<typename ProjectStorage, typename Mutex>
class SourcePathCache;
-template<typename Database>
-class ProjectStorage;
-
class FileSystem : public FileSystemInterface
{
- using PathCache = SourcePathCache<ProjectStorage<Sqlite::Database>, NonLockingMutex>;
+ using PathCache = SourcePathCache<ProjectStorage, NonLockingMutex>;
public:
FileSystem(PathCache &sourcePathCache)
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp
index 2bef2244d7..a037ddae9a 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp
@@ -5,4 +5,3776 @@
#include <sqlitedatabase.h>
-template class QmlDesigner::ProjectStorage<Sqlite::Database>;
+namespace QmlDesigner {
+
+class ProjectStorage::Initializer
+{
+public:
+ Initializer(Database &database, bool isInitialized)
+ {
+ if (!isInitialized) {
+ auto moduleIdColumn = createModulesTable(database);
+ createSourceContextsTable(database);
+ createSourcesTable(database);
+ createTypesAndePropertyDeclarationsTables(database, moduleIdColumn);
+ createExportedTypeNamesTable(database, moduleIdColumn);
+ createImportedTypeNamesTable(database);
+ createEnumerationsTable(database);
+ createFunctionsTable(database);
+ createSignalsTable(database);
+ createModuleExportedImportsTable(database, moduleIdColumn);
+ createDocumentImportsTable(database, moduleIdColumn);
+ createFileStatusesTable(database);
+ createProjectDatasTable(database);
+ createPropertyEditorPathsTable(database);
+ createTypeAnnotionsTable(database);
+ }
+ database.setIsInitialized(true);
+ }
+
+ void createSourceContextsTable(Database &database)
+ {
+ Sqlite::Table table;
+ table.setUseIfNotExists(true);
+ table.setName("sourceContexts");
+ table.addColumn("sourceContextId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
+ const Sqlite::Column &sourceContextPathColumn = table.addColumn("sourceContextPath");
+
+ table.addUniqueIndex({sourceContextPathColumn});
+
+ table.initialize(database);
+ }
+
+ void createSourcesTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("sources");
+ table.addColumn("sourceId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}});
+ const auto &sourceContextIdColumn = table.addColumn(
+ "sourceContextId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::NotNull{},
+ Sqlite::ForeignKey{"sourceContexts",
+ "sourceContextId",
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Cascade}});
+ const auto &sourceNameColumn = table.addColumn("sourceName", Sqlite::StrictColumnType::Text);
+ table.addUniqueIndex({sourceContextIdColumn, sourceNameColumn});
+
+ table.initialize(database);
+ }
+
+ void createTypesAndePropertyDeclarationsTables(
+ Database &database, [[maybe_unused]] const Sqlite::StrictColumn &foreignModuleIdColumn)
+ {
+ Sqlite::StrictTable typesTable;
+ typesTable.setUseIfNotExists(true);
+ typesTable.setName("types");
+ typesTable.addColumn("typeId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}});
+ auto &sourceIdColumn = typesTable.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
+ auto &typesNameColumn = typesTable.addColumn("name", Sqlite::StrictColumnType::Text);
+ typesTable.addColumn("traits", Sqlite::StrictColumnType::Integer);
+ auto &prototypeIdColumn = typesTable.addForeignKeyColumn("prototypeId",
+ typesTable,
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Restrict);
+ typesTable.addColumn("prototypeNameId", Sqlite::StrictColumnType::Integer);
+ auto &extensionIdColumn = typesTable.addForeignKeyColumn("extensionId",
+ typesTable,
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Restrict);
+ typesTable.addColumn("extensionNameId", Sqlite::StrictColumnType::Integer);
+ auto &defaultPropertyIdColumn = typesTable.addColumn("defaultPropertyId",
+ Sqlite::StrictColumnType::Integer);
+ typesTable.addColumn("annotationTraits", Sqlite::StrictColumnType::Integer);
+ typesTable.addUniqueIndex({sourceIdColumn, typesNameColumn});
+ typesTable.addIndex({defaultPropertyIdColumn});
+ typesTable.addIndex({prototypeIdColumn});
+ typesTable.addIndex({extensionIdColumn});
+
+ typesTable.initialize(database);
+
+ {
+ Sqlite::StrictTable propertyDeclarationTable;
+ propertyDeclarationTable.setUseIfNotExists(true);
+ propertyDeclarationTable.setName("propertyDeclarations");
+ propertyDeclarationTable.addColumn("propertyDeclarationId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{}});
+ auto &typeIdColumn = propertyDeclarationTable.addColumn("typeId");
+ auto &nameColumn = propertyDeclarationTable.addColumn("name");
+ auto &propertyTypeIdColumn = propertyDeclarationTable.addForeignKeyColumn(
+ "propertyTypeId",
+ typesTable,
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Restrict);
+ propertyDeclarationTable.addColumn("propertyTraits", Sqlite::StrictColumnType::Integer);
+ propertyDeclarationTable.addColumn("propertyImportedTypeNameId",
+ Sqlite::StrictColumnType::Integer);
+ auto &aliasPropertyDeclarationIdColumn = propertyDeclarationTable.addForeignKeyColumn(
+ "aliasPropertyDeclarationId",
+ propertyDeclarationTable,
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Restrict);
+ auto &aliasPropertyDeclarationTailIdColumn = propertyDeclarationTable.addForeignKeyColumn(
+ "aliasPropertyDeclarationTailId",
+ propertyDeclarationTable,
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Restrict);
+
+ propertyDeclarationTable.addUniqueIndex({typeIdColumn, nameColumn});
+ propertyDeclarationTable.addIndex({propertyTypeIdColumn});
+ propertyDeclarationTable.addIndex({aliasPropertyDeclarationIdColumn},
+ "aliasPropertyDeclarationId IS NOT NULL");
+ propertyDeclarationTable.addIndex({aliasPropertyDeclarationTailIdColumn},
+ "aliasPropertyDeclarationTailId IS NOT NULL");
+
+ propertyDeclarationTable.initialize(database);
+ }
+ }
+
+ void createExportedTypeNamesTable(Database &database,
+ const Sqlite::StrictColumn &foreignModuleIdColumn)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("exportedTypeNames");
+ table.addColumn("exportedTypeNameId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{}});
+ auto &moduleIdColumn = table.addForeignKeyColumn("moduleId",
+ foreignModuleIdColumn,
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::NoAction);
+ auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
+ auto &typeIdColumn = table.addColumn("typeId", Sqlite::StrictColumnType::Integer);
+ auto &majorVersionColumn = table.addColumn("majorVersion", Sqlite::StrictColumnType::Integer);
+ auto &minorVersionColumn = table.addColumn("minorVersion", Sqlite::StrictColumnType::Integer);
+
+ table.addUniqueIndex({moduleIdColumn, nameColumn},
+ "majorVersion IS NULL AND minorVersion IS NULL");
+ table.addUniqueIndex({moduleIdColumn, nameColumn, majorVersionColumn},
+ "majorVersion IS NOT NULL AND minorVersion IS NULL");
+ table.addUniqueIndex({moduleIdColumn, nameColumn, majorVersionColumn, minorVersionColumn},
+ "majorVersion IS NOT NULL AND minorVersion IS NOT NULL");
+
+ table.addIndex({typeIdColumn});
+ table.addIndex({moduleIdColumn, nameColumn});
+
+ table.initialize(database);
+ }
+
+ void createImportedTypeNamesTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("importedTypeNames");
+ table.addColumn("importedTypeNameId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{}});
+ auto &importOrSourceIdColumn = table.addColumn("importOrSourceId");
+ auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
+ auto &kindColumn = table.addColumn("kind", Sqlite::StrictColumnType::Integer);
+
+ table.addUniqueIndex({kindColumn, importOrSourceIdColumn, nameColumn});
+ table.addIndex({nameColumn});
+
+ table.initialize(database);
+ }
+
+ void createEnumerationsTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("enumerationDeclarations");
+ table.addColumn("enumerationDeclarationId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{}});
+ auto &typeIdColumn = table.addColumn("typeId", Sqlite::StrictColumnType::Integer);
+ auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
+ table.addColumn("enumeratorDeclarations", Sqlite::StrictColumnType::Text);
+
+ table.addUniqueIndex({typeIdColumn, nameColumn});
+
+ table.initialize(database);
+ }
+
+ void createFunctionsTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("functionDeclarations");
+ table.addColumn("functionDeclarationId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{}});
+ auto &typeIdColumn = table.addColumn("typeId", Sqlite::StrictColumnType::Integer);
+ auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
+ auto &signatureColumn = table.addColumn("signature", Sqlite::StrictColumnType::Text);
+ table.addColumn("returnTypeName");
+
+ table.addUniqueIndex({typeIdColumn, nameColumn, signatureColumn});
+
+ table.initialize(database);
+ }
+
+ void createSignalsTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("signalDeclarations");
+ table.addColumn("signalDeclarationId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{}});
+ auto &typeIdColumn = table.addColumn("typeId", Sqlite::StrictColumnType::Integer);
+ auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
+ auto &signatureColumn = table.addColumn("signature", Sqlite::StrictColumnType::Text);
+
+ table.addUniqueIndex({typeIdColumn, nameColumn, signatureColumn});
+
+ table.initialize(database);
+ }
+
+ Sqlite::StrictColumn createModulesTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("modules");
+ auto &modelIdColumn = table.addColumn("moduleId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{}});
+ auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
+
+ table.addUniqueIndex({nameColumn});
+
+ table.initialize(database);
+
+ return std::move(modelIdColumn);
+ }
+
+ void createModuleExportedImportsTable(Database &database,
+ const Sqlite::StrictColumn &foreignModuleIdColumn)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("moduleExportedImports");
+ table.addColumn("moduleExportedImportId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{}});
+ auto &moduleIdColumn = table.addForeignKeyColumn("moduleId",
+ foreignModuleIdColumn,
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Cascade,
+ Sqlite::Enforment::Immediate);
+ auto &sourceIdColumn = table.addColumn("exportedModuleId", Sqlite::StrictColumnType::Integer);
+ table.addColumn("isAutoVersion", Sqlite::StrictColumnType::Integer);
+ table.addColumn("majorVersion", Sqlite::StrictColumnType::Integer);
+ table.addColumn("minorVersion", Sqlite::StrictColumnType::Integer);
+
+ table.addUniqueIndex({sourceIdColumn, moduleIdColumn});
+
+ table.initialize(database);
+ }
+
+ void createDocumentImportsTable(Database &database,
+ const Sqlite::StrictColumn &foreignModuleIdColumn)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("documentImports");
+ table.addColumn("importId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}});
+ auto &sourceIdColumn = table.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
+ auto &moduleIdColumn = table.addForeignKeyColumn("moduleId",
+ foreignModuleIdColumn,
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Cascade,
+ Sqlite::Enforment::Immediate);
+ auto &sourceModuleIdColumn = table.addForeignKeyColumn("sourceModuleId",
+ foreignModuleIdColumn,
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Cascade,
+ Sqlite::Enforment::Immediate);
+ auto &kindColumn = table.addColumn("kind", Sqlite::StrictColumnType::Integer);
+ auto &majorVersionColumn = table.addColumn("majorVersion", Sqlite::StrictColumnType::Integer);
+ auto &minorVersionColumn = table.addColumn("minorVersion", Sqlite::StrictColumnType::Integer);
+ auto &parentImportIdColumn = table.addColumn("parentImportId",
+ Sqlite::StrictColumnType::Integer);
+
+ table.addUniqueIndex(
+ {sourceIdColumn, moduleIdColumn, kindColumn, sourceModuleIdColumn, parentImportIdColumn},
+ "majorVersion IS NULL AND minorVersion IS NULL");
+ table.addUniqueIndex({sourceIdColumn,
+ moduleIdColumn,
+ kindColumn,
+ sourceModuleIdColumn,
+ majorVersionColumn,
+ parentImportIdColumn},
+ "majorVersion IS NOT NULL AND minorVersion IS NULL");
+ table.addUniqueIndex({sourceIdColumn,
+ moduleIdColumn,
+ kindColumn,
+ sourceModuleIdColumn,
+ majorVersionColumn,
+ minorVersionColumn,
+ parentImportIdColumn},
+ "majorVersion IS NOT NULL AND minorVersion IS NOT NULL");
+
+ table.addIndex({sourceIdColumn, kindColumn});
+
+ table.initialize(database);
+ }
+
+ void createFileStatusesTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setName("fileStatuses");
+ table.addColumn("sourceId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{},
+ Sqlite::ForeignKey{"sources",
+ "sourceId",
+ Sqlite::ForeignKeyAction::NoAction,
+ Sqlite::ForeignKeyAction::Cascade}});
+ table.addColumn("size", Sqlite::StrictColumnType::Integer);
+ table.addColumn("lastModified", Sqlite::StrictColumnType::Integer);
+
+ table.initialize(database);
+ }
+
+ void createProjectDatasTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setUseWithoutRowId(true);
+ table.setName("projectDatas");
+ auto &projectSourceIdColumn = table.addColumn("projectSourceId",
+ Sqlite::StrictColumnType::Integer);
+ auto &sourceIdColumn = table.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
+ table.addColumn("moduleId", Sqlite::StrictColumnType::Integer);
+ table.addColumn("fileType", Sqlite::StrictColumnType::Integer);
+
+ table.addPrimaryKeyContraint({projectSourceIdColumn, sourceIdColumn});
+ table.addUniqueIndex({sourceIdColumn});
+
+ table.initialize(database);
+ }
+
+ void createPropertyEditorPathsTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setUseWithoutRowId(true);
+ table.setName("propertyEditorPaths");
+ table.addColumn("typeId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}});
+ table.addColumn("pathSourceId", Sqlite::StrictColumnType::Integer);
+ auto &directoryIdColumn = table.addColumn("directoryId", Sqlite::StrictColumnType::Integer);
+
+ table.addIndex({directoryIdColumn});
+
+ table.initialize(database);
+ }
+
+ void createTypeAnnotionsTable(Database &database)
+ {
+ Sqlite::StrictTable table;
+ table.setUseIfNotExists(true);
+ table.setUseWithoutRowId(true);
+ table.setName("typeAnnotations");
+ auto &typeIdColumn = table.addColumn("typeId",
+ Sqlite::StrictColumnType::Integer,
+ {Sqlite::PrimaryKey{}});
+ auto &sourceIdColumn = table.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
+ auto &directorySourceIdColumn = table.addColumn("directorySourceId",
+ Sqlite::StrictColumnType::Integer);
+
+ table.addColumn("iconPath", Sqlite::StrictColumnType::Text);
+ table.addColumn("itemLibrary", Sqlite::StrictColumnType::Text);
+ table.addColumn("hints", Sqlite::StrictColumnType::Text);
+
+ table.addUniqueIndex({sourceIdColumn, typeIdColumn});
+ table.addIndex({directorySourceIdColumn});
+
+ table.initialize(database);
+ }
+};
+
+ProjectStorage::ProjectStorage(Database &database, bool isInitialized)
+ : database{database}
+ , exclusiveTransaction{database}
+ , initializer{std::make_unique<ProjectStorage::Initializer>(database, isInitialized)}
+ , moduleCache{ModuleStorageAdapter{*this}}
+{
+ NanotraceHR::Tracer tracer{"initialize"_t, projectStorageCategory()};
+
+ exclusiveTransaction.commit();
+
+ database.walCheckpointFull();
+
+ moduleCache.populate();
+}
+
+ProjectStorage::~ProjectStorage() = default;
+
+void ProjectStorage::synchronize(Storage::Synchronization::SynchronizationPackage package)
+{
+ NanotraceHR::Tracer tracer{"synchronize"_t, projectStorageCategory()};
+
+ TypeIds deletedTypeIds;
+ Sqlite::withImmediateTransaction(database, [&] {
+ AliasPropertyDeclarations insertedAliasPropertyDeclarations;
+ AliasPropertyDeclarations updatedAliasPropertyDeclarations;
+
+ AliasPropertyDeclarations relinkableAliasPropertyDeclarations;
+ PropertyDeclarations relinkablePropertyDeclarations;
+ Prototypes relinkablePrototypes;
+ Prototypes relinkableExtensions;
+
+ TypeIds updatedTypeIds;
+ updatedTypeIds.reserve(package.types.size());
+
+ TypeIds typeIdsToBeDeleted;
+
+ std::sort(package.updatedSourceIds.begin(), package.updatedSourceIds.end());
+
+ synchronizeFileStatuses(package.fileStatuses, package.updatedFileStatusSourceIds);
+ synchronizeImports(package.imports,
+ package.updatedSourceIds,
+ package.moduleDependencies,
+ package.updatedModuleDependencySourceIds,
+ package.moduleExportedImports,
+ package.updatedModuleIds);
+ synchronizeTypes(package.types,
+ updatedTypeIds,
+ insertedAliasPropertyDeclarations,
+ updatedAliasPropertyDeclarations,
+ relinkableAliasPropertyDeclarations,
+ relinkablePropertyDeclarations,
+ relinkablePrototypes,
+ relinkableExtensions,
+ package.updatedSourceIds);
+ synchronizeTypeAnnotations(package.typeAnnotations, package.updatedTypeAnnotationSourceIds);
+ synchronizePropertyEditorQmlPaths(package.propertyEditorQmlPaths,
+ package.updatedPropertyEditorQmlPathSourceIds);
+
+ deleteNotUpdatedTypes(updatedTypeIds,
+ package.updatedSourceIds,
+ typeIdsToBeDeleted,
+ relinkableAliasPropertyDeclarations,
+ relinkablePropertyDeclarations,
+ relinkablePrototypes,
+ relinkableExtensions,
+ deletedTypeIds);
+
+ relink(relinkableAliasPropertyDeclarations,
+ relinkablePropertyDeclarations,
+ relinkablePrototypes,
+ relinkableExtensions,
+ deletedTypeIds);
+
+ linkAliases(insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations);
+
+ synchronizeProjectDatas(package.projectDatas, package.updatedProjectSourceIds);
+
+ commonTypeCache_.resetTypeIds();
+ });
+
+ callRefreshMetaInfoCallback(deletedTypeIds);
+}
+
+void ProjectStorage::synchronizeDocumentImports(Storage::Imports imports, SourceId sourceId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"synchronize document imports"_t,
+ projectStorageCategory(),
+ keyValue("imports", imports),
+ keyValue("source id", sourceId)};
+
+ Sqlite::withImmediateTransaction(database, [&] {
+ synchronizeDocumentImports(imports, {sourceId}, Storage::Synchronization::ImportKind::Import);
+ });
+}
+
+void ProjectStorage::addObserver(ProjectStorageObserver *observer)
+{
+ NanotraceHR::Tracer tracer{"add observer"_t, projectStorageCategory()};
+ observers.push_back(observer);
+}
+
+void ProjectStorage::removeObserver(ProjectStorageObserver *observer)
+{
+ NanotraceHR::Tracer tracer{"remove observer"_t, projectStorageCategory()};
+ observers.removeOne(observer);
+}
+
+ModuleId ProjectStorage::moduleId(Utils::SmallStringView moduleName) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get module id"_t,
+ projectStorageCategory(),
+ keyValue("module name", moduleName)};
+
+ auto moduleId = moduleCache.id(moduleName);
+
+ tracer.end(keyValue("module id", moduleId));
+
+ return moduleId;
+}
+
+Utils::SmallString ProjectStorage::moduleName(ModuleId moduleId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get module name"_t,
+ projectStorageCategory(),
+ keyValue("module id", moduleId)};
+
+ if (!moduleId)
+ throw ModuleDoesNotExists{};
+
+ auto moduleName = moduleCache.value(moduleId);
+
+ tracer.end(keyValue("module name", moduleName));
+
+ return moduleName;
+}
+
+TypeId ProjectStorage::typeId(ModuleId moduleId,
+ Utils::SmallStringView exportedTypeName,
+ Storage::Version version) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type id by exported name"_t,
+ projectStorageCategory(),
+ keyValue("module id", moduleId),
+ keyValue("exported type name", exportedTypeName),
+ keyValue("version", version)};
+
+ TypeId typeId;
+
+ if (version.minor) {
+ typeId = selectTypeIdByModuleIdAndExportedNameAndVersionStatement.valueWithTransaction<TypeId>(
+ moduleId, exportedTypeName, version.major.value, version.minor.value);
+
+ } else if (version.major) {
+ typeId = selectTypeIdByModuleIdAndExportedNameAndMajorVersionStatement
+ .valueWithTransaction<TypeId>(moduleId, exportedTypeName, version.major.value);
+
+ } else {
+ typeId = selectTypeIdByModuleIdAndExportedNameStatement
+ .valueWithTransaction<TypeId>(moduleId, exportedTypeName);
+ }
+
+ tracer.end(keyValue("type id", typeId));
+
+ return typeId;
+}
+
+TypeId ProjectStorage::typeId(ImportedTypeNameId typeNameId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type id by imported type name"_t,
+ projectStorageCategory(),
+ keyValue("imported type name id", typeNameId)};
+
+ auto typeId = Sqlite::withDeferredTransaction(database, [&] { return fetchTypeId(typeNameId); });
+
+ tracer.end(keyValue("type id", typeId));
+
+ return typeId;
+}
+
+QVarLengthArray<TypeId, 256> ProjectStorage::typeIds(ModuleId moduleId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type ids by module id"_t,
+ projectStorageCategory(),
+ keyValue("module id", moduleId)};
+
+ auto typeIds = selectTypeIdsByModuleIdStatement.valuesWithTransaction<QVarLengthArray<TypeId, 256>>(
+ moduleId);
+
+ tracer.end(keyValue("type ids", typeIds));
+
+ return typeIds;
+}
+
+Storage::Info::ExportedTypeNames ProjectStorage::exportedTypeNames(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get exported type names by type id"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto exportedTypenames = selectExportedTypesByTypeIdStatement
+ .valuesWithTransaction<Storage::Info::ExportedTypeName, 4>(typeId);
+
+ tracer.end(keyValue("exported type names", exportedTypenames));
+
+ return exportedTypenames;
+}
+
+Storage::Info::ExportedTypeNames ProjectStorage::exportedTypeNames(TypeId typeId, SourceId sourceId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get exported type names by source id"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId),
+ keyValue("source id", sourceId)};
+
+ auto exportedTypenames = selectExportedTypesByTypeIdAndSourceIdStatement
+ .valuesWithTransaction<Storage::Info::ExportedTypeName, 4>(typeId,
+ sourceId);
+
+ tracer.end(keyValue("exported type names", exportedTypenames));
+
+ return exportedTypenames;
+}
+
+ImportId ProjectStorage::importId(const Storage::Import &import) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get import id by import"_t,
+ projectStorageCategory(),
+ keyValue("import", import)};
+
+ auto importId = Sqlite::withDeferredTransaction(database, [&] {
+ return fetchImportId(import.sourceId, import);
+ });
+
+ tracer.end(keyValue("import id", importId));
+
+ return importId;
+}
+
+ImportedTypeNameId ProjectStorage::importedTypeNameId(ImportId importId,
+ Utils::SmallStringView typeName)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get imported type name id by import id"_t,
+ projectStorageCategory(),
+ keyValue("import id", importId),
+ keyValue("imported type name", typeName)};
+
+ auto importedTypeNameId = Sqlite::withDeferredTransaction(database, [&] {
+ return fetchImportedTypeNameId(Storage::Synchronization::TypeNameKind::QualifiedExported,
+ importId,
+ typeName);
+ });
+
+ tracer.end(keyValue("imported type name id", importedTypeNameId));
+
+ return importedTypeNameId;
+}
+
+ImportedTypeNameId ProjectStorage::importedTypeNameId(SourceId sourceId,
+ Utils::SmallStringView typeName)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get imported type name id by source id"_t,
+ projectStorageCategory(),
+ keyValue("source id", sourceId),
+ keyValue("imported type name", typeName)};
+
+ auto importedTypeNameId = Sqlite::withDeferredTransaction(database, [&] {
+ return fetchImportedTypeNameId(Storage::Synchronization::TypeNameKind::Exported,
+ sourceId,
+ typeName);
+ });
+
+ tracer.end(keyValue("imported type name id", importedTypeNameId));
+
+ return importedTypeNameId;
+}
+
+QVarLengthArray<PropertyDeclarationId, 128> ProjectStorage::propertyDeclarationIds(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get property declaration ids"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto propertyDeclarationIds = Sqlite::withDeferredTransaction(database, [&] {
+ return fetchPropertyDeclarationIds(typeId);
+ });
+
+ std::sort(propertyDeclarationIds.begin(), propertyDeclarationIds.end());
+
+ tracer.end(keyValue("property declaration ids", propertyDeclarationIds));
+
+ return propertyDeclarationIds;
+}
+
+QVarLengthArray<PropertyDeclarationId, 128> ProjectStorage::localPropertyDeclarationIds(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get local property declaration ids"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto propertyDeclarationIds = selectLocalPropertyDeclarationIdsForTypeStatement
+ .valuesWithTransaction<QVarLengthArray<PropertyDeclarationId, 128>>(
+ typeId);
+
+ tracer.end(keyValue("property declaration ids", propertyDeclarationIds));
+
+ return propertyDeclarationIds;
+}
+
+PropertyDeclarationId ProjectStorage::propertyDeclarationId(TypeId typeId,
+ Utils::SmallStringView propertyName) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get property declaration id"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId),
+ keyValue("property name", propertyName)};
+
+ auto propertyDeclarationId = Sqlite::withDeferredTransaction(database, [&] {
+ return fetchPropertyDeclarationId(typeId, propertyName);
+ });
+
+ tracer.end(keyValue("property declaration id", propertyDeclarationId));
+
+ return propertyDeclarationId;
+}
+
+PropertyDeclarationId ProjectStorage::localPropertyDeclarationId(TypeId typeId,
+ Utils::SmallStringView propertyName) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get local property declaration id"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId),
+ keyValue("property name", propertyName)};
+
+ auto propertyDeclarationId = selectLocalPropertyDeclarationIdForTypeAndPropertyNameStatement
+ .valueWithTransaction<PropertyDeclarationId>(typeId,
+ propertyName);
+
+ tracer.end(keyValue("property declaration id", propertyDeclarationId));
+
+ return propertyDeclarationId;
+}
+
+PropertyDeclarationId ProjectStorage::defaultPropertyDeclarationId(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get default property declaration id"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto propertyDeclarationId = Sqlite::withDeferredTransaction(database, [&] {
+ return fetchDefaultPropertyDeclarationId(typeId);
+ });
+
+ tracer.end(keyValue("property declaration id", propertyDeclarationId));
+
+ return propertyDeclarationId;
+}
+
+std::optional<Storage::Info::PropertyDeclaration> ProjectStorage::propertyDeclaration(
+ PropertyDeclarationId propertyDeclarationId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get property declaration"_t,
+ projectStorageCategory(),
+ keyValue("property declaration id", propertyDeclarationId)};
+
+ auto propertyDeclaration = selectPropertyDeclarationForPropertyDeclarationIdStatement
+ .optionalValueWithTransaction<Storage::Info::PropertyDeclaration>(
+ propertyDeclarationId);
+
+ tracer.end(keyValue("property declaration", propertyDeclaration));
+
+ return propertyDeclaration;
+}
+
+std::optional<Storage::Info::Type> ProjectStorage::type(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type"_t, projectStorageCategory(), keyValue("type id", typeId)};
+
+ auto type = selectInfoTypeByTypeIdStatement.optionalValueWithTransaction<Storage::Info::Type>(
+ typeId);
+
+ tracer.end(keyValue("type", type));
+
+ return type;
+}
+
+Utils::PathString ProjectStorage::typeIconPath(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type icon path"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto typeIconPath = selectTypeIconPathStatement.valueWithTransaction<Utils::PathString>(typeId);
+
+ tracer.end(keyValue("type icon path", typeIconPath));
+
+ return typeIconPath;
+}
+
+Storage::Info::TypeHints ProjectStorage::typeHints(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type hints"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto typeHints = selectTypeHintsStatement.valuesWithTransaction<Storage::Info::TypeHints, 4>(
+ typeId);
+
+ tracer.end(keyValue("type hints", typeHints));
+
+ return typeHints;
+}
+
+SmallSourceIds<4> ProjectStorage::typeAnnotationSourceIds(SourceId directoryId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type annotaion source ids"_t,
+ projectStorageCategory(),
+ keyValue("source id", directoryId)};
+
+ auto sourceIds = selectTypeAnnotationSourceIdsStatement.valuesWithTransaction<SmallSourceIds<4>>(
+ directoryId);
+
+ tracer.end(keyValue("source ids", sourceIds));
+
+ return sourceIds;
+}
+
+SmallSourceIds<64> ProjectStorage::typeAnnotationDirectorySourceIds() const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get type annotaion source ids"_t, projectStorageCategory()};
+
+ auto sourceIds = selectTypeAnnotationDirectorySourceIdsStatement
+ .valuesWithTransaction<SmallSourceIds<64>>();
+
+ tracer.end(keyValue("source ids", sourceIds));
+
+ return sourceIds;
+}
+
+Storage::Info::ItemLibraryEntries ProjectStorage::itemLibraryEntries(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get item library entries by type id"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ using Storage::Info::ItemLibraryProperties;
+ Storage::Info::ItemLibraryEntries entries;
+
+ auto callback = [&](TypeId typeId_,
+ Utils::SmallStringView name,
+ Utils::SmallStringView iconPath,
+ Utils::SmallStringView category,
+ Utils::SmallStringView import,
+ Utils::SmallStringView toolTip,
+ Utils::SmallStringView properties,
+ Utils::SmallStringView extraFilePaths,
+ Utils::SmallStringView templatePath) {
+ auto &last = entries.emplace_back(typeId_, name, iconPath, category, import, toolTip, templatePath);
+ if (properties.size())
+ selectItemLibraryPropertiesStatement.readTo(last.properties, properties);
+ if (extraFilePaths.size())
+ selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths);
+ };
+
+ selectItemLibraryEntriesByTypeIdStatement.readCallbackWithTransaction(callback, typeId);
+
+ tracer.end(keyValue("item library entries", entries));
+
+ return entries;
+}
+
+Storage::Info::ItemLibraryEntries ProjectStorage::itemLibraryEntries(ImportId importId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get item library entries by import id"_t,
+ projectStorageCategory(),
+ keyValue("import id", importId)};
+
+ using Storage::Info::ItemLibraryProperties;
+ Storage::Info::ItemLibraryEntries entries;
+
+ auto callback = [&](TypeId typeId_,
+ Utils::SmallStringView name,
+ Utils::SmallStringView iconPath,
+ Utils::SmallStringView category,
+ Utils::SmallStringView import,
+ Utils::SmallStringView toolTip,
+ Utils::SmallStringView properties,
+ Utils::SmallStringView extraFilePaths,
+ Utils::SmallStringView templatePath) {
+ auto &last = entries.emplace_back(typeId_, name, iconPath, category, import, toolTip, templatePath);
+ if (properties.size())
+ selectItemLibraryPropertiesStatement.readTo(last.properties, properties);
+ if (extraFilePaths.size())
+ selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths);
+ };
+
+ selectItemLibraryEntriesByTypeIdStatement.readCallbackWithTransaction(callback, importId);
+
+ tracer.end(keyValue("item library entries", entries));
+
+ return entries;
+}
+
+Storage::Info::ItemLibraryEntries ProjectStorage::itemLibraryEntries(SourceId sourceId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get item library entries by source id"_t,
+ projectStorageCategory(),
+ keyValue("source id", sourceId)};
+
+ using Storage::Info::ItemLibraryProperties;
+ Storage::Info::ItemLibraryEntries entries;
+
+ auto callback = [&](TypeId typeId,
+ Utils::SmallStringView name,
+ Utils::SmallStringView iconPath,
+ Utils::SmallStringView category,
+ Utils::SmallStringView import,
+ Utils::SmallStringView toolTip,
+ Utils::SmallStringView properties,
+ Utils::SmallStringView extraFilePaths,
+ Utils::SmallStringView templatePath) {
+ auto &last = entries.emplace_back(typeId, name, iconPath, category, import, toolTip, templatePath);
+ if (properties.size())
+ selectItemLibraryPropertiesStatement.readTo(last.properties, properties);
+ if (extraFilePaths.size())
+ selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths);
+ };
+
+ selectItemLibraryEntriesBySourceIdStatement.readCallbackWithTransaction(callback, sourceId);
+
+ tracer.end(keyValue("item library entries", entries));
+
+ return entries;
+}
+
+Storage::Info::ItemLibraryEntries ProjectStorage::allItemLibraryEntries() const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get all item library entries"_t, projectStorageCategory()};
+
+ using Storage::Info::ItemLibraryProperties;
+ Storage::Info::ItemLibraryEntries entries;
+
+ auto callback = [&](TypeId typeId,
+ Utils::SmallStringView name,
+ Utils::SmallStringView iconPath,
+ Utils::SmallStringView category,
+ Utils::SmallStringView import,
+ Utils::SmallStringView toolTip,
+ Utils::SmallStringView properties,
+ Utils::SmallStringView extraFilePaths,
+ Utils::SmallStringView templatePath) {
+ auto &last = entries.emplace_back(typeId, name, iconPath, category, import, toolTip, templatePath);
+ if (properties.size())
+ selectItemLibraryPropertiesStatement.readTo(last.properties, properties);
+ if (extraFilePaths.size())
+ selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths);
+ };
+
+ selectItemLibraryEntriesStatement.readCallbackWithTransaction(callback);
+
+ tracer.end(keyValue("item library entries", entries));
+
+ return entries;
+}
+
+std::vector<Utils::SmallString> ProjectStorage::signalDeclarationNames(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get signal names"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto signalDeclarationNames = selectSignalDeclarationNamesForTypeStatement
+ .valuesWithTransaction<Utils::SmallString, 32>(typeId);
+
+ tracer.end(keyValue("signal names", signalDeclarationNames));
+
+ return signalDeclarationNames;
+}
+
+std::vector<Utils::SmallString> ProjectStorage::functionDeclarationNames(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get function names"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto functionDeclarationNames = selectFuncionDeclarationNamesForTypeStatement
+ .valuesWithTransaction<Utils::SmallString, 32>(typeId);
+
+ tracer.end(keyValue("function names", functionDeclarationNames));
+
+ return functionDeclarationNames;
+}
+
+std::optional<Utils::SmallString> ProjectStorage::propertyName(
+ PropertyDeclarationId propertyDeclarationId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get property name"_t,
+ projectStorageCategory(),
+ keyValue("property declaration id", propertyDeclarationId)};
+
+ auto propertyName = selectPropertyNameStatement.optionalValueWithTransaction<Utils::SmallString>(
+ propertyDeclarationId);
+
+ tracer.end(keyValue("property name", propertyName));
+
+ return propertyName;
+}
+
+SmallTypeIds<16> ProjectStorage::prototypeIds(TypeId type) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get prototypes"_t, projectStorageCategory(), keyValue("type id", type)};
+
+ auto prototypeIds = selectPrototypeAndExtensionIdsStatement.valuesWithTransaction<SmallTypeIds<16>>(
+ type);
+
+ tracer.end(keyValue("type ids", prototypeIds));
+
+ return prototypeIds;
+}
+
+SmallTypeIds<16> ProjectStorage::prototypeAndSelfIds(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get prototypes and self"_t, projectStorageCategory()};
+
+ SmallTypeIds<16> prototypeAndSelfIds;
+ prototypeAndSelfIds.push_back(typeId);
+
+ selectPrototypeAndExtensionIdsStatement.readToWithTransaction(prototypeAndSelfIds, typeId);
+
+ tracer.end(keyValue("type ids", prototypeAndSelfIds));
+
+ return prototypeAndSelfIds;
+}
+
+SmallTypeIds<64> ProjectStorage::heirIds(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"get heirs"_t, projectStorageCategory()};
+
+ auto heirIds = selectHeirTypeIdsStatement.valuesWithTransaction<SmallTypeIds<64>>(typeId);
+
+ tracer.end(keyValue("type ids", heirIds));
+
+ return heirIds;
+}
+
+bool ProjectStorage::isBasedOn(TypeId) const
+{
+ return false;
+}
+
+bool ProjectStorage::isBasedOn(TypeId typeId, TypeId id1) const
+{
+ return isBasedOn_(typeId, id1);
+}
+
+bool ProjectStorage::isBasedOn(TypeId typeId, TypeId id1, TypeId id2) const
+{
+ return isBasedOn_(typeId, id1, id2);
+}
+
+bool ProjectStorage::isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3) const
+{
+ return isBasedOn_(typeId, id1, id2, id3);
+}
+
+bool ProjectStorage::isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4) const
+{
+ return isBasedOn_(typeId, id1, id2, id3, id4);
+}
+
+bool ProjectStorage::isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4, TypeId id5) const
+{
+ return isBasedOn_(typeId, id1, id2, id3, id4, id5);
+}
+
+bool ProjectStorage::isBasedOn(
+ TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4, TypeId id5, TypeId id6) const
+{
+ return isBasedOn_(typeId, id1, id2, id3, id4, id5, id6);
+}
+
+bool ProjectStorage::isBasedOn(
+ TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4, TypeId id5, TypeId id6, TypeId id7) const
+{
+ return isBasedOn_(typeId, id1, id2, id3, id4, id5, id6, id7);
+}
+
+TypeId ProjectStorage::fetchTypeIdByExportedName(Utils::SmallStringView name) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"is based on"_t,
+ projectStorageCategory(),
+ keyValue("exported type name", name)};
+
+ auto typeId = selectTypeIdByExportedNameStatement.valueWithTransaction<TypeId>(name);
+
+ tracer.end(keyValue("type id", typeId));
+
+ return typeId;
+}
+
+TypeId ProjectStorage::fetchTypeIdByModuleIdsAndExportedName(ModuleIds moduleIds,
+ Utils::SmallStringView name) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch type id by module ids and exported name"_t,
+ projectStorageCategory(),
+ keyValue("module ids", NanotraceHR::array(moduleIds)),
+ keyValue("exported type name", name)};
+ auto typeId = selectTypeIdByModuleIdsAndExportedNameStatement.valueWithTransaction<TypeId>(
+ static_cast<void *>(moduleIds.data()), static_cast<long long>(moduleIds.size()), name);
+
+ tracer.end(keyValue("type id", typeId));
+
+ return typeId;
+}
+
+TypeId ProjectStorage::fetchTypeIdByName(SourceId sourceId, Utils::SmallStringView name)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch type id by name"_t,
+ projectStorageCategory(),
+ keyValue("source id", sourceId),
+ keyValue("internal type name", name)};
+
+ auto typeId = selectTypeIdBySourceIdAndNameStatement.valueWithTransaction<TypeId>(sourceId, name);
+
+ tracer.end(keyValue("type id", typeId));
+
+ return typeId;
+}
+
+Storage::Synchronization::Type ProjectStorage::fetchTypeByTypeId(TypeId typeId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch type by type id"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto type = Sqlite::withDeferredTransaction(database, [&] {
+ auto type = selectTypeByTypeIdStatement.value<Storage::Synchronization::Type>(typeId);
+
+ type.exportedTypes = fetchExportedTypes(typeId);
+ type.propertyDeclarations = fetchPropertyDeclarations(type.typeId);
+ type.functionDeclarations = fetchFunctionDeclarations(type.typeId);
+ type.signalDeclarations = fetchSignalDeclarations(type.typeId);
+ type.enumerationDeclarations = fetchEnumerationDeclarations(type.typeId);
+
+ return type;
+ });
+
+ tracer.end(keyValue("type", type));
+
+ return type;
+}
+
+Storage::Synchronization::Types ProjectStorage::fetchTypes()
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch types"_t, projectStorageCategory()};
+
+ auto types = Sqlite::withDeferredTransaction(database, [&] {
+ auto types = selectTypesStatement.values<Storage::Synchronization::Type, 64>();
+
+ for (Storage::Synchronization::Type &type : types) {
+ type.exportedTypes = fetchExportedTypes(type.typeId);
+ type.propertyDeclarations = fetchPropertyDeclarations(type.typeId);
+ type.functionDeclarations = fetchFunctionDeclarations(type.typeId);
+ type.signalDeclarations = fetchSignalDeclarations(type.typeId);
+ type.enumerationDeclarations = fetchEnumerationDeclarations(type.typeId);
+ }
+
+ return types;
+ });
+
+ tracer.end(keyValue("type", types));
+
+ return types;
+}
+
+SourceContextId ProjectStorage::fetchSourceContextIdUnguarded(Utils::SmallStringView sourceContextPath)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch source context id unguarded"_t, projectStorageCategory()};
+
+ auto sourceContextId = readSourceContextId(sourceContextPath);
+
+ return sourceContextId ? sourceContextId : writeSourceContextId(sourceContextPath);
+}
+
+SourceContextId ProjectStorage::fetchSourceContextId(Utils::SmallStringView sourceContextPath)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch source context id"_t,
+ projectStorageCategory(),
+ keyValue("source context path", sourceContextPath)};
+
+ SourceContextId sourceContextId;
+ try {
+ sourceContextId = Sqlite::withDeferredTransaction(database, [&] {
+ return fetchSourceContextIdUnguarded(sourceContextPath);
+ });
+ } catch (const Sqlite::ConstraintPreventsModification &) {
+ sourceContextId = fetchSourceContextId(sourceContextPath);
+ }
+
+ tracer.end(keyValue("source context id", sourceContextId));
+
+ return sourceContextId;
+}
+
+Utils::PathString ProjectStorage::fetchSourceContextPath(SourceContextId sourceContextId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch source context path"_t,
+ projectStorageCategory(),
+ keyValue("source context id", sourceContextId)};
+
+ auto path = Sqlite::withDeferredTransaction(database, [&] {
+ auto optionalSourceContextPath = selectSourceContextPathFromSourceContextsBySourceContextIdStatement
+ .optionalValue<Utils::PathString>(sourceContextId);
+
+ if (!optionalSourceContextPath)
+ throw SourceContextIdDoesNotExists();
+
+ return std::move(*optionalSourceContextPath);
+ });
+
+ tracer.end(keyValue("source context path", path));
+
+ return path;
+}
+
+Cache::SourceContexts ProjectStorage::fetchAllSourceContexts() const
+{
+ NanotraceHR::Tracer tracer{"fetch all source contexts"_t, projectStorageCategory()};
+
+ return selectAllSourceContextsStatement.valuesWithTransaction<Cache::SourceContext, 128>();
+}
+
+SourceId ProjectStorage::fetchSourceId(SourceContextId sourceContextId,
+ Utils::SmallStringView sourceName)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch source id"_t,
+ projectStorageCategory(),
+ keyValue("source context id", sourceContextId),
+ keyValue("source name", sourceName)};
+
+ auto sourceId = Sqlite::withDeferredTransaction(database, [&] {
+ return fetchSourceIdUnguarded(sourceContextId, sourceName);
+ });
+
+ tracer.end(keyValue("source id", sourceId));
+
+ return sourceId;
+}
+
+Cache::SourceNameAndSourceContextId ProjectStorage::fetchSourceNameAndSourceContextId(SourceId sourceId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch source name and source context id"_t,
+ projectStorageCategory(),
+ keyValue("source id", sourceId)};
+
+ auto value = selectSourceNameAndSourceContextIdFromSourcesBySourceIdStatement
+ .valueWithTransaction<Cache::SourceNameAndSourceContextId>(sourceId);
+
+ if (!value.sourceContextId)
+ throw SourceIdDoesNotExists();
+
+ tracer.end(keyValue("source name", value.sourceName),
+ keyValue("source context id", value.sourceContextId));
+
+ return value;
+}
+
+void ProjectStorage::clearSources()
+{
+ Sqlite::withImmediateTransaction(database, [&] {
+ deleteAllSourceContextsStatement.execute();
+ deleteAllSourcesStatement.execute();
+ });
+}
+
+SourceContextId ProjectStorage::fetchSourceContextId(SourceId sourceId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch source context id"_t,
+ projectStorageCategory(),
+ keyValue("source id", sourceId)};
+
+ auto sourceContextId = selectSourceContextIdFromSourcesBySourceIdStatement
+ .valueWithTransaction<SourceContextId>(sourceId);
+
+ if (!sourceContextId)
+ throw SourceIdDoesNotExists();
+
+ tracer.end(keyValue("source context id", sourceContextId));
+
+ return sourceContextId;
+}
+
+Cache::Sources ProjectStorage::fetchAllSources() const
+{
+ NanotraceHR::Tracer tracer{"fetch all sources"_t, projectStorageCategory()};
+
+ return selectAllSourcesStatement.valuesWithTransaction<Cache::Source, 1024>();
+}
+
+SourceId ProjectStorage::fetchSourceIdUnguarded(SourceContextId sourceContextId,
+ Utils::SmallStringView sourceName)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch source id unguarded"_t,
+ projectStorageCategory(),
+ keyValue("source context id", sourceContextId),
+ keyValue("source name", sourceName)};
+
+ auto sourceId = readSourceId(sourceContextId, sourceName);
+
+ if (!sourceId)
+ sourceId = writeSourceId(sourceContextId, sourceName);
+
+ tracer.end(keyValue("source id", sourceId));
+
+ return sourceId;
+}
+
+FileStatus ProjectStorage::fetchFileStatus(SourceId sourceId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch file status"_t,
+ projectStorageCategory(),
+ keyValue("source id", sourceId)};
+
+ auto fileStatus = selectFileStatusesForSourceIdStatement.valueWithTransaction<FileStatus>(sourceId);
+
+ tracer.end(keyValue("file status", fileStatus));
+
+ return fileStatus;
+}
+
+std::optional<Storage::Synchronization::ProjectData> ProjectStorage::fetchProjectData(SourceId sourceId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch project data"_t,
+ projectStorageCategory(),
+ keyValue("source id", sourceId)};
+
+ auto projectData = selectProjectDataForSourceIdStatement
+ .optionalValueWithTransaction<Storage::Synchronization::ProjectData>(
+ sourceId);
+
+ tracer.end(keyValue("project data", projectData));
+
+ return projectData;
+}
+
+Storage::Synchronization::ProjectDatas ProjectStorage::fetchProjectDatas(SourceId projectSourceId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch project datas by source id"_t,
+ projectStorageCategory(),
+ keyValue("source id", projectSourceId)};
+
+ auto projectDatas = selectProjectDatasForSourceIdStatement
+ .valuesWithTransaction<Storage::Synchronization::ProjectData, 1024>(
+ projectSourceId);
+
+ tracer.end(keyValue("project datas", projectDatas));
+
+ return projectDatas;
+}
+
+Storage::Synchronization::ProjectDatas ProjectStorage::fetchProjectDatas(
+ const SourceIds &projectSourceIds) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch project datas by source ids"_t,
+ projectStorageCategory(),
+ keyValue("source ids", projectSourceIds)};
+
+ auto projectDatas = selectProjectDatasForSourceIdsStatement
+ .valuesWithTransaction<Storage::Synchronization::ProjectData, 64>(
+ toIntegers(projectSourceIds));
+
+ tracer.end(keyValue("project datas", projectDatas));
+
+ return projectDatas;
+}
+
+void ProjectStorage::setPropertyEditorPathId(TypeId typeId, SourceId pathId)
+{
+ Sqlite::ImmediateSessionTransaction transaction{database};
+
+ upsertPropertyEditorPathIdStatement.write(typeId, pathId);
+
+ transaction.commit();
+}
+
+SourceId ProjectStorage::propertyEditorPathId(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"property editor path id"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto sourceId = selectPropertyEditorPathIdStatement.valueWithTransaction<SourceId>(typeId);
+
+ tracer.end(keyValue("source id", sourceId));
+
+ return sourceId;
+}
+
+Storage::Imports ProjectStorage::fetchDocumentImports() const
+{
+ NanotraceHR::Tracer tracer{"fetch document imports"_t, projectStorageCategory()};
+
+ return selectAllDocumentImportForSourceIdStatement.valuesWithTransaction<Storage::Imports>();
+}
+
+void ProjectStorage::resetForTestsOnly()
+{
+ database.clearAllTablesForTestsOnly();
+ commonTypeCache_.clearForTestsOnly();
+ moduleCache.clearForTestOnly();
+}
+
+bool ProjectStorage::moduleNameLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept
+{
+ return first < second;
+}
+
+ModuleId ProjectStorage::fetchModuleId(Utils::SmallStringView moduleName)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch module id"_t,
+ projectStorageCategory(),
+ keyValue("module name", moduleName)};
+
+ auto moduleId = Sqlite::withDeferredTransaction(database, [&] {
+ return fetchModuleIdUnguarded(moduleName);
+ });
+
+ tracer.end(keyValue("module id", moduleId));
+
+ return moduleId;
+}
+
+Utils::PathString ProjectStorage::fetchModuleName(ModuleId id)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch module name"_t,
+ projectStorageCategory(),
+ keyValue("module id", id)};
+
+ auto moduleName = Sqlite::withDeferredTransaction(database,
+ [&] { return fetchModuleNameUnguarded(id); });
+
+ tracer.end(keyValue("module name", moduleName));
+
+ return moduleName;
+}
+
+ProjectStorage::Modules ProjectStorage::fetchAllModules() const
+{
+ NanotraceHR::Tracer tracer{"fetch all modules"_t, projectStorageCategory()};
+
+ return selectAllModulesStatement.valuesWithTransaction<Module, 128>();
+}
+
+void ProjectStorage::callRefreshMetaInfoCallback(const TypeIds &deletedTypeIds)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"call refresh meta info callback"_t,
+ projectStorageCategory(),
+ keyValue("type ids", deletedTypeIds)};
+
+ if (deletedTypeIds.size()) {
+ for (ProjectStorageObserver *observer : observers)
+ observer->removedTypeIds(deletedTypeIds);
+ }
+}
+
+SourceIds ProjectStorage::filterSourceIdsWithoutType(const SourceIds &updatedSourceIds,
+ SourceIds &sourceIdsOfTypes)
+{
+ std::sort(sourceIdsOfTypes.begin(), sourceIdsOfTypes.end());
+
+ SourceIds sourceIdsWithoutTypeSourceIds;
+ sourceIdsWithoutTypeSourceIds.reserve(updatedSourceIds.size());
+ std::set_difference(updatedSourceIds.begin(),
+ updatedSourceIds.end(),
+ sourceIdsOfTypes.begin(),
+ sourceIdsOfTypes.end(),
+ std::back_inserter(sourceIdsWithoutTypeSourceIds));
+
+ return sourceIdsWithoutTypeSourceIds;
+}
+
+TypeIds ProjectStorage::fetchTypeIds(const SourceIds &sourceIds)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch type ids"_t,
+ projectStorageCategory(),
+ keyValue("source ids", sourceIds)};
+
+ return selectTypeIdsForSourceIdsStatement.values<TypeId, 128>(toIntegers(sourceIds));
+}
+
+void ProjectStorage::unique(SourceIds &sourceIds)
+{
+ std::sort(sourceIds.begin(), sourceIds.end());
+ auto newEnd = std::unique(sourceIds.begin(), sourceIds.end());
+ sourceIds.erase(newEnd, sourceIds.end());
+}
+
+void ProjectStorage::synchronizeTypeTraits(TypeId typeId, Storage::TypeTraits traits)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"synchronize type traits"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId),
+ keyValue("type traits", traits)};
+
+ updateTypeAnnotationTraitStatement.write(typeId, traits.annotation);
+}
+
+void ProjectStorage::updateTypeIdInTypeAnnotations(Storage::Synchronization::TypeAnnotations &typeAnnotations)
+{
+ NanotraceHR::Tracer tracer{"update type id in type annotations"_t, projectStorageCategory()};
+
+ for (auto &annotation : typeAnnotations) {
+ annotation.typeId = fetchTypeIdByModuleIdAndExportedName(annotation.moduleId,
+ annotation.typeName);
+ }
+
+ for (auto &annotation : typeAnnotations) {
+ if (!annotation.typeId)
+ qWarning() << moduleName(annotation.moduleId).toQString()
+ << annotation.typeName.toQString();
+ }
+
+ typeAnnotations.erase(std::remove_if(typeAnnotations.begin(),
+ typeAnnotations.end(),
+ [](const auto &annotation) { return !annotation.typeId; }),
+ typeAnnotations.end());
+}
+
+void ProjectStorage::synchronizeTypeAnnotations(Storage::Synchronization::TypeAnnotations &typeAnnotations,
+ const SourceIds &updatedTypeAnnotationSourceIds)
+{
+ NanotraceHR::Tracer tracer{"synchronize type annotations"_t, projectStorageCategory()};
+
+ using Storage::Synchronization::TypeAnnotation;
+
+ updateTypeIdInTypeAnnotations(typeAnnotations);
+
+ auto compareKey = [](auto &&first, auto &&second) { return first.typeId - second.typeId; };
+
+ std::sort(typeAnnotations.begin(), typeAnnotations.end(), [&](auto &&first, auto &&second) {
+ return first.typeId < second.typeId;
+ });
+
+ auto range = selectTypeAnnotationsForSourceIdsStatement.range<TypeAnnotationView>(
+ toIntegers(updatedTypeAnnotationSourceIds));
+
+ auto insert = [&](const TypeAnnotation &annotation) {
+ if (!annotation.sourceId)
+ throw TypeAnnotationHasInvalidSourceId{};
+
+ synchronizeTypeTraits(annotation.typeId, annotation.traits);
+
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert type annotations"_t,
+ projectStorageCategory(),
+ keyValue("type annotation", annotation)};
+
+ insertTypeAnnotationStatement.write(annotation.typeId,
+ annotation.sourceId,
+ annotation.directorySourceId,
+ annotation.iconPath,
+ createEmptyAsNull(annotation.itemLibraryJson),
+ createEmptyAsNull(annotation.hintsJson));
+ };
+
+ auto update = [&](const TypeAnnotationView &annotationFromDatabase,
+ const TypeAnnotation &annotation) {
+ synchronizeTypeTraits(annotation.typeId, annotation.traits);
+
+ if (annotationFromDatabase.iconPath != annotation.iconPath
+ || annotationFromDatabase.itemLibraryJson != annotation.itemLibraryJson
+ || annotationFromDatabase.hintsJson != annotation.hintsJson) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"update type annotations"_t,
+ projectStorageCategory(),
+ keyValue("type annotation from database",
+ annotationFromDatabase),
+ keyValue("type annotation", annotation)};
+
+ updateTypeAnnotationStatement.write(annotation.typeId,
+ annotation.iconPath,
+ createEmptyAsNull(annotation.itemLibraryJson),
+ createEmptyAsNull(annotation.hintsJson));
+ return Sqlite::UpdateChange::Update;
+ }
+
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const TypeAnnotationView &annotationFromDatabase) {
+ synchronizeTypeTraits(annotationFromDatabase.typeId, Storage::TypeTraits{});
+
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove type annotations"_t,
+ projectStorageCategory(),
+ keyValue("type annotation", annotationFromDatabase)};
+
+ deleteTypeAnnotationStatement.write(annotationFromDatabase.typeId);
+ };
+
+ Sqlite::insertUpdateDelete(range, typeAnnotations, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::synchronizeTypeTrait(const Storage::Synchronization::Type &type)
+{
+ updateTypeTraitStatement.write(type.typeId, type.traits.type);
+}
+
+void ProjectStorage::synchronizeTypes(Storage::Synchronization::Types &types,
+ TypeIds &updatedTypeIds,
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes,
+ Prototypes &relinkableExtensions,
+ const SourceIds &updatedSourceIds)
+{
+ NanotraceHR::Tracer tracer{"synchronize types"_t, projectStorageCategory()};
+
+ Storage::Synchronization::ExportedTypes exportedTypes;
+ exportedTypes.reserve(types.size() * 3);
+ SourceIds sourceIdsOfTypes;
+ sourceIdsOfTypes.reserve(updatedSourceIds.size());
+ SourceIds notUpdatedExportedSourceIds;
+ notUpdatedExportedSourceIds.reserve(updatedSourceIds.size());
+ SourceIds exportedSourceIds;
+ exportedSourceIds.reserve(types.size());
+
+ for (auto &type : types) {
+ if (!type.sourceId)
+ throw TypeHasInvalidSourceId{};
+
+ TypeId typeId = declareType(type);
+ synchronizeTypeTrait(type);
+ sourceIdsOfTypes.push_back(type.sourceId);
+ updatedTypeIds.push_back(typeId);
+ if (type.changeLevel != Storage::Synchronization::ChangeLevel::ExcludeExportedTypes) {
+ exportedSourceIds.push_back(type.sourceId);
+ extractExportedTypes(typeId, type, exportedTypes);
+ }
+ }
+
+ std::sort(types.begin(), types.end(), [](const auto &first, const auto &second) {
+ return first.typeId < second.typeId;
+ });
+
+ unique(exportedSourceIds);
+
+ SourceIds sourceIdsWithoutType = filterSourceIdsWithoutType(updatedSourceIds, sourceIdsOfTypes);
+ exportedSourceIds.insert(exportedSourceIds.end(),
+ sourceIdsWithoutType.begin(),
+ sourceIdsWithoutType.end());
+ TypeIds exportedTypeIds = fetchTypeIds(exportedSourceIds);
+ synchronizeExportedTypes(exportedTypeIds,
+ exportedTypes,
+ relinkableAliasPropertyDeclarations,
+ relinkablePropertyDeclarations,
+ relinkablePrototypes,
+ relinkableExtensions);
+
+ syncPrototypesAndExtensions(types, relinkablePrototypes, relinkableExtensions);
+ resetDefaultPropertiesIfChanged(types);
+ resetRemovedAliasPropertyDeclarationsToNull(types, relinkableAliasPropertyDeclarations);
+ syncDeclarations(types,
+ insertedAliasPropertyDeclarations,
+ updatedAliasPropertyDeclarations,
+ relinkablePropertyDeclarations);
+ syncDefaultProperties(types);
+}
+
+void ProjectStorage::synchronizeProjectDatas(Storage::Synchronization::ProjectDatas &projectDatas,
+ const SourceIds &updatedProjectSourceIds)
+{
+ NanotraceHR::Tracer tracer{"synchronize project datas"_t, projectStorageCategory()};
+
+ auto compareKey = [](auto &&first, auto &&second) {
+ auto projectSourceIdDifference = first.projectSourceId - second.projectSourceId;
+ if (projectSourceIdDifference != 0)
+ return projectSourceIdDifference;
+
+ return first.sourceId - second.sourceId;
+ };
+
+ 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 = selectProjectDatasForSourceIdsStatement.range<Storage::Synchronization::ProjectData>(
+ toIntegers(updatedProjectSourceIds));
+
+ auto insert = [&](const Storage::Synchronization::ProjectData &projectData) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert project data"_t,
+ projectStorageCategory(),
+ keyValue("project data", projectData)};
+
+ if (!projectData.projectSourceId)
+ throw ProjectDataHasInvalidProjectSourceId{};
+ if (!projectData.sourceId)
+ throw ProjectDataHasInvalidSourceId{};
+
+ insertProjectDataStatement.write(projectData.projectSourceId,
+ projectData.sourceId,
+ projectData.moduleId,
+ projectData.fileType);
+ };
+
+ auto update = [&](const Storage::Synchronization::ProjectData &projectDataFromDatabase,
+ const Storage::Synchronization::ProjectData &projectData) {
+ if (projectDataFromDatabase.fileType != projectData.fileType
+ || !compareInvalidAreTrue(projectDataFromDatabase.moduleId, projectData.moduleId)) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"update project data"_t,
+ projectStorageCategory(),
+ keyValue("project data", projectData),
+ keyValue("project data from database", projectDataFromDatabase)};
+
+ updateProjectDataStatement.write(projectData.projectSourceId,
+ projectData.sourceId,
+ projectData.moduleId,
+ projectData.fileType);
+ return Sqlite::UpdateChange::Update;
+ }
+
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const Storage::Synchronization::ProjectData &projectData) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove project data"_t,
+ projectStorageCategory(),
+ keyValue("project data", projectData)};
+
+ deleteProjectDataStatement.write(projectData.projectSourceId, projectData.sourceId);
+ };
+
+ Sqlite::insertUpdateDelete(range, projectDatas, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::synchronizeFileStatuses(FileStatuses &fileStatuses,
+ const SourceIds &updatedSourceIds)
+{
+ NanotraceHR::Tracer tracer{"synchronize file statuses"_t, projectStorageCategory()};
+
+ auto compareKey = [](auto &&first, auto &&second) { return first.sourceId - second.sourceId; };
+
+ std::sort(fileStatuses.begin(), fileStatuses.end(), [&](auto &&first, auto &&second) {
+ return first.sourceId < second.sourceId;
+ });
+
+ auto range = selectFileStatusesForSourceIdsStatement.range<FileStatus>(
+ toIntegers(updatedSourceIds));
+
+ auto insert = [&](const FileStatus &fileStatus) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert file status"_t,
+ projectStorageCategory(),
+ keyValue("file status", fileStatus)};
+
+ if (!fileStatus.sourceId)
+ throw FileStatusHasInvalidSourceId{};
+ insertFileStatusStatement.write(fileStatus.sourceId, fileStatus.size, fileStatus.lastModified);
+ };
+
+ auto update = [&](const FileStatus &fileStatusFromDatabase, const FileStatus &fileStatus) {
+ if (fileStatusFromDatabase.lastModified != fileStatus.lastModified
+ || fileStatusFromDatabase.size != fileStatus.size) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"update file status"_t,
+ projectStorageCategory(),
+ keyValue("file status", fileStatus),
+ keyValue("file status from database", fileStatusFromDatabase)};
+
+ updateFileStatusStatement.write(fileStatus.sourceId,
+ fileStatus.size,
+ fileStatus.lastModified);
+ return Sqlite::UpdateChange::Update;
+ }
+
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const FileStatus &fileStatus) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove file status"_t,
+ projectStorageCategory(),
+ keyValue("file status", fileStatus)};
+
+ deleteFileStatusStatement.write(fileStatus.sourceId);
+ };
+
+ Sqlite::insertUpdateDelete(range, fileStatuses, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::synchronizeImports(Storage::Imports &imports,
+ const SourceIds &updatedSourceIds,
+ Storage::Imports &moduleDependencies,
+ const SourceIds &updatedModuleDependencySourceIds,
+ Storage::Synchronization::ModuleExportedImports &moduleExportedImports,
+ const ModuleIds &updatedModuleIds)
+{
+ NanotraceHR::Tracer tracer{"synchronize imports"_t, projectStorageCategory()};
+
+ synchromizeModuleExportedImports(moduleExportedImports, updatedModuleIds);
+ NanotraceHR::Tracer importTracer{"synchronize qml document imports"_t, projectStorageCategory()};
+ synchronizeDocumentImports(imports, updatedSourceIds, Storage::Synchronization::ImportKind::Import);
+ importTracer.end();
+ NanotraceHR::Tracer moduleDependenciesTracer{"synchronize module depdencies"_t,
+ projectStorageCategory()};
+ synchronizeDocumentImports(moduleDependencies,
+ updatedModuleDependencySourceIds,
+ Storage::Synchronization::ImportKind::ModuleDependency);
+ moduleDependenciesTracer.end();
+}
+
+void ProjectStorage::synchromizeModuleExportedImports(
+ Storage::Synchronization::ModuleExportedImports &moduleExportedImports,
+ const ModuleIds &updatedModuleIds)
+{
+ NanotraceHR::Tracer tracer{"synchronize module exported imports"_t, projectStorageCategory()};
+ std::sort(moduleExportedImports.begin(),
+ moduleExportedImports.end(),
+ [](auto &&first, auto &&second) {
+ return std::tie(first.moduleId, first.exportedModuleId)
+ < std::tie(second.moduleId, second.exportedModuleId);
+ });
+
+ auto range = selectModuleExportedImportsForSourceIdStatement
+ .range<Storage::Synchronization::ModuleExportedImportView>(
+ toIntegers(updatedModuleIds));
+
+ auto compareKey = [](const Storage::Synchronization::ModuleExportedImportView &view,
+ const Storage::Synchronization::ModuleExportedImport &import) -> long long {
+ auto moduleIdDifference = view.moduleId - import.moduleId;
+ if (moduleIdDifference != 0)
+ return moduleIdDifference;
+
+ return view.exportedModuleId - import.exportedModuleId;
+ };
+
+ auto insert = [&](const Storage::Synchronization::ModuleExportedImport &import) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert module exported import"_t,
+ projectStorageCategory(),
+ keyValue("module exported import", import),
+ keyValue("module id", import.moduleId)};
+ tracer.tick("exported module"_t, keyValue("module id", import.exportedModuleId));
+
+ if (import.version.minor) {
+ insertModuleExportedImportWithVersionStatement.write(import.moduleId,
+ import.exportedModuleId,
+ import.isAutoVersion,
+ import.version.major.value,
+ import.version.minor.value);
+ } else if (import.version.major) {
+ insertModuleExportedImportWithMajorVersionStatement.write(import.moduleId,
+ import.exportedModuleId,
+ import.isAutoVersion,
+ import.version.major.value);
+ } else {
+ insertModuleExportedImportWithoutVersionStatement.write(import.moduleId,
+ import.exportedModuleId,
+ import.isAutoVersion);
+ }
+ };
+
+ auto update = [](const Storage::Synchronization::ModuleExportedImportView &,
+ const Storage::Synchronization::ModuleExportedImport &) {
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const Storage::Synchronization::ModuleExportedImportView &view) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove module exported import"_t,
+ projectStorageCategory(),
+ keyValue("module exported import view", view),
+ keyValue("module id", view.moduleId)};
+ tracer.tick("exported module"_t, keyValue("module id", view.exportedModuleId));
+
+ deleteModuleExportedImportStatement.write(view.moduleExportedImportId);
+ };
+
+ Sqlite::insertUpdateDelete(range, moduleExportedImports, compareKey, insert, update, remove);
+}
+
+ModuleId ProjectStorage::fetchModuleIdUnguarded(Utils::SmallStringView name) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch module id ungarded"_t,
+ projectStorageCategory(),
+ keyValue("module name", name)};
+
+ auto moduleId = selectModuleIdByNameStatement.value<ModuleId>(name);
+
+ if (!moduleId)
+ moduleId = insertModuleNameStatement.value<ModuleId>(name);
+
+ tracer.end(keyValue("module id", moduleId));
+
+ return moduleId;
+}
+
+Utils::PathString ProjectStorage::fetchModuleNameUnguarded(ModuleId id) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch module name ungarded"_t,
+ projectStorageCategory(),
+ keyValue("module id", id)};
+
+ auto moduleName = selectModuleNameStatement.value<Utils::PathString>(id);
+
+ if (moduleName.empty())
+ throw ModuleDoesNotExists{};
+
+ tracer.end(keyValue("module name", moduleName));
+
+ return moduleName;
+}
+
+void ProjectStorage::handleAliasPropertyDeclarationsWithPropertyType(
+ TypeId typeId, AliasPropertyDeclarations &relinkableAliasPropertyDeclarations)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"handle alias property declarations with property type"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId),
+ keyValue("relinkable alias property declarations",
+ relinkableAliasPropertyDeclarations)};
+
+ auto callback = [&](TypeId typeId_,
+ PropertyDeclarationId propertyDeclarationId,
+ ImportedTypeNameId propertyImportedTypeNameId,
+ PropertyDeclarationId aliasPropertyDeclarationId,
+ PropertyDeclarationId aliasPropertyDeclarationTailId) {
+ auto aliasPropertyName = selectPropertyNameStatement.value<Utils::SmallString>(
+ aliasPropertyDeclarationId);
+ Utils::SmallString aliasPropertyNameTail;
+ if (aliasPropertyDeclarationTailId)
+ aliasPropertyNameTail = selectPropertyNameStatement.value<Utils::SmallString>(
+ aliasPropertyDeclarationTailId);
+
+ relinkableAliasPropertyDeclarations.emplace_back(TypeId{typeId_},
+ PropertyDeclarationId{propertyDeclarationId},
+ ImportedTypeNameId{propertyImportedTypeNameId},
+ std::move(aliasPropertyName),
+ std::move(aliasPropertyNameTail));
+
+ updateAliasPropertyDeclarationToNullStatement.write(propertyDeclarationId);
+ };
+
+ selectAliasPropertiesDeclarationForPropertiesWithTypeIdStatement.readCallback(callback, typeId);
+}
+
+void ProjectStorage::handlePropertyDeclarationWithPropertyType(
+ TypeId typeId, PropertyDeclarations &relinkablePropertyDeclarations)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"handle property declarations with property type"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId),
+ keyValue("relinkable property declarations",
+ relinkablePropertyDeclarations)};
+
+ updatesPropertyDeclarationPropertyTypeToNullStatement.readTo(relinkablePropertyDeclarations,
+ typeId);
+}
+
+void ProjectStorage::handlePrototypes(TypeId prototypeId, Prototypes &relinkablePrototypes)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"handle prototypes"_t,
+ projectStorageCategory(),
+ keyValue("type id", prototypeId),
+ keyValue("relinkable prototypes", relinkablePrototypes)};
+
+ auto callback = [&](TypeId typeId, ImportedTypeNameId prototypeNameId) {
+ relinkablePrototypes.emplace_back(typeId, prototypeNameId);
+ };
+
+ updatePrototypeIdToNullStatement.readCallback(callback, prototypeId);
+}
+
+void ProjectStorage::handleExtensions(TypeId extensionId, Prototypes &relinkableExtensions)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"handle extension"_t,
+ projectStorageCategory(),
+ keyValue("type id", extensionId),
+ keyValue("relinkable extensions", relinkableExtensions)};
+
+ auto callback = [&](TypeId typeId, ImportedTypeNameId extensionNameId) {
+ relinkableExtensions.emplace_back(typeId, extensionNameId);
+ };
+
+ updateExtensionIdToNullStatement.readCallback(callback, extensionId);
+}
+
+void ProjectStorage::deleteType(TypeId typeId,
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes,
+ Prototypes &relinkableExtensions)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"delete type"_t, projectStorageCategory(), keyValue("type id", typeId)};
+
+ handlePropertyDeclarationWithPropertyType(typeId, relinkablePropertyDeclarations);
+ handleAliasPropertyDeclarationsWithPropertyType(typeId, relinkableAliasPropertyDeclarations);
+ handlePrototypes(typeId, relinkablePrototypes);
+ handleExtensions(typeId, relinkableExtensions);
+ deleteTypeNamesByTypeIdStatement.write(typeId);
+ deleteEnumerationDeclarationByTypeIdStatement.write(typeId);
+ deletePropertyDeclarationByTypeIdStatement.write(typeId);
+ deleteFunctionDeclarationByTypeIdStatement.write(typeId);
+ deleteSignalDeclarationByTypeIdStatement.write(typeId);
+ deleteTypeStatement.write(typeId);
+}
+
+void ProjectStorage::relinkAliasPropertyDeclarations(AliasPropertyDeclarations &aliasPropertyDeclarations,
+ const TypeIds &deletedTypeIds)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"relink alias properties"_t,
+ projectStorageCategory(),
+ keyValue("alias property declarations", aliasPropertyDeclarations),
+ keyValue("deleted type ids", deletedTypeIds)};
+
+ std::sort(aliasPropertyDeclarations.begin(), aliasPropertyDeclarations.end());
+
+ Utils::set_greedy_difference(
+ aliasPropertyDeclarations.cbegin(),
+ aliasPropertyDeclarations.cend(),
+ deletedTypeIds.begin(),
+ deletedTypeIds.end(),
+ [&](const AliasPropertyDeclaration &alias) {
+ auto typeId = fetchTypeId(alias.aliasImportedTypeNameId);
+
+ if (!typeId)
+ throw TypeNameDoesNotExists{fetchImportedTypeName(alias.aliasImportedTypeNameId)};
+
+ auto [propertyTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeIdAndNameUngarded(
+ typeId, alias.aliasPropertyName);
+
+ updatePropertyDeclarationWithAliasAndTypeStatement.write(alias.propertyDeclarationId,
+ propertyTypeId,
+ propertyTraits,
+ alias.aliasImportedTypeNameId,
+ aliasId);
+ },
+ TypeCompare<AliasPropertyDeclaration>{});
+}
+
+void ProjectStorage::relinkPropertyDeclarations(PropertyDeclarations &relinkablePropertyDeclaration,
+ const TypeIds &deletedTypeIds)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"relink property declarations"_t,
+ projectStorageCategory(),
+ keyValue("relinkable property declarations",
+ relinkablePropertyDeclaration),
+ keyValue("deleted type ids", deletedTypeIds)};
+
+ std::sort(relinkablePropertyDeclaration.begin(), relinkablePropertyDeclaration.end());
+
+ Utils::set_greedy_difference(
+ relinkablePropertyDeclaration.cbegin(),
+ relinkablePropertyDeclaration.cend(),
+ deletedTypeIds.begin(),
+ deletedTypeIds.end(),
+ [&](const PropertyDeclaration &property) {
+ TypeId propertyTypeId = fetchTypeId(property.importedTypeNameId);
+
+ if (!propertyTypeId)
+ throw TypeNameDoesNotExists{fetchImportedTypeName(property.importedTypeNameId)};
+
+ updatePropertyDeclarationTypeStatement.write(property.propertyDeclarationId,
+ propertyTypeId);
+ },
+ TypeCompare<PropertyDeclaration>{});
+}
+
+void ProjectStorage::deleteNotUpdatedTypes(const TypeIds &updatedTypeIds,
+ const SourceIds &updatedSourceIds,
+ const TypeIds &typeIdsToBeDeleted,
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes,
+ Prototypes &relinkableExtensions,
+ TypeIds &deletedTypeIds)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"delete not updated types"_t,
+ projectStorageCategory(),
+ keyValue("updated type ids", updatedTypeIds),
+ keyValue("updated source ids", updatedSourceIds),
+ keyValue("type ids to be deleted", typeIdsToBeDeleted)};
+
+ auto callback = [&](TypeId typeId) {
+ deletedTypeIds.push_back(typeId);
+ deleteType(typeId,
+ relinkableAliasPropertyDeclarations,
+ relinkablePropertyDeclarations,
+ relinkablePrototypes,
+ relinkableExtensions);
+ };
+
+ selectNotUpdatedTypesInSourcesStatement.readCallback(callback,
+ toIntegers(updatedSourceIds),
+ toIntegers(updatedTypeIds));
+ for (TypeId typeIdToBeDeleted : typeIdsToBeDeleted)
+ callback(typeIdToBeDeleted);
+}
+
+void ProjectStorage::relink(AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes,
+ Prototypes &relinkableExtensions,
+ TypeIds &deletedTypeIds)
+{
+ NanotraceHR::Tracer tracer{"relink"_t, projectStorageCategory()};
+
+ std::sort(deletedTypeIds.begin(), deletedTypeIds.end());
+
+ relinkPrototypes(relinkablePrototypes, deletedTypeIds, [&](TypeId typeId, TypeId prototypeId) {
+ updateTypePrototypeStatement.write(typeId, prototypeId);
+ });
+ relinkPrototypes(relinkableExtensions, deletedTypeIds, [&](TypeId typeId, TypeId prototypeId) {
+ updateTypeExtensionStatement.write(typeId, prototypeId);
+ });
+ relinkPropertyDeclarations(relinkablePropertyDeclarations, deletedTypeIds);
+ relinkAliasPropertyDeclarations(relinkableAliasPropertyDeclarations, deletedTypeIds);
+}
+
+PropertyDeclarationId ProjectStorage::fetchAliasId(TypeId aliasTypeId,
+ Utils::SmallStringView aliasPropertyName,
+ Utils::SmallStringView aliasPropertyNameTail)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch alias id"_t,
+ projectStorageCategory(),
+ keyValue("alias type id", aliasTypeId),
+ keyValue("alias property name", aliasPropertyName),
+ keyValue("alias property name tail", aliasPropertyNameTail)};
+
+ if (aliasPropertyNameTail.empty())
+ return fetchPropertyDeclarationIdByTypeIdAndNameUngarded(aliasTypeId, aliasPropertyName);
+
+ auto stemAlias = fetchPropertyDeclarationByTypeIdAndNameUngarded(aliasTypeId, aliasPropertyName);
+
+ return fetchPropertyDeclarationIdByTypeIdAndNameUngarded(stemAlias.propertyTypeId,
+ aliasPropertyNameTail);
+}
+
+void ProjectStorage::linkAliasPropertyDeclarationAliasIds(const AliasPropertyDeclarations &aliasDeclarations)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"link alias property declarations alias ids"_t,
+ projectStorageCategory(),
+ keyValue("alias property declarations", aliasDeclarations)};
+
+ for (const auto &aliasDeclaration : aliasDeclarations) {
+ auto aliasTypeId = fetchTypeId(aliasDeclaration.aliasImportedTypeNameId);
+
+ if (!aliasTypeId) {
+ throw TypeNameDoesNotExists{
+ fetchImportedTypeName(aliasDeclaration.aliasImportedTypeNameId)};
+ }
+
+ auto aliasId = fetchAliasId(aliasTypeId,
+ aliasDeclaration.aliasPropertyName,
+ aliasDeclaration.aliasPropertyNameTail);
+
+ updatePropertyDeclarationAliasIdAndTypeNameIdStatement.write(
+ aliasDeclaration.propertyDeclarationId, aliasId, aliasDeclaration.aliasImportedTypeNameId);
+ }
+}
+
+void ProjectStorage::updateAliasPropertyDeclarationValues(const AliasPropertyDeclarations &aliasDeclarations)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"update alias property declarations"_t,
+ projectStorageCategory(),
+ keyValue("alias property declarations", aliasDeclarations)};
+
+ for (const auto &aliasDeclaration : aliasDeclarations) {
+ updatetPropertiesDeclarationValuesOfAliasStatement.write(
+ aliasDeclaration.propertyDeclarationId);
+ updatePropertyAliasDeclarationRecursivelyStatement.write(
+ aliasDeclaration.propertyDeclarationId);
+ }
+}
+
+void ProjectStorage::checkAliasPropertyDeclarationCycles(const AliasPropertyDeclarations &aliasDeclarations)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"check alias property declarations cycles"_t,
+ projectStorageCategory(),
+ keyValue("alias property declarations", aliasDeclarations)};
+ for (const auto &aliasDeclaration : aliasDeclarations)
+ checkForAliasChainCycle(aliasDeclaration.propertyDeclarationId);
+}
+
+void ProjectStorage::linkAliases(const AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ const AliasPropertyDeclarations &updatedAliasPropertyDeclarations)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"link aliases"_t, projectStorageCategory()};
+
+ linkAliasPropertyDeclarationAliasIds(insertedAliasPropertyDeclarations);
+ linkAliasPropertyDeclarationAliasIds(updatedAliasPropertyDeclarations);
+
+ checkAliasPropertyDeclarationCycles(insertedAliasPropertyDeclarations);
+ checkAliasPropertyDeclarationCycles(updatedAliasPropertyDeclarations);
+
+ updateAliasPropertyDeclarationValues(insertedAliasPropertyDeclarations);
+ updateAliasPropertyDeclarationValues(updatedAliasPropertyDeclarations);
+}
+
+void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds,
+ Storage::Synchronization::ExportedTypes &exportedTypes,
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations,
+ Prototypes &relinkablePrototypes,
+ Prototypes &relinkableExtensions)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"synchronize exported types"_t, projectStorageCategory()};
+
+ std::sort(exportedTypes.begin(), exportedTypes.end(), [](auto &&first, auto &&second) {
+ if (first.moduleId < second.moduleId)
+ return true;
+ else if (first.moduleId > second.moduleId)
+ return false;
+
+ auto nameCompare = Sqlite::compare(first.name, second.name);
+
+ if (nameCompare < 0)
+ return true;
+ else if (nameCompare > 0)
+ return false;
+
+ return first.version < second.version;
+ });
+
+ auto range = selectExportedTypesForSourceIdsStatement
+ .range<Storage::Synchronization::ExportedTypeView>(toIntegers(updatedTypeIds));
+
+ auto compareKey = [](const Storage::Synchronization::ExportedTypeView &view,
+ const Storage::Synchronization::ExportedType &type) -> long long {
+ auto moduleIdDifference = view.moduleId - type.moduleId;
+ if (moduleIdDifference != 0)
+ return moduleIdDifference;
+
+ auto nameDifference = Sqlite::compare(view.name, type.name);
+ if (nameDifference != 0)
+ return nameDifference;
+
+ auto versionDifference = view.version.major.value - type.version.major.value;
+ if (versionDifference != 0)
+ return versionDifference;
+
+ return view.version.minor.value - type.version.minor.value;
+ };
+
+ auto insert = [&](const Storage::Synchronization::ExportedType &type) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert exported type"_t,
+ projectStorageCategory(),
+ keyValue("exported type", type),
+ keyValue("type id", type.typeId),
+ keyValue("module id", type.moduleId)};
+ if (!type.moduleId)
+ throw QmlDesigner::ModuleDoesNotExists{};
+
+ try {
+ if (type.version) {
+ insertExportedTypeNamesWithVersionStatement.write(type.moduleId,
+ type.name,
+ type.version.major.value,
+ type.version.minor.value,
+ type.typeId);
+
+ } else if (type.version.major) {
+ insertExportedTypeNamesWithMajorVersionStatement.write(type.moduleId,
+ type.name,
+ type.version.major.value,
+ type.typeId);
+ } else {
+ insertExportedTypeNamesWithoutVersionStatement.write(type.moduleId,
+ type.name,
+ type.typeId);
+ }
+ } catch (const Sqlite::ConstraintPreventsModification &) {
+ throw QmlDesigner::ExportedTypeCannotBeInserted{type.name};
+ }
+ };
+
+ auto update = [&](const Storage::Synchronization::ExportedTypeView &view,
+ const Storage::Synchronization::ExportedType &type) {
+ if (view.typeId != type.typeId) {
+ NanotraceHR::Tracer tracer{"update exported type"_t,
+ projectStorageCategory(),
+ keyValue("exported type", type),
+ keyValue("exported type view", view),
+ keyValue("type id", type.typeId),
+ keyValue("module id", type.typeId)};
+
+ handlePropertyDeclarationWithPropertyType(view.typeId, relinkablePropertyDeclarations);
+ handleAliasPropertyDeclarationsWithPropertyType(view.typeId,
+ relinkableAliasPropertyDeclarations);
+ handlePrototypes(view.typeId, relinkablePrototypes);
+ handleExtensions(view.typeId, relinkableExtensions);
+ updateExportedTypeNameTypeIdStatement.write(view.exportedTypeNameId, type.typeId);
+ return Sqlite::UpdateChange::Update;
+ }
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const Storage::Synchronization::ExportedTypeView &view) {
+ NanotraceHR::Tracer tracer{"remove exported type"_t,
+ projectStorageCategory(),
+ keyValue("exported type", view),
+ keyValue("type id", view.typeId),
+ keyValue("module id", view.moduleId)};
+
+ handlePropertyDeclarationWithPropertyType(view.typeId, relinkablePropertyDeclarations);
+ handleAliasPropertyDeclarationsWithPropertyType(view.typeId,
+ relinkableAliasPropertyDeclarations);
+ handlePrototypes(view.typeId, relinkablePrototypes);
+ handleExtensions(view.typeId, relinkableExtensions);
+ deleteExportedTypeNameStatement.write(view.exportedTypeNameId);
+ };
+
+ Sqlite::insertUpdateDelete(range, exportedTypes, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::synchronizePropertyDeclarationsInsertAlias(
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ const Storage::Synchronization::PropertyDeclaration &value,
+ SourceId sourceId,
+ TypeId typeId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert property declaration to alias"_t,
+ projectStorageCategory(),
+ keyValue("property declaration", value)};
+
+ auto callback = [&](PropertyDeclarationId propertyDeclarationId) {
+ insertedAliasPropertyDeclarations.emplace_back(typeId,
+ propertyDeclarationId,
+ fetchImportedTypeNameId(value.typeName,
+ sourceId),
+ value.aliasPropertyName,
+ value.aliasPropertyNameTail);
+ return Sqlite::CallbackControl::Abort;
+ };
+
+ insertAliasPropertyDeclarationStatement.readCallback(callback, typeId, value.name);
+}
+
+QVarLengthArray<PropertyDeclarationId, 128> ProjectStorage::fetchPropertyDeclarationIds(
+ TypeId baseTypeId) const
+{
+ QVarLengthArray<PropertyDeclarationId, 128> propertyDeclarationIds;
+
+ selectLocalPropertyDeclarationIdsForTypeStatement.readTo(propertyDeclarationIds, baseTypeId);
+
+ auto range = selectPrototypeAndExtensionIdsStatement.range<TypeId>(baseTypeId);
+
+ for (TypeId prototype : range) {
+ selectLocalPropertyDeclarationIdsForTypeStatement.readTo(propertyDeclarationIds, prototype);
+ }
+
+ return propertyDeclarationIds;
+}
+
+PropertyDeclarationId ProjectStorage::fetchNextPropertyDeclarationId(
+ TypeId baseTypeId, Utils::SmallStringView propertyName) const
+{
+ auto range = selectPrototypeAndExtensionIdsStatement.range<TypeId>(baseTypeId);
+
+ for (TypeId prototype : range) {
+ auto propertyDeclarationId = selectPropertyDeclarationIdByTypeIdAndNameStatement
+ .value<PropertyDeclarationId>(prototype, propertyName);
+
+ if (propertyDeclarationId)
+ return propertyDeclarationId;
+ }
+
+ return PropertyDeclarationId{};
+}
+
+PropertyDeclarationId ProjectStorage::fetchPropertyDeclarationId(TypeId typeId,
+ Utils::SmallStringView propertyName) const
+{
+ auto propertyDeclarationId = selectPropertyDeclarationIdByTypeIdAndNameStatement
+ .value<PropertyDeclarationId>(typeId, propertyName);
+
+ if (propertyDeclarationId)
+ return propertyDeclarationId;
+
+ return fetchNextPropertyDeclarationId(typeId, propertyName);
+}
+
+PropertyDeclarationId ProjectStorage::fetchNextDefaultPropertyDeclarationId(TypeId baseTypeId) const
+{
+ auto range = selectPrototypeAndExtensionIdsStatement.range<TypeId>(baseTypeId);
+
+ for (TypeId prototype : range) {
+ auto propertyDeclarationId = selectDefaultPropertyDeclarationIdStatement
+ .value<PropertyDeclarationId>(prototype);
+
+ if (propertyDeclarationId)
+ return propertyDeclarationId;
+ }
+
+ return PropertyDeclarationId{};
+}
+
+PropertyDeclarationId ProjectStorage::fetchDefaultPropertyDeclarationId(TypeId typeId) const
+{
+ auto propertyDeclarationId = selectDefaultPropertyDeclarationIdStatement.value<PropertyDeclarationId>(
+ typeId);
+
+ if (propertyDeclarationId)
+ return propertyDeclarationId;
+
+ return fetchNextDefaultPropertyDeclarationId(typeId);
+}
+
+void ProjectStorage::synchronizePropertyDeclarationsInsertProperty(
+ const Storage::Synchronization::PropertyDeclaration &value, SourceId sourceId, TypeId typeId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert property declaration"_t,
+ projectStorageCategory(),
+ keyValue("property declaration", value)};
+
+ auto propertyImportedTypeNameId = fetchImportedTypeNameId(value.typeName, sourceId);
+ auto propertyTypeId = fetchTypeId(propertyImportedTypeNameId);
+
+ if (!propertyTypeId)
+ throw TypeNameDoesNotExists{fetchImportedTypeName(propertyImportedTypeNameId), sourceId};
+
+ auto propertyDeclarationId = insertPropertyDeclarationStatement.value<PropertyDeclarationId>(
+ typeId, value.name, propertyTypeId, value.traits, propertyImportedTypeNameId);
+
+ auto nextPropertyDeclarationId = fetchNextPropertyDeclarationId(typeId, value.name);
+ if (nextPropertyDeclarationId) {
+ updateAliasIdPropertyDeclarationStatement.write(nextPropertyDeclarationId,
+ propertyDeclarationId);
+ updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement.write(propertyDeclarationId,
+ propertyTypeId,
+ value.traits);
+ }
+}
+
+void ProjectStorage::synchronizePropertyDeclarationsUpdateAlias(
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
+ const Storage::Synchronization::PropertyDeclarationView &view,
+ const Storage::Synchronization::PropertyDeclaration &value,
+ SourceId sourceId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"update property declaration to alias"_t,
+ projectStorageCategory(),
+ keyValue("property declaration", value),
+ keyValue("property declaration view", view)};
+
+ updatedAliasPropertyDeclarations.emplace_back(view.typeId,
+ view.id,
+ fetchImportedTypeNameId(value.typeName, sourceId),
+ value.aliasPropertyName,
+ value.aliasPropertyNameTail,
+ view.aliasId);
+}
+
+Sqlite::UpdateChange ProjectStorage::synchronizePropertyDeclarationsUpdateProperty(
+ const Storage::Synchronization::PropertyDeclarationView &view,
+ const Storage::Synchronization::PropertyDeclaration &value,
+ SourceId sourceId,
+ PropertyDeclarationIds &propertyDeclarationIds)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"update property declaration"_t,
+ projectStorageCategory(),
+ keyValue("property declaration", value),
+ keyValue("property declaration view", view)};
+
+ auto propertyImportedTypeNameId = fetchImportedTypeNameId(value.typeName, sourceId);
+
+ auto propertyTypeId = fetchTypeId(propertyImportedTypeNameId);
+
+ if (!propertyTypeId)
+ throw TypeNameDoesNotExists{fetchImportedTypeName(propertyImportedTypeNameId), sourceId};
+
+ if (view.traits == value.traits && propertyTypeId == view.typeId
+ && propertyImportedTypeNameId == view.typeNameId)
+ return Sqlite::UpdateChange::No;
+
+ updatePropertyDeclarationStatement.write(view.id,
+ propertyTypeId,
+ value.traits,
+ propertyImportedTypeNameId);
+ updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement.write(view.id,
+ propertyTypeId,
+ value.traits);
+ propertyDeclarationIds.push_back(view.id);
+
+ tracer.end(keyValue("updated", "yes"));
+
+ return Sqlite::UpdateChange::Update;
+}
+
+void ProjectStorage::synchronizePropertyDeclarations(
+ TypeId typeId,
+ Storage::Synchronization::PropertyDeclarations &propertyDeclarations,
+ SourceId sourceId,
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
+ PropertyDeclarationIds &propertyDeclarationIds)
+{
+ NanotraceHR::Tracer tracer{"synchronize property declaration"_t, projectStorageCategory()};
+
+ std::sort(propertyDeclarations.begin(), propertyDeclarations.end(), [](auto &&first, auto &&second) {
+ return Sqlite::compare(first.name, second.name) < 0;
+ });
+
+ auto range = selectPropertyDeclarationsForTypeIdStatement
+ .range<Storage::Synchronization::PropertyDeclarationView>(typeId);
+
+ auto compareKey = [](const Storage::Synchronization::PropertyDeclarationView &view,
+ const Storage::Synchronization::PropertyDeclaration &value) {
+ return Sqlite::compare(view.name, value.name);
+ };
+
+ auto insert = [&](const Storage::Synchronization::PropertyDeclaration &value) {
+ if (value.kind == Storage::Synchronization::PropertyKind::Alias) {
+ synchronizePropertyDeclarationsInsertAlias(insertedAliasPropertyDeclarations,
+ value,
+ sourceId,
+ typeId);
+ } else {
+ synchronizePropertyDeclarationsInsertProperty(value, sourceId, typeId);
+ }
+ };
+
+ auto update = [&](const Storage::Synchronization::PropertyDeclarationView &view,
+ const Storage::Synchronization::PropertyDeclaration &value) {
+ if (value.kind == Storage::Synchronization::PropertyKind::Alias) {
+ synchronizePropertyDeclarationsUpdateAlias(updatedAliasPropertyDeclarations,
+ view,
+ value,
+ sourceId);
+ propertyDeclarationIds.push_back(view.id);
+ } else {
+ return synchronizePropertyDeclarationsUpdateProperty(view,
+ value,
+ sourceId,
+ propertyDeclarationIds);
+ }
+
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const Storage::Synchronization::PropertyDeclarationView &view) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove property declaration"_t,
+ projectStorageCategory(),
+ keyValue("property declaratio viewn", view)};
+
+ auto nextPropertyDeclarationId = fetchNextPropertyDeclarationId(typeId, view.name);
+
+ if (nextPropertyDeclarationId) {
+ updateAliasPropertyDeclarationByAliasPropertyDeclarationIdStatement
+ .write(nextPropertyDeclarationId, view.id);
+ }
+
+ updateDefaultPropertyIdToNullStatement.write(view.id);
+ deletePropertyDeclarationStatement.write(view.id);
+ propertyDeclarationIds.push_back(view.id);
+ };
+
+ Sqlite::insertUpdateDelete(range, propertyDeclarations, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::resetRemovedAliasPropertyDeclarationsToNull(
+ Storage::Synchronization::Type &type, PropertyDeclarationIds &propertyDeclarationIds)
+{
+ NanotraceHR::Tracer tracer{"reset removed alias property declaration to null"_t,
+ projectStorageCategory()};
+
+ if (type.changeLevel == Storage::Synchronization::ChangeLevel::Minimal)
+ return;
+
+ Storage::Synchronization::PropertyDeclarations &aliasDeclarations = type.propertyDeclarations;
+
+ std::sort(aliasDeclarations.begin(), aliasDeclarations.end(), [](auto &&first, auto &&second) {
+ return Sqlite::compare(first.name, second.name) < 0;
+ });
+
+ auto range = selectPropertyDeclarationsWithAliasForTypeIdStatement
+ .range<AliasPropertyDeclarationView>(type.typeId);
+
+ auto compareKey = [](const AliasPropertyDeclarationView &view,
+ const Storage::Synchronization::PropertyDeclaration &value) {
+ return Sqlite::compare(view.name, value.name);
+ };
+
+ auto insert = [&](const Storage::Synchronization::PropertyDeclaration &) {};
+
+ auto update = [&](const AliasPropertyDeclarationView &,
+ const Storage::Synchronization::PropertyDeclaration &) {
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const AliasPropertyDeclarationView &view) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"reset removed alias property declaration to null"_t,
+ projectStorageCategory(),
+ keyValue("alias property declaration view", view)};
+
+ updatePropertyDeclarationAliasIdToNullStatement.write(view.id);
+ propertyDeclarationIds.push_back(view.id);
+ };
+
+ Sqlite::insertUpdateDelete(range, aliasDeclarations, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::resetRemovedAliasPropertyDeclarationsToNull(
+ Storage::Synchronization::Types &types,
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations)
+{
+ NanotraceHR::Tracer tracer{"reset removed alias properties to null"_t, projectStorageCategory()};
+
+ PropertyDeclarationIds propertyDeclarationIds;
+ propertyDeclarationIds.reserve(types.size());
+
+ for (auto &&type : types)
+ resetRemovedAliasPropertyDeclarationsToNull(type, propertyDeclarationIds);
+
+ removeRelinkableEntries(relinkableAliasPropertyDeclarations,
+ propertyDeclarationIds,
+ PropertyCompare<AliasPropertyDeclaration>{});
+}
+
+ImportId ProjectStorage::insertDocumentImport(const Storage::Import &import,
+ Storage::Synchronization::ImportKind importKind,
+ ModuleId sourceModuleId,
+ ImportId parentImportId)
+{
+ if (import.version.minor) {
+ return insertDocumentImportWithVersionStatement.value<ImportId>(import.sourceId,
+ import.moduleId,
+ sourceModuleId,
+ importKind,
+ import.version.major.value,
+ import.version.minor.value,
+ parentImportId);
+ } else if (import.version.major) {
+ return insertDocumentImportWithMajorVersionStatement.value<ImportId>(import.sourceId,
+ import.moduleId,
+ sourceModuleId,
+ importKind,
+ import.version.major.value,
+ parentImportId);
+ } else {
+ return insertDocumentImportWithoutVersionStatement.value<ImportId>(import.sourceId,
+ import.moduleId,
+ sourceModuleId,
+ importKind,
+ parentImportId);
+ }
+}
+
+void ProjectStorage::synchronizeDocumentImports(Storage::Imports &imports,
+ const SourceIds &updatedSourceIds,
+ Storage::Synchronization::ImportKind importKind)
+{
+ std::sort(imports.begin(), imports.end(), [](auto &&first, auto &&second) {
+ return std::tie(first.sourceId, first.moduleId, first.version)
+ < std::tie(second.sourceId, second.moduleId, second.version);
+ });
+
+ auto range = selectDocumentImportForSourceIdStatement.range<Storage::Synchronization::ImportView>(
+ toIntegers(updatedSourceIds), importKind);
+
+ auto compareKey = [](const Storage::Synchronization::ImportView &view,
+ const Storage::Import &import) -> long long {
+ auto sourceIdDifference = view.sourceId - import.sourceId;
+ if (sourceIdDifference != 0)
+ return sourceIdDifference;
+
+ auto moduleIdDifference = view.moduleId - import.moduleId;
+ if (moduleIdDifference != 0)
+ return moduleIdDifference;
+
+ auto versionDifference = view.version.major.value - import.version.major.value;
+ if (versionDifference != 0)
+ return versionDifference;
+
+ return view.version.minor.value - import.version.minor.value;
+ };
+
+ auto insert = [&](const Storage::Import &import) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert import"_t,
+ projectStorageCategory(),
+ keyValue("import", import),
+ keyValue("import kind", importKind),
+ keyValue("source id", import.sourceId),
+ keyValue("module id", import.moduleId)};
+
+ auto importId = insertDocumentImport(import, importKind, import.moduleId, ImportId{});
+ auto callback = [&](ModuleId exportedModuleId, int majorVersion, int minorVersion) {
+ Storage::Import additionImport{exportedModuleId,
+ Storage::Version{majorVersion, minorVersion},
+ import.sourceId};
+
+ auto exportedImportKind = importKind == Storage::Synchronization::ImportKind::Import
+ ? Storage::Synchronization::ImportKind::ModuleExportedImport
+ : Storage::Synchronization::ImportKind::ModuleExportedModuleDependency;
+
+ NanotraceHR::Tracer tracer{"insert indirect import"_t,
+ projectStorageCategory(),
+ keyValue("import", import),
+ keyValue("import kind", exportedImportKind),
+ keyValue("source id", import.sourceId),
+ keyValue("module id", import.moduleId)};
+
+ auto indirectImportId = insertDocumentImport(additionImport,
+ exportedImportKind,
+ import.moduleId,
+ importId);
+
+ tracer.end(keyValue("import id", indirectImportId));
+ };
+
+ selectModuleExportedImportsForModuleIdStatement.readCallback(callback,
+ import.moduleId,
+ import.version.major.value,
+ import.version.minor.value);
+ tracer.end(keyValue("import id", importId));
+ };
+
+ auto update = [](const Storage::Synchronization::ImportView &, const Storage::Import &) {
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const Storage::Synchronization::ImportView &view) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove import"_t,
+ projectStorageCategory(),
+ keyValue("import", view),
+ keyValue("import id", view.importId),
+ keyValue("source id", view.sourceId),
+ keyValue("module id", view.moduleId)};
+
+ deleteDocumentImportStatement.write(view.importId);
+ deleteDocumentImportsWithParentImportIdStatement.write(view.sourceId, view.importId);
+ };
+
+ Sqlite::insertUpdateDelete(range, imports, compareKey, insert, update, remove);
+}
+
+Utils::PathString ProjectStorage::createJson(const Storage::Synchronization::ParameterDeclarations &parameters)
+{
+ NanotraceHR::Tracer tracer{"create json from parameter declarations"_t, projectStorageCategory()};
+
+ Utils::PathString json;
+ json.append("[");
+
+ Utils::SmallStringView comma{""};
+
+ for (const auto &parameter : parameters) {
+ json.append(comma);
+ comma = ",";
+ json.append(R"({"n":")");
+ json.append(parameter.name);
+ json.append(R"(","tn":")");
+ json.append(parameter.typeName);
+ if (parameter.traits == Storage::PropertyDeclarationTraits::None) {
+ json.append("\"}");
+ } else {
+ json.append(R"(","tr":)");
+ json.append(Utils::SmallString::number(to_underlying(parameter.traits)));
+ json.append("}");
+ }
+ }
+
+ json.append("]");
+
+ return json;
+}
+
+TypeId ProjectStorage::fetchTypeIdByModuleIdAndExportedName(ModuleId moduleId,
+ Utils::SmallStringView name) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch type id by module id and exported name"_t,
+ projectStorageCategory(),
+ keyValue("module id", moduleId),
+ keyValue("exported name", name)};
+
+ return selectTypeIdByModuleIdAndExportedNameStatement.value<TypeId>(moduleId, name);
+}
+
+void ProjectStorage::addTypeIdToPropertyEditorQmlPaths(
+ Storage::Synchronization::PropertyEditorQmlPaths &paths)
+{
+ NanotraceHR::Tracer tracer{"add type id to property editor qml paths"_t, projectStorageCategory()};
+
+ for (auto &path : paths)
+ path.typeId = fetchTypeIdByModuleIdAndExportedName(path.moduleId, path.typeName);
+}
+
+void ProjectStorage::synchronizePropertyEditorPaths(Storage::Synchronization::PropertyEditorQmlPaths &paths,
+ SourceIds updatedPropertyEditorQmlPathsSourceIds)
+{
+ using Storage::Synchronization::PropertyEditorQmlPath;
+ std::sort(paths.begin(), paths.end(), [](auto &&first, auto &&second) {
+ return first.typeId < second.typeId;
+ });
+
+ auto range = selectPropertyEditorPathsForForSourceIdsStatement.range<PropertyEditorQmlPathView>(
+ toIntegers(updatedPropertyEditorQmlPathsSourceIds));
+
+ auto compareKey = [](const PropertyEditorQmlPathView &view,
+ const PropertyEditorQmlPath &value) -> long long {
+ return view.typeId - value.typeId;
+ };
+
+ auto insert = [&](const PropertyEditorQmlPath &path) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert property editor paths"_t,
+ projectStorageCategory(),
+ keyValue("property editor qml path", path)};
+
+ if (path.typeId)
+ insertPropertyEditorPathStatement.write(path.typeId, path.pathId, path.directoryId);
+ };
+
+ auto update = [&](const PropertyEditorQmlPathView &view, const PropertyEditorQmlPath &value) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"update property editor paths"_t,
+ projectStorageCategory(),
+ keyValue("property editor qml path", value),
+ keyValue("property editor qml path view", view)};
+
+ if (value.pathId != view.pathId || value.directoryId != view.directoryId) {
+ updatePropertyEditorPathsStatement.write(value.typeId, value.pathId, value.directoryId);
+
+ tracer.end(keyValue("updated", "yes"));
+
+ return Sqlite::UpdateChange::Update;
+ }
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const PropertyEditorQmlPathView &view) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove property editor paths"_t,
+ projectStorageCategory(),
+ keyValue("property editor qml path view", view)};
+
+ deletePropertyEditorPathStatement.write(view.typeId);
+ };
+
+ Sqlite::insertUpdateDelete(range, paths, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::synchronizePropertyEditorQmlPaths(
+ Storage::Synchronization::PropertyEditorQmlPaths &paths,
+ SourceIds updatedPropertyEditorQmlPathsSourceIds)
+{
+ NanotraceHR::Tracer tracer{"synchronize property editor qml paths"_t, projectStorageCategory()};
+
+ addTypeIdToPropertyEditorQmlPaths(paths);
+ synchronizePropertyEditorPaths(paths, updatedPropertyEditorQmlPathsSourceIds);
+}
+
+void ProjectStorage::synchronizeFunctionDeclarations(
+ TypeId typeId, Storage::Synchronization::FunctionDeclarations &functionsDeclarations)
+{
+ NanotraceHR::Tracer tracer{"synchronize function declaration"_t, projectStorageCategory()};
+
+ std::sort(functionsDeclarations.begin(),
+ functionsDeclarations.end(),
+ [](auto &&first, auto &&second) {
+ auto compare = Sqlite::compare(first.name, second.name);
+
+ if (compare == 0) {
+ Utils::PathString firstSignature{createJson(first.parameters)};
+ Utils::PathString secondSignature{createJson(second.parameters)};
+
+ return Sqlite::compare(firstSignature, secondSignature) < 0;
+ }
+
+ return compare < 0;
+ });
+
+ auto range = selectFunctionDeclarationsForTypeIdStatement
+ .range<Storage::Synchronization::FunctionDeclarationView>(typeId);
+
+ auto compareKey = [](const Storage::Synchronization::FunctionDeclarationView &view,
+ const Storage::Synchronization::FunctionDeclaration &value) {
+ auto nameKey = Sqlite::compare(view.name, value.name);
+ if (nameKey != 0)
+ return nameKey;
+
+ Utils::PathString valueSignature{createJson(value.parameters)};
+
+ return Sqlite::compare(view.signature, valueSignature);
+ };
+
+ auto insert = [&](const Storage::Synchronization::FunctionDeclaration &value) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert function declaration"_t,
+ projectStorageCategory(),
+ keyValue("function declaration", value)};
+
+ Utils::PathString signature{createJson(value.parameters)};
+
+ insertFunctionDeclarationStatement.write(typeId, value.name, value.returnTypeName, signature);
+ };
+
+ auto update = [&](const Storage::Synchronization::FunctionDeclarationView &view,
+ const Storage::Synchronization::FunctionDeclaration &value) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"update function declaration"_t,
+ projectStorageCategory(),
+ keyValue("function declaration", value),
+ keyValue("function declaration view", view)};
+
+ Utils::PathString signature{createJson(value.parameters)};
+
+ if (value.returnTypeName == view.returnTypeName && signature == view.signature)
+ return Sqlite::UpdateChange::No;
+
+ updateFunctionDeclarationStatement.write(view.id, value.returnTypeName, signature);
+
+ tracer.end(keyValue("updated", "yes"));
+
+ return Sqlite::UpdateChange::Update;
+ };
+
+ auto remove = [&](const Storage::Synchronization::FunctionDeclarationView &view) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove function declaration"_t,
+ projectStorageCategory(),
+ keyValue("function declaration view", view)};
+
+ deleteFunctionDeclarationStatement.write(view.id);
+ };
+
+ Sqlite::insertUpdateDelete(range, functionsDeclarations, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::synchronizeSignalDeclarations(
+ TypeId typeId, Storage::Synchronization::SignalDeclarations &signalDeclarations)
+{
+ NanotraceHR::Tracer tracer{"synchronize signal declaration"_t, projectStorageCategory()};
+
+ std::sort(signalDeclarations.begin(), signalDeclarations.end(), [](auto &&first, auto &&second) {
+ auto compare = Sqlite::compare(first.name, second.name);
+
+ if (compare == 0) {
+ Utils::PathString firstSignature{createJson(first.parameters)};
+ Utils::PathString secondSignature{createJson(second.parameters)};
+
+ return Sqlite::compare(firstSignature, secondSignature) < 0;
+ }
+
+ return compare < 0;
+ });
+
+ auto range = selectSignalDeclarationsForTypeIdStatement
+ .range<Storage::Synchronization::SignalDeclarationView>(typeId);
+
+ auto compareKey = [](const Storage::Synchronization::SignalDeclarationView &view,
+ const Storage::Synchronization::SignalDeclaration &value) {
+ auto nameKey = Sqlite::compare(view.name, value.name);
+ if (nameKey != 0)
+ return nameKey;
+
+ Utils::PathString valueSignature{createJson(value.parameters)};
+
+ return Sqlite::compare(view.signature, valueSignature);
+ };
+
+ auto insert = [&](const Storage::Synchronization::SignalDeclaration &value) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert signal declaration"_t,
+ projectStorageCategory(),
+ keyValue("signal declaration", value)};
+
+ Utils::PathString signature{createJson(value.parameters)};
+
+ insertSignalDeclarationStatement.write(typeId, value.name, signature);
+ };
+
+ auto update = [&]([[maybe_unused]] const Storage::Synchronization::SignalDeclarationView &view,
+ [[maybe_unused]] const Storage::Synchronization::SignalDeclaration &value) {
+ return Sqlite::UpdateChange::No;
+ };
+
+ auto remove = [&](const Storage::Synchronization::SignalDeclarationView &view) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove signal declaration"_t,
+ projectStorageCategory(),
+ keyValue("signal declaration view", view)};
+
+ deleteSignalDeclarationStatement.write(view.id);
+ };
+
+ Sqlite::insertUpdateDelete(range, signalDeclarations, compareKey, insert, update, remove);
+}
+
+Utils::PathString ProjectStorage::createJson(
+ const Storage::Synchronization::EnumeratorDeclarations &enumeratorDeclarations)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"create json from enumerator declarations"_t, projectStorageCategory()};
+
+ Utils::PathString json;
+ json.append("{");
+
+ Utils::SmallStringView comma{"\""};
+
+ for (const auto &enumerator : enumeratorDeclarations) {
+ json.append(comma);
+ comma = ",\"";
+ json.append(enumerator.name);
+ if (enumerator.hasValue) {
+ json.append("\":\"");
+ json.append(Utils::SmallString::number(enumerator.value));
+ json.append("\"");
+ } else {
+ json.append("\":null");
+ }
+ }
+
+ json.append("}");
+
+ return json;
+}
+
+void ProjectStorage::synchronizeEnumerationDeclarations(
+ TypeId typeId, Storage::Synchronization::EnumerationDeclarations &enumerationDeclarations)
+{
+ NanotraceHR::Tracer tracer{"synchronize enumeration declaration"_t, projectStorageCategory()};
+
+ std::sort(enumerationDeclarations.begin(),
+ enumerationDeclarations.end(),
+ [](auto &&first, auto &&second) {
+ return Sqlite::compare(first.name, second.name) < 0;
+ });
+
+ auto range = selectEnumerationDeclarationsForTypeIdStatement
+ .range<Storage::Synchronization::EnumerationDeclarationView>(typeId);
+
+ auto compareKey = [](const Storage::Synchronization::EnumerationDeclarationView &view,
+ const Storage::Synchronization::EnumerationDeclaration &value) {
+ return Sqlite::compare(view.name, value.name);
+ };
+
+ auto insert = [&](const Storage::Synchronization::EnumerationDeclaration &value) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"insert enumeration declaration"_t,
+ projectStorageCategory(),
+ keyValue("enumeration declaration", value)};
+
+ Utils::PathString signature{createJson(value.enumeratorDeclarations)};
+
+ insertEnumerationDeclarationStatement.write(typeId, value.name, signature);
+ };
+
+ auto update = [&](const Storage::Synchronization::EnumerationDeclarationView &view,
+ const Storage::Synchronization::EnumerationDeclaration &value) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"update enumeration declaration"_t,
+ projectStorageCategory(),
+ keyValue("enumeration declaration", value),
+ keyValue("enumeration declaration view", view)};
+
+ Utils::PathString enumeratorDeclarations{createJson(value.enumeratorDeclarations)};
+
+ if (enumeratorDeclarations == view.enumeratorDeclarations)
+ return Sqlite::UpdateChange::No;
+
+ updateEnumerationDeclarationStatement.write(view.id, enumeratorDeclarations);
+
+ tracer.end(keyValue("updated", "yes"));
+
+ return Sqlite::UpdateChange::Update;
+ };
+
+ auto remove = [&](const Storage::Synchronization::EnumerationDeclarationView &view) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"remove enumeration declaration"_t,
+ projectStorageCategory(),
+ keyValue("enumeration declaration view", view)};
+
+ deleteEnumerationDeclarationStatement.write(view.id);
+ };
+
+ Sqlite::insertUpdateDelete(range, enumerationDeclarations, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::extractExportedTypes(TypeId typeId,
+ const Storage::Synchronization::Type &type,
+ Storage::Synchronization::ExportedTypes &exportedTypes)
+{
+ for (const auto &exportedType : type.exportedTypes)
+ exportedTypes.emplace_back(exportedType.name, exportedType.version, typeId, exportedType.moduleId);
+}
+
+TypeId ProjectStorage::declareType(Storage::Synchronization::Type &type)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"declare type"_t,
+ projectStorageCategory(),
+ keyValue("source id", type.sourceId),
+ keyValue("type name", type.typeName)};
+
+ if (type.typeName.isEmpty()) {
+ type.typeId = selectTypeIdBySourceIdStatement.value<TypeId>(type.sourceId);
+
+ tracer.end(keyValue("type id", type.typeId));
+
+ return type.typeId;
+ }
+
+ type.typeId = insertTypeStatement.value<TypeId>(type.sourceId, type.typeName);
+
+ if (!type.typeId)
+ type.typeId = selectTypeIdBySourceIdAndNameStatement.value<TypeId>(type.sourceId,
+ type.typeName);
+
+ tracer.end(keyValue("type id", type.typeId));
+
+ return type.typeId;
+}
+
+void ProjectStorage::syncDeclarations(Storage::Synchronization::Type &type,
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
+ PropertyDeclarationIds &propertyDeclarationIds)
+{
+ NanotraceHR::Tracer tracer{"synchronize declaration per type"_t, projectStorageCategory()};
+
+ if (type.changeLevel == Storage::Synchronization::ChangeLevel::Minimal)
+ return;
+
+ synchronizePropertyDeclarations(type.typeId,
+ type.propertyDeclarations,
+ type.sourceId,
+ insertedAliasPropertyDeclarations,
+ updatedAliasPropertyDeclarations,
+ propertyDeclarationIds);
+ synchronizeFunctionDeclarations(type.typeId, type.functionDeclarations);
+ synchronizeSignalDeclarations(type.typeId, type.signalDeclarations);
+ synchronizeEnumerationDeclarations(type.typeId, type.enumerationDeclarations);
+}
+
+void ProjectStorage::syncDeclarations(Storage::Synchronization::Types &types,
+ AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
+ AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
+ PropertyDeclarations &relinkablePropertyDeclarations)
+{
+ NanotraceHR::Tracer tracer{"synchronize declaration"_t, projectStorageCategory()};
+
+ PropertyDeclarationIds propertyDeclarationIds;
+ propertyDeclarationIds.reserve(types.size() * 10);
+
+ for (auto &&type : types)
+ syncDeclarations(type,
+ insertedAliasPropertyDeclarations,
+ updatedAliasPropertyDeclarations,
+ propertyDeclarationIds);
+
+ removeRelinkableEntries(relinkablePropertyDeclarations,
+ propertyDeclarationIds,
+ PropertyCompare<PropertyDeclaration>{});
+}
+
+void ProjectStorage::syncDefaultProperties(Storage::Synchronization::Types &types)
+{
+ NanotraceHR::Tracer tracer{"synchronize default properties"_t, projectStorageCategory()};
+
+ auto range = selectTypesWithDefaultPropertyStatement.range<TypeWithDefaultPropertyView>();
+
+ auto compareKey = [](const TypeWithDefaultPropertyView &view,
+ const Storage::Synchronization::Type &value) {
+ return view.typeId - value.typeId;
+ };
+
+ auto insert = [&](const Storage::Synchronization::Type &) {
+
+ };
+
+ auto update = [&](const TypeWithDefaultPropertyView &view,
+ const Storage::Synchronization::Type &value) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"synchronize default properties by update"_t,
+ projectStorageCategory(),
+ keyValue("type id", value.typeId),
+ keyValue("value", value),
+ keyValue("view", view)};
+
+ PropertyDeclarationId valueDefaultPropertyId;
+ if (value.defaultPropertyName.size())
+ valueDefaultPropertyId = fetchPropertyDeclarationByTypeIdAndNameUngarded(value.typeId,
+ value.defaultPropertyName)
+ .propertyDeclarationId;
+
+ if (compareInvalidAreTrue(valueDefaultPropertyId, view.defaultPropertyId))
+ return Sqlite::UpdateChange::No;
+
+ updateDefaultPropertyIdStatement.write(value.typeId, valueDefaultPropertyId);
+
+ tracer.end(keyValue("updated", "yes"),
+ keyValue("default property id", valueDefaultPropertyId));
+
+ return Sqlite::UpdateChange::Update;
+ };
+
+ auto remove = [&](const TypeWithDefaultPropertyView &) {};
+
+ Sqlite::insertUpdateDelete(range, types, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::resetDefaultPropertiesIfChanged(Storage::Synchronization::Types &types)
+{
+ NanotraceHR::Tracer tracer{"reset changed default properties"_t, projectStorageCategory()};
+
+ auto range = selectTypesWithDefaultPropertyStatement.range<TypeWithDefaultPropertyView>();
+
+ auto compareKey = [](const TypeWithDefaultPropertyView &view,
+ const Storage::Synchronization::Type &value) {
+ return view.typeId - value.typeId;
+ };
+
+ auto insert = [&](const Storage::Synchronization::Type &) {
+
+ };
+
+ auto update = [&](const TypeWithDefaultPropertyView &view,
+ const Storage::Synchronization::Type &value) {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"reset changed default properties by update"_t,
+ projectStorageCategory(),
+ keyValue("type id", value.typeId),
+ keyValue("value", value),
+ keyValue("view", view)};
+
+ PropertyDeclarationId valueDefaultPropertyId;
+ if (value.defaultPropertyName.size()) {
+ auto optionalValueDefaultPropertyId = fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(
+ value.typeId, value.defaultPropertyName);
+ if (optionalValueDefaultPropertyId)
+ valueDefaultPropertyId = optionalValueDefaultPropertyId->propertyDeclarationId;
+ }
+
+ if (compareInvalidAreTrue(valueDefaultPropertyId, view.defaultPropertyId))
+ return Sqlite::UpdateChange::No;
+
+ updateDefaultPropertyIdStatement.write(value.typeId, Sqlite::NullValue{});
+
+ tracer.end(keyValue("updated", "yes"));
+
+ return Sqlite::UpdateChange::Update;
+ };
+
+ auto remove = [&](const TypeWithDefaultPropertyView &) {};
+
+ Sqlite::insertUpdateDelete(range, types, compareKey, insert, update, remove);
+}
+
+void ProjectStorage::checkForPrototypeChainCycle(TypeId typeId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"check for prototype chain cycle"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto callback = [=](TypeId currentTypeId) {
+ if (typeId == currentTypeId)
+ throw PrototypeChainCycle{};
+ };
+
+ selectPrototypeAndExtensionIdsStatement.readCallback(callback, typeId);
+}
+
+void ProjectStorage::checkForAliasChainCycle(PropertyDeclarationId propertyDeclarationId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"check for alias chain cycle"_t,
+ projectStorageCategory(),
+ keyValue("property declaration id", propertyDeclarationId)};
+ auto callback = [=](PropertyDeclarationId currentPropertyDeclarationId) {
+ if (propertyDeclarationId == currentPropertyDeclarationId)
+ throw AliasChainCycle{};
+ };
+
+ selectPropertyDeclarationIdsForAliasChainStatement.readCallback(callback, propertyDeclarationId);
+}
+
+std::pair<TypeId, ImportedTypeNameId> ProjectStorage::fetchImportedTypeNameIdAndTypeId(
+ const Storage::Synchronization::ImportedTypeName &typeName, SourceId sourceId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch imported type name id and type id"_t,
+ projectStorageCategory(),
+ keyValue("imported type name", typeName),
+ keyValue("source id", sourceId)};
+
+ TypeId typeId;
+ ImportedTypeNameId typeNameId;
+ if (!std::visit([](auto &&typeName_) -> bool { return typeName_.name.isEmpty(); }, typeName)) {
+ typeNameId = fetchImportedTypeNameId(typeName, sourceId);
+
+ typeId = fetchTypeId(typeNameId);
+
+ tracer.end(keyValue("type id", typeId), keyValue("type name id", typeNameId));
+
+ if (!typeId)
+ throw TypeNameDoesNotExists{fetchImportedTypeName(typeNameId), sourceId};
+ }
+
+ return {typeId, typeNameId};
+}
+
+void ProjectStorage::syncPrototypeAndExtension(Storage::Synchronization::Type &type, TypeIds &typeIds)
+{
+ if (type.changeLevel == Storage::Synchronization::ChangeLevel::Minimal)
+ return;
+
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"synchronize prototype and extension"_t,
+ projectStorageCategory(),
+ keyValue("prototype", type.prototype),
+ keyValue("extension", type.extension),
+ keyValue("type id", type.typeId),
+ keyValue("source id", type.sourceId)};
+
+ auto [prototypeId, prototypeTypeNameId] = fetchImportedTypeNameIdAndTypeId(type.prototype,
+ type.sourceId);
+ auto [extensionId, extensionTypeNameId] = fetchImportedTypeNameIdAndTypeId(type.extension,
+ type.sourceId);
+
+ updatePrototypeAndExtensionStatement.write(type.typeId,
+ prototypeId,
+ prototypeTypeNameId,
+ extensionId,
+ extensionTypeNameId);
+
+ if (prototypeId || extensionId)
+ checkForPrototypeChainCycle(type.typeId);
+
+ typeIds.push_back(type.typeId);
+
+ tracer.end(keyValue("prototype id", prototypeId),
+ keyValue("prototype type name id", prototypeTypeNameId),
+ keyValue("extension id", extensionId),
+ keyValue("extension type name id", extensionTypeNameId));
+}
+
+void ProjectStorage::syncPrototypesAndExtensions(Storage::Synchronization::Types &types,
+ Prototypes &relinkablePrototypes,
+ Prototypes &relinkableExtensions)
+{
+ NanotraceHR::Tracer tracer{"synchronize prototypes and extensions"_t, projectStorageCategory()};
+
+ TypeIds typeIds;
+ typeIds.reserve(types.size());
+
+ for (auto &type : types)
+ syncPrototypeAndExtension(type, typeIds);
+
+ removeRelinkableEntries(relinkablePrototypes, typeIds, TypeCompare<Prototype>{});
+ removeRelinkableEntries(relinkableExtensions, typeIds, TypeCompare<Prototype>{});
+}
+
+ImportId ProjectStorage::fetchImportId(SourceId sourceId, const Storage::Import &import) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch imported type name id"_t,
+ projectStorageCategory(),
+ keyValue("import", import),
+ keyValue("source id", sourceId)};
+
+ ImportId importId;
+ if (import.version) {
+ importId = selectImportIdBySourceIdAndModuleIdAndVersionStatement.value<ImportId>(
+ sourceId, import.moduleId, import.version.major.value, import.version.minor.value);
+ } else if (import.version.major) {
+ importId = selectImportIdBySourceIdAndModuleIdAndMajorVersionStatement
+ .value<ImportId>(sourceId, import.moduleId, import.version.major.value);
+ } else {
+ importId = selectImportIdBySourceIdAndModuleIdStatement.value<ImportId>(sourceId,
+ import.moduleId);
+ }
+
+ tracer.end(keyValue("import id", importId));
+
+ return importId;
+}
+
+ImportedTypeNameId ProjectStorage::fetchImportedTypeNameId(
+ const Storage::Synchronization::ImportedTypeName &name, SourceId sourceId)
+{
+ struct Inspect
+ {
+ auto operator()(const Storage::Synchronization::ImportedType &importedType)
+ {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch imported type name id"_t,
+ projectStorageCategory(),
+ keyValue("imported type name", importedType.name),
+ keyValue("source id", sourceId),
+ keyValue("type name kind", "exported"sv)};
+
+ return storage.fetchImportedTypeNameId(Storage::Synchronization::TypeNameKind::Exported,
+ sourceId,
+ importedType.name);
+ }
+
+ auto operator()(const Storage::Synchronization::QualifiedImportedType &importedType)
+ {
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch imported type name id"_t,
+ projectStorageCategory(),
+ keyValue("imported type name", importedType.name),
+ keyValue("import", importedType.import),
+ keyValue("type name kind", "qualified exported"sv)};
+
+ ImportId importId = storage.fetchImportId(sourceId, importedType.import);
+
+ auto importedTypeNameId = storage.fetchImportedTypeNameId(
+ Storage::Synchronization::TypeNameKind::QualifiedExported, importId, importedType.name);
+
+ tracer.end(keyValue("import id", importId), keyValue("source id", sourceId));
+
+ return importedTypeNameId;
+ }
+
+ ProjectStorage &storage;
+ SourceId sourceId;
+ };
+
+ return std::visit(Inspect{*this, sourceId}, name);
+}
+
+TypeId ProjectStorage::fetchTypeId(ImportedTypeNameId typeNameId) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch type id with type name kind"_t,
+ projectStorageCategory(),
+ keyValue("type name id", typeNameId)};
+
+ auto kind = selectKindFromImportedTypeNamesStatement.value<Storage::Synchronization::TypeNameKind>(
+ typeNameId);
+
+ auto typeId = fetchTypeId(typeNameId, kind);
+
+ tracer.end(keyValue("type id", typeId), keyValue("type name kind", kind));
+
+ return typeId;
+}
+
+Utils::SmallString ProjectStorage::fetchImportedTypeName(ImportedTypeNameId typeNameId) const
+{
+ return selectNameFromImportedTypeNamesStatement.value<Utils::SmallString>(typeNameId);
+}
+
+TypeId ProjectStorage::fetchTypeId(ImportedTypeNameId typeNameId,
+ Storage::Synchronization::TypeNameKind kind) const
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch type id"_t,
+ projectStorageCategory(),
+ keyValue("type name id", typeNameId),
+ keyValue("type name kind", kind)};
+
+ TypeId typeId;
+ if (kind == Storage::Synchronization::TypeNameKind::Exported) {
+ typeId = selectTypeIdForImportedTypeNameNamesStatement.value<TypeId>(typeNameId);
+ } else {
+ typeId = selectTypeIdForQualifiedImportedTypeNameNamesStatement.value<TypeId>(typeNameId);
+ }
+
+ tracer.end(keyValue("type id", typeId));
+
+ return typeId;
+}
+
+std::optional<ProjectStorage::FetchPropertyDeclarationResult>
+ProjectStorage::fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(TypeId typeId,
+ Utils::SmallStringView name)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch optional property declaration by type id and name ungarded"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId),
+ keyValue("property name", name)};
+
+ auto propertyDeclarationId = fetchPropertyDeclarationId(typeId, name);
+ auto propertyDeclaration = selectPropertyDeclarationResultByPropertyDeclarationIdStatement
+ .optionalValue<FetchPropertyDeclarationResult>(
+ propertyDeclarationId);
+
+ tracer.end(keyValue("property declaration", propertyDeclaration));
+
+ return propertyDeclaration;
+}
+
+ProjectStorage::FetchPropertyDeclarationResult ProjectStorage::fetchPropertyDeclarationByTypeIdAndNameUngarded(
+ TypeId typeId, Utils::SmallStringView name)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch property declaration by type id and name ungarded"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId),
+ keyValue("property name", name)};
+
+ auto propertyDeclaration = fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(typeId, name);
+ tracer.end(keyValue("property declaration", propertyDeclaration));
+
+ if (propertyDeclaration)
+ return *propertyDeclaration;
+
+ throw PropertyNameDoesNotExists{};
+}
+
+PropertyDeclarationId ProjectStorage::fetchPropertyDeclarationIdByTypeIdAndNameUngarded(
+ TypeId typeId, Utils::SmallStringView name)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch property declaration id by type id and name ungarded"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId),
+ keyValue("property name", name)};
+
+ auto propertyDeclarationId = fetchPropertyDeclarationId(typeId, name);
+
+ tracer.end(keyValue("property declaration id", propertyDeclarationId));
+
+ if (propertyDeclarationId)
+ return propertyDeclarationId;
+
+ throw PropertyNameDoesNotExists{};
+}
+
+SourceContextId ProjectStorage::readSourceContextId(Utils::SmallStringView sourceContextPath)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"read source context id"_t,
+ projectStorageCategory(),
+ keyValue("source context path", sourceContextPath)};
+
+ auto sourceContextId = selectSourceContextIdFromSourceContextsBySourceContextPathStatement
+ .value<SourceContextId>(sourceContextPath);
+
+ tracer.end(keyValue("source context id", sourceContextId));
+
+ return sourceContextId;
+}
+
+SourceContextId ProjectStorage::writeSourceContextId(Utils::SmallStringView sourceContextPath)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"write source context id"_t,
+ projectStorageCategory(),
+ keyValue("source context path", sourceContextPath)};
+
+ insertIntoSourceContextsStatement.write(sourceContextPath);
+
+ auto sourceContextId = SourceContextId::create(static_cast<int>(database.lastInsertedRowId()));
+
+ tracer.end(keyValue("source context id", sourceContextId));
+
+ return sourceContextId;
+}
+
+SourceId ProjectStorage::writeSourceId(SourceContextId sourceContextId,
+ Utils::SmallStringView sourceName)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"write source id"_t,
+ projectStorageCategory(),
+ keyValue("source context id", sourceContextId),
+ keyValue("source name", sourceName)};
+
+ insertIntoSourcesStatement.write(sourceContextId, sourceName);
+
+ auto sourceId = SourceId::create(static_cast<int>(database.lastInsertedRowId()));
+
+ tracer.end(keyValue("source id", sourceId));
+
+ return sourceId;
+}
+
+SourceId ProjectStorage::readSourceId(SourceContextId sourceContextId,
+ Utils::SmallStringView sourceName)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"read source id"_t,
+ projectStorageCategory(),
+ keyValue("source context id", sourceContextId),
+ keyValue("source name", sourceName)};
+
+ auto sourceId = selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatement
+ .value<SourceId>(sourceContextId, sourceName);
+
+ tracer.end(keyValue("source id", sourceId));
+
+ return sourceId;
+}
+
+Storage::Synchronization::ExportedTypes ProjectStorage::fetchExportedTypes(TypeId typeId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch exported type"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto exportedTypes = selectExportedTypesByTypeIdStatement
+ .values<Storage::Synchronization::ExportedType, 12>(typeId);
+
+ tracer.end(keyValue("exported types", exportedTypes));
+
+ return exportedTypes;
+}
+
+Storage::Synchronization::PropertyDeclarations ProjectStorage::fetchPropertyDeclarations(TypeId typeId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch property declarations"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ auto propertyDeclarations = selectPropertyDeclarationsByTypeIdStatement
+ .values<Storage::Synchronization::PropertyDeclaration, 24>(typeId);
+
+ tracer.end(keyValue("property declarations", propertyDeclarations));
+
+ return propertyDeclarations;
+}
+
+Storage::Synchronization::FunctionDeclarations ProjectStorage::fetchFunctionDeclarations(TypeId typeId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch signal declarations"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ Storage::Synchronization::FunctionDeclarations functionDeclarations;
+
+ auto callback = [&](Utils::SmallStringView name,
+ Utils::SmallStringView returnType,
+ FunctionDeclarationId functionDeclarationId) {
+ auto &functionDeclaration = functionDeclarations.emplace_back(name, returnType);
+ functionDeclaration.parameters = selectFunctionParameterDeclarationsStatement
+ .values<Storage::Synchronization::ParameterDeclaration, 8>(
+ functionDeclarationId);
+ };
+
+ selectFunctionDeclarationsForTypeIdWithoutSignatureStatement.readCallback(callback, typeId);
+
+ tracer.end(keyValue("function declarations", functionDeclarations));
+
+ return functionDeclarations;
+}
+
+Storage::Synchronization::SignalDeclarations ProjectStorage::fetchSignalDeclarations(TypeId typeId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch signal declarations"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ Storage::Synchronization::SignalDeclarations signalDeclarations;
+
+ auto callback = [&](Utils::SmallStringView name, SignalDeclarationId signalDeclarationId) {
+ auto &signalDeclaration = signalDeclarations.emplace_back(name);
+ signalDeclaration.parameters = selectSignalParameterDeclarationsStatement
+ .values<Storage::Synchronization::ParameterDeclaration, 8>(
+ signalDeclarationId);
+ };
+
+ selectSignalDeclarationsForTypeIdWithoutSignatureStatement.readCallback(callback, typeId);
+
+ tracer.end(keyValue("signal declarations", signalDeclarations));
+
+ return signalDeclarations;
+}
+
+Storage::Synchronization::EnumerationDeclarations ProjectStorage::fetchEnumerationDeclarations(TypeId typeId)
+{
+ using NanotraceHR::keyValue;
+ NanotraceHR::Tracer tracer{"fetch enumeration declarations"_t,
+ projectStorageCategory(),
+ keyValue("type id", typeId)};
+
+ Storage::Synchronization::EnumerationDeclarations enumerationDeclarations;
+
+ auto callback = [&](Utils::SmallStringView name,
+ EnumerationDeclarationId enumerationDeclarationId) {
+ enumerationDeclarations.emplace_back(
+ name,
+ selectEnumeratorDeclarationStatement
+ .values<Storage::Synchronization::EnumeratorDeclaration, 8>(enumerationDeclarationId));
+ };
+
+ selectEnumerationDeclarationsForTypeIdWithoutEnumeratorDeclarationsStatement.readCallback(callback,
+ typeId);
+
+ tracer.end(keyValue("enumeration declarations", enumerationDeclarations));
+
+ return enumerationDeclarations;
+}
+
+} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h
index 70d5e92b25..d7687a8c6f 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h
@@ -33,10 +33,10 @@ using namespace NanotraceHR::Literals;
using ProjectStorageTracing::projectStorageCategory;
-template<typename Database>
class ProjectStorage final : public ProjectStorageInterface
{
- friend Storage::Info::CommonTypeCache<Database>;
+ using Database = Sqlite::Database;
+ friend Storage::Info::CommonTypeCache<ProjectStorageType>;
public:
template<int ResultCount, int BindParameterCount = 0>
@@ -46,655 +46,79 @@ public:
template<int BindParameterCount>
using WriteStatement = typename Database::template WriteStatement<BindParameterCount>;
- ProjectStorage(Database &database, bool isInitialized)
- : database{database}
- , exclusiveTransaction{database}
- , initializer{database, isInitialized}
- {
- NanotraceHR::Tracer tracer{"initialize"_t, projectStorageCategory()};
-
- exclusiveTransaction.commit();
+ ProjectStorage(Database &database, bool isInitialized);
+ ~ProjectStorage();
- database.walCheckpointFull();
+ void synchronize(Storage::Synchronization::SynchronizationPackage package) override;
- moduleCache.populate();
- }
+ void synchronizeDocumentImports(Storage::Imports imports, SourceId sourceId) override;
- void synchronize(Storage::Synchronization::SynchronizationPackage package) override
- {
- NanotraceHR::Tracer tracer{"synchronize"_t, projectStorageCategory()};
-
- TypeIds deletedTypeIds;
- Sqlite::withImmediateTransaction(database, [&] {
- AliasPropertyDeclarations insertedAliasPropertyDeclarations;
- AliasPropertyDeclarations updatedAliasPropertyDeclarations;
-
- AliasPropertyDeclarations relinkableAliasPropertyDeclarations;
- PropertyDeclarations relinkablePropertyDeclarations;
- Prototypes relinkablePrototypes;
- Prototypes relinkableExtensions;
-
- TypeIds updatedTypeIds;
- updatedTypeIds.reserve(package.types.size());
-
- TypeIds typeIdsToBeDeleted;
-
- std::sort(package.updatedSourceIds.begin(), package.updatedSourceIds.end());
-
- synchronizeFileStatuses(package.fileStatuses, package.updatedFileStatusSourceIds);
- synchronizeImports(package.imports,
- package.updatedSourceIds,
- package.moduleDependencies,
- package.updatedModuleDependencySourceIds,
- package.moduleExportedImports,
- package.updatedModuleIds);
- synchronizeTypes(package.types,
- updatedTypeIds,
- insertedAliasPropertyDeclarations,
- updatedAliasPropertyDeclarations,
- relinkableAliasPropertyDeclarations,
- relinkablePropertyDeclarations,
- relinkablePrototypes,
- relinkableExtensions,
- package.updatedSourceIds);
- synchronizeTypeAnnotations(package.typeAnnotations,
- package.updatedTypeAnnotationSourceIds);
- synchronizePropertyEditorQmlPaths(package.propertyEditorQmlPaths,
- package.updatedPropertyEditorQmlPathSourceIds);
-
- deleteNotUpdatedTypes(updatedTypeIds,
- package.updatedSourceIds,
- typeIdsToBeDeleted,
- relinkableAliasPropertyDeclarations,
- relinkablePropertyDeclarations,
- relinkablePrototypes,
- relinkableExtensions,
- deletedTypeIds);
-
- relink(relinkableAliasPropertyDeclarations,
- relinkablePropertyDeclarations,
- relinkablePrototypes,
- relinkableExtensions,
- deletedTypeIds);
-
- linkAliases(insertedAliasPropertyDeclarations, updatedAliasPropertyDeclarations);
-
- synchronizeProjectDatas(package.projectDatas, package.updatedProjectSourceIds);
-
- commonTypeCache_.resetTypeIds();
- });
-
- callRefreshMetaInfoCallback(deletedTypeIds);
- }
-
- void synchronizeDocumentImports(Storage::Imports imports, SourceId sourceId) override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"synchronize document imports"_t,
- projectStorageCategory(),
- keyValue("imports", imports),
- keyValue("source id", sourceId)};
+ void addObserver(ProjectStorageObserver *observer) override;
- Sqlite::withImmediateTransaction(database, [&] {
- synchronizeDocumentImports(imports,
- {sourceId},
- Storage::Synchronization::ImportKind::Import);
- });
- }
+ void removeObserver(ProjectStorageObserver *observer) override;
- void addObserver(ProjectStorageObserver *observer) override
- {
- NanotraceHR::Tracer tracer{"add observer"_t, projectStorageCategory()};
- observers.push_back(observer);
- }
+ ModuleId moduleId(Utils::SmallStringView moduleName) const override;
- void removeObserver(ProjectStorageObserver *observer) override
- {
- NanotraceHR::Tracer tracer{"remove observer"_t, projectStorageCategory()};
- observers.removeOne(observer);
- }
-
- ModuleId moduleId(Utils::SmallStringView moduleName) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get module id"_t,
- projectStorageCategory(),
- keyValue("module name", moduleName)};
-
- auto moduleId = moduleCache.id(moduleName);
-
- tracer.end(keyValue("module id", moduleId));
-
- return moduleId;
- }
-
- Utils::SmallString moduleName(ModuleId moduleId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get module name"_t,
- projectStorageCategory(),
- keyValue("module id", moduleId)};
-
- if (!moduleId)
- throw ModuleDoesNotExists{};
-
- auto moduleName = moduleCache.value(moduleId);
-
- tracer.end(keyValue("module name", moduleName));
-
- return moduleName;
- }
+ Utils::SmallString moduleName(ModuleId moduleId) const override;
TypeId typeId(ModuleId moduleId,
Utils::SmallStringView exportedTypeName,
- Storage::Version version) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get type id by exported name"_t,
- projectStorageCategory(),
- keyValue("module id", moduleId),
- keyValue("exported type name", exportedTypeName),
- keyValue("version", version)};
-
- TypeId typeId;
-
- if (version.minor) {
- typeId = selectTypeIdByModuleIdAndExportedNameAndVersionStatement
- .template valueWithTransaction<TypeId>(moduleId,
- exportedTypeName,
- version.major.value,
- version.minor.value);
-
- } else if (version.major) {
- typeId = selectTypeIdByModuleIdAndExportedNameAndMajorVersionStatement
- .template valueWithTransaction<TypeId>(moduleId,
- exportedTypeName,
- version.major.value);
-
- } else {
- typeId = selectTypeIdByModuleIdAndExportedNameStatement
- .template valueWithTransaction<TypeId>(moduleId, exportedTypeName);
- }
-
- tracer.end(keyValue("type id", typeId));
-
- return typeId;
- }
-
- TypeId typeId(ImportedTypeNameId typeNameId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get type id by imported type name"_t,
- projectStorageCategory(),
- keyValue("imported type name id", typeNameId)};
-
- auto typeId = Sqlite::withDeferredTransaction(database,
- [&] { return fetchTypeId(typeNameId); });
-
- tracer.end(keyValue("type id", typeId));
-
- return typeId;
- }
-
- QVarLengthArray<TypeId, 256> typeIds(ModuleId moduleId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get type ids by module id"_t,
- projectStorageCategory(),
- keyValue("module id", moduleId)};
-
- auto typeIds = selectTypeIdsByModuleIdStatement
- .template valuesWithTransaction<QVarLengthArray<TypeId, 256>>(moduleId);
-
- tracer.end(keyValue("type ids", typeIds));
-
- return typeIds;
- }
-
- Storage::Info::ExportedTypeNames exportedTypeNames(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get exported type names by type id"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- auto exportedTypenames = selectExportedTypesByTypeIdStatement
- .template valuesWithTransaction<Storage::Info::ExportedTypeName, 4>(
- typeId);
-
- tracer.end(keyValue("exported type names", exportedTypenames));
+ Storage::Version version) const override;
- return exportedTypenames;
- }
-
- Storage::Info::ExportedTypeNames exportedTypeNames(TypeId typeId, SourceId sourceId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get exported type names by source id"_t,
- projectStorageCategory(),
- keyValue("type id", typeId),
- keyValue("source id", sourceId)};
-
- auto exportedTypenames = selectExportedTypesByTypeIdAndSourceIdStatement
- .template valuesWithTransaction<Storage::Info::ExportedTypeName,
- 4>(typeId, sourceId);
-
- tracer.end(keyValue("exported type names", exportedTypenames));
-
- return exportedTypenames;
- }
-
- ImportId importId(const Storage::Import &import) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get import id by import"_t,
- projectStorageCategory(),
- keyValue("import", import)};
-
- auto importId = Sqlite::withDeferredTransaction(database, [&] {
- return fetchImportId(import.sourceId, import);
- });
-
- tracer.end(keyValue("import id", importId));
-
- return importId;
- }
-
- ImportedTypeNameId importedTypeNameId(ImportId importId, Utils::SmallStringView typeName) override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get imported type name id by import id"_t,
- projectStorageCategory(),
- keyValue("import id", importId),
- keyValue("imported type name", typeName)};
-
- auto importedTypeNameId = Sqlite::withDeferredTransaction(database, [&] {
- return fetchImportedTypeNameId(Storage::Synchronization::TypeNameKind::QualifiedExported,
- importId,
- typeName);
- });
-
- tracer.end(keyValue("imported type name id", importedTypeNameId));
-
- return importedTypeNameId;
- }
-
- ImportedTypeNameId importedTypeNameId(SourceId sourceId, Utils::SmallStringView typeName) override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get imported type name id by source id"_t,
- projectStorageCategory(),
- keyValue("source id", sourceId),
- keyValue("imported type name", typeName)};
-
- auto importedTypeNameId = Sqlite::withDeferredTransaction(database, [&] {
- return fetchImportedTypeNameId(Storage::Synchronization::TypeNameKind::Exported,
- sourceId,
- typeName);
- });
-
- tracer.end(keyValue("imported type name id", importedTypeNameId));
-
- return importedTypeNameId;
- }
-
- QVarLengthArray<PropertyDeclarationId, 128> propertyDeclarationIds(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get property declaration ids"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
+ TypeId typeId(ImportedTypeNameId typeNameId) const override;
- auto propertyDeclarationIds = Sqlite::withDeferredTransaction(database, [&] {
- return fetchPropertyDeclarationIds(typeId);
- });
+ QVarLengthArray<TypeId, 256> typeIds(ModuleId moduleId) const override;
- std::sort(propertyDeclarationIds.begin(), propertyDeclarationIds.end());
+ Storage::Info::ExportedTypeNames exportedTypeNames(TypeId typeId) const override;
- tracer.end(keyValue("property declaration ids", propertyDeclarationIds));
+ Storage::Info::ExportedTypeNames exportedTypeNames(TypeId typeId, SourceId sourceId) const override;
- return propertyDeclarationIds;
- }
+ ImportId importId(const Storage::Import &import) const override;
- QVarLengthArray<PropertyDeclarationId, 128> localPropertyDeclarationIds(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get local property declaration ids"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
+ ImportedTypeNameId importedTypeNameId(ImportId importId, Utils::SmallStringView typeName) override;
- auto propertyDeclarationIds = selectLocalPropertyDeclarationIdsForTypeStatement
- .template valuesWithTransaction<
- QVarLengthArray<PropertyDeclarationId, 128>>(typeId);
+ ImportedTypeNameId importedTypeNameId(SourceId sourceId, Utils::SmallStringView typeName) override;
- tracer.end(keyValue("property declaration ids", propertyDeclarationIds));
+ QVarLengthArray<PropertyDeclarationId, 128> propertyDeclarationIds(TypeId typeId) const override;
- return propertyDeclarationIds;
- }
+ QVarLengthArray<PropertyDeclarationId, 128> localPropertyDeclarationIds(TypeId typeId) const override;
PropertyDeclarationId propertyDeclarationId(TypeId typeId,
- Utils::SmallStringView propertyName) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get property declaration id"_t,
- projectStorageCategory(),
- keyValue("type id", typeId),
- keyValue("property name", propertyName)};
-
- auto propertyDeclarationId = Sqlite::withDeferredTransaction(database, [&] {
- return fetchPropertyDeclarationId(typeId, propertyName);
- });
-
- tracer.end(keyValue("property declaration id", propertyDeclarationId));
-
- return propertyDeclarationId;
- }
+ Utils::SmallStringView propertyName) const override;
PropertyDeclarationId localPropertyDeclarationId(TypeId typeId,
- Utils::SmallStringView propertyName) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get local property declaration id"_t,
- projectStorageCategory(),
- keyValue("type id", typeId),
- keyValue("property name", propertyName)};
-
- auto propertyDeclarationId = selectLocalPropertyDeclarationIdForTypeAndPropertyNameStatement
- .template valueWithTransaction<PropertyDeclarationId>(
- typeId, propertyName);
-
- tracer.end(keyValue("property declaration id", propertyDeclarationId));
-
- return propertyDeclarationId;
- }
-
- PropertyDeclarationId defaultPropertyDeclarationId(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get default property declaration id"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
+ Utils::SmallStringView propertyName) const;
- auto propertyDeclarationId = Sqlite::withDeferredTransaction(database, [&] {
- return fetchDefaultPropertyDeclarationId(typeId);
- });
-
- tracer.end(keyValue("property declaration id", propertyDeclarationId));
-
- return propertyDeclarationId;
- }
+ PropertyDeclarationId defaultPropertyDeclarationId(TypeId typeId) const override;
std::optional<Storage::Info::PropertyDeclaration> propertyDeclaration(
- PropertyDeclarationId propertyDeclarationId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get property declaration"_t,
- projectStorageCategory(),
- keyValue("property declaration id", propertyDeclarationId)};
-
- auto propertyDeclaration = selectPropertyDeclarationForPropertyDeclarationIdStatement
- .template optionalValueWithTransaction<Storage::Info::PropertyDeclaration>(
- propertyDeclarationId);
-
- tracer.end(keyValue("property declaration", propertyDeclaration));
-
- return propertyDeclaration;
- }
-
- std::optional<Storage::Info::Type> type(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get type"_t, projectStorageCategory(), keyValue("type id", typeId)};
-
- auto type = selectInfoTypeByTypeIdStatement
- .template optionalValueWithTransaction<Storage::Info::Type>(typeId);
-
- tracer.end(keyValue("type", type));
-
- return type;
- }
-
- Utils::PathString typeIconPath(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get type icon path"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- auto typeIconPath = selectTypeIconPathStatement.template valueWithTransaction<Utils::PathString>(
- typeId);
-
- tracer.end(keyValue("type icon path", typeIconPath));
-
- return typeIconPath;
- }
-
- Storage::Info::TypeHints typeHints(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get type hints"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- auto typeHints = selectTypeHintsStatement
- .template valuesWithTransaction<Storage::Info::TypeHints, 4>(typeId);
-
- tracer.end(keyValue("type hints", typeHints));
-
- return typeHints;
- }
-
- SmallSourceIds<4> typeAnnotationSourceIds(SourceId directoryId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get type annotaion source ids"_t,
- projectStorageCategory(),
- keyValue("source id", directoryId)};
-
- auto sourceIds = selectTypeAnnotationSourceIdsStatement
- .template valuesWithTransaction<SmallSourceIds<4>>(directoryId);
-
- tracer.end(keyValue("source ids", sourceIds));
-
- return sourceIds;
- }
-
- SmallSourceIds<64> typeAnnotationDirectorySourceIds() const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get type annotaion source ids"_t, projectStorageCategory()};
-
- auto sourceIds = selectTypeAnnotationDirectorySourceIdsStatement
- .template valuesWithTransaction<SmallSourceIds<64>>();
-
- tracer.end(keyValue("source ids", sourceIds));
-
- return sourceIds;
- }
-
- Storage::Info::ItemLibraryEntries itemLibraryEntries(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get item library entries by type id"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- using Storage::Info::ItemLibraryProperties;
- Storage::Info::ItemLibraryEntries entries;
-
- auto callback = [&](TypeId typeId_,
- Utils::SmallStringView name,
- Utils::SmallStringView iconPath,
- Utils::SmallStringView category,
- Utils::SmallStringView import,
- Utils::SmallStringView toolTip,
- Utils::SmallStringView properties,
- Utils::SmallStringView extraFilePaths,
- Utils::SmallStringView templatePath) {
- auto &last = entries.emplace_back(
- typeId_, name, iconPath, category, import, toolTip, templatePath);
- if (properties.size())
- selectItemLibraryPropertiesStatement.readTo(last.properties, properties);
- if (extraFilePaths.size())
- selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths);
- };
-
- selectItemLibraryEntriesByTypeIdStatement.readCallbackWithTransaction(callback, typeId);
-
- tracer.end(keyValue("item library entries", entries));
-
- return entries;
- }
-
- Storage::Info::ItemLibraryEntries itemLibraryEntries(ImportId importId) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get item library entries by import id"_t,
- projectStorageCategory(),
- keyValue("import id", importId)};
-
- using Storage::Info::ItemLibraryProperties;
- Storage::Info::ItemLibraryEntries entries;
-
- auto callback = [&](TypeId typeId_,
- Utils::SmallStringView name,
- Utils::SmallStringView iconPath,
- Utils::SmallStringView category,
- Utils::SmallStringView import,
- Utils::SmallStringView toolTip,
- Utils::SmallStringView properties,
- Utils::SmallStringView extraFilePaths,
- Utils::SmallStringView templatePath) {
- auto &last = entries.emplace_back(
- typeId_, name, iconPath, category, import, toolTip, templatePath);
- if (properties.size())
- selectItemLibraryPropertiesStatement.readTo(last.properties, properties);
- if (extraFilePaths.size())
- selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths);
- };
-
- selectItemLibraryEntriesByTypeIdStatement.readCallbackWithTransaction(callback, importId);
-
- tracer.end(keyValue("item library entries", entries));
-
- return entries;
- }
-
- Storage::Info::ItemLibraryEntries itemLibraryEntries(SourceId sourceId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get item library entries by source id"_t,
- projectStorageCategory(),
- keyValue("source id", sourceId)};
-
- using Storage::Info::ItemLibraryProperties;
- Storage::Info::ItemLibraryEntries entries;
-
- auto callback = [&](TypeId typeId,
- Utils::SmallStringView name,
- Utils::SmallStringView iconPath,
- Utils::SmallStringView category,
- Utils::SmallStringView import,
- Utils::SmallStringView toolTip,
- Utils::SmallStringView properties,
- Utils::SmallStringView extraFilePaths,
- Utils::SmallStringView templatePath) {
- auto &last = entries.emplace_back(
- typeId, name, iconPath, category, import, toolTip, templatePath);
- if (properties.size())
- selectItemLibraryPropertiesStatement.readTo(last.properties, properties);
- if (extraFilePaths.size())
- selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths);
- };
-
- selectItemLibraryEntriesBySourceIdStatement.readCallbackWithTransaction(callback, sourceId);
-
- tracer.end(keyValue("item library entries", entries));
-
- return entries;
- }
-
- Storage::Info::ItemLibraryEntries allItemLibraryEntries() const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get all item library entries"_t, projectStorageCategory()};
-
- using Storage::Info::ItemLibraryProperties;
- Storage::Info::ItemLibraryEntries entries;
-
- auto callback = [&](TypeId typeId,
- Utils::SmallStringView name,
- Utils::SmallStringView iconPath,
- Utils::SmallStringView category,
- Utils::SmallStringView import,
- Utils::SmallStringView toolTip,
- Utils::SmallStringView properties,
- Utils::SmallStringView extraFilePaths,
- Utils::SmallStringView templatePath) {
- auto &last = entries.emplace_back(
- typeId, name, iconPath, category, import, toolTip, templatePath);
- if (properties.size())
- selectItemLibraryPropertiesStatement.readTo(last.properties, properties);
- if (extraFilePaths.size())
- selectItemLibraryExtraFilePathsStatement.readTo(last.extraFilePaths, extraFilePaths);
- };
-
- selectItemLibraryEntriesStatement.readCallbackWithTransaction(callback);
-
- tracer.end(keyValue("item library entries", entries));
-
- return entries;
- }
+ PropertyDeclarationId propertyDeclarationId) const override;
- std::vector<Utils::SmallString> signalDeclarationNames(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get signal names"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
+ std::optional<Storage::Info::Type> type(TypeId typeId) const override;
- auto signalDeclarationNames = selectSignalDeclarationNamesForTypeStatement
- .template valuesWithTransaction<Utils::SmallString, 32>(
- typeId);
+ Utils::PathString typeIconPath(TypeId typeId) const override;
- tracer.end(keyValue("signal names", signalDeclarationNames));
+ Storage::Info::TypeHints typeHints(TypeId typeId) const override;
- return signalDeclarationNames;
- }
+ SmallSourceIds<4> typeAnnotationSourceIds(SourceId directoryId) const override;
- std::vector<Utils::SmallString> functionDeclarationNames(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get function names"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
+ SmallSourceIds<64> typeAnnotationDirectorySourceIds() const override;
- auto functionDeclarationNames = selectFuncionDeclarationNamesForTypeStatement
- .template valuesWithTransaction<Utils::SmallString, 32>(
- typeId);
+ Storage::Info::ItemLibraryEntries itemLibraryEntries(TypeId typeId) const override;
- tracer.end(keyValue("function names", functionDeclarationNames));
+ Storage::Info::ItemLibraryEntries itemLibraryEntries(ImportId importId) const;
- return functionDeclarationNames;
- }
+ Storage::Info::ItemLibraryEntries itemLibraryEntries(SourceId sourceId) const override;
- std::optional<Utils::SmallString> propertyName(PropertyDeclarationId propertyDeclarationId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get property name"_t,
- projectStorageCategory(),
- keyValue("property declaration id", propertyDeclarationId)};
+ Storage::Info::ItemLibraryEntries allItemLibraryEntries() const override;
- auto propertyName = selectPropertyNameStatement
- .template optionalValueWithTransaction<Utils::SmallString>(
- propertyDeclarationId);
+ std::vector<Utils::SmallString> signalDeclarationNames(TypeId typeId) const override;
- tracer.end(keyValue("property name", propertyName));
+ std::vector<Utils::SmallString> functionDeclarationNames(TypeId typeId) const override;
- return propertyName;
- }
+ std::optional<Utils::SmallString> propertyName(PropertyDeclarationId propertyDeclarationId) const override;
- const Storage::Info::CommonTypeCache<ProjectStorageInterface> &commonTypeCache() const override
+ const Storage::Info::CommonTypeCache<ProjectStorageType> &commonTypeCache() const override
{
return commonTypeCache_;
}
@@ -708,7 +132,7 @@ public:
keyValue("module name", std::string_view{moduleName}),
keyValue("type name", std::string_view{typeName})};
- auto typeId = commonTypeCache_.template typeId<moduleName, typeName>();
+ auto typeId = commonTypeCache_.typeId<moduleName, typeName>();
tracer.end(keyValue("type id", typeId));
@@ -722,7 +146,7 @@ public:
NanotraceHR::Tracer tracer{"get builtin type id from common type cache"_t,
projectStorageCategory()};
- auto typeId = commonTypeCache_.template builtinTypeId<BuiltinType>();
+ auto typeId = commonTypeCache_.builtinTypeId<BuiltinType>();
tracer.end(keyValue("type id", typeId));
@@ -736,55 +160,18 @@ public:
NanotraceHR::Tracer tracer{"get builtin type id from common type cache"_t,
projectStorageCategory()};
- auto typeId = commonTypeCache_.template builtinTypeId<builtinType>();
+ auto typeId = commonTypeCache_.builtinTypeId<builtinType>();
tracer.end(keyValue("type id", typeId));
return typeId;
}
- SmallTypeIds<16> prototypeIds(TypeId type) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get prototypes"_t,
- projectStorageCategory(),
- keyValue("type id", type)};
-
- auto prototypeIds = selectPrototypeAndExtensionIdsStatement
- .template valuesWithTransaction<SmallTypeIds<16>>(type);
+ SmallTypeIds<16> prototypeIds(TypeId type) const override;
- tracer.end(keyValue("type ids", prototypeIds));
+ SmallTypeIds<16> prototypeAndSelfIds(TypeId typeId) const override;
- return prototypeIds;
- }
-
- SmallTypeIds<16> prototypeAndSelfIds(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get prototypes and self"_t, projectStorageCategory()};
-
- SmallTypeIds<16> prototypeAndSelfIds;
- prototypeAndSelfIds.push_back(typeId);
-
- selectPrototypeAndExtensionIdsStatement.readToWithTransaction(prototypeAndSelfIds, typeId);
-
- tracer.end(keyValue("type ids", prototypeAndSelfIds));
-
- return prototypeAndSelfIds;
- }
-
- SmallTypeIds<64> heirIds(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"get heirs"_t, projectStorageCategory()};
-
- auto heirIds = selectHeirTypeIdsStatement.template valuesWithTransaction<SmallTypeIds<64>>(
- typeId);
-
- tracer.end(keyValue("type ids", heirIds));
-
- return heirIds;
- }
+ SmallTypeIds<64> heirIds(TypeId typeId) const override;
template<typename... TypeIds>
bool isBasedOn_(TypeId typeId, TypeIds... baseTypeIds) const
@@ -802,8 +189,7 @@ public:
return true;
}
- auto range = selectPrototypeAndExtensionIdsStatement.template rangeWithTransaction<TypeId>(
- typeId);
+ auto range = selectPrototypeAndExtensionIdsStatement.rangeWithTransaction<TypeId>(typeId);
auto isBasedOn = std::any_of(range.begin(), range.end(), [&](TypeId currentTypeId) {
return ((currentTypeId == baseTypeIds) || ...);
@@ -814,35 +200,20 @@ public:
return isBasedOn;
}
- bool isBasedOn(TypeId) const { return false; }
+ bool isBasedOn(TypeId) const;
- bool isBasedOn(TypeId typeId, TypeId id1) const override { return isBasedOn_(typeId, id1); }
+ bool isBasedOn(TypeId typeId, TypeId id1) const override;
- bool isBasedOn(TypeId typeId, TypeId id1, TypeId id2) const override
- {
- return isBasedOn_(typeId, id1, id2);
- }
+ bool isBasedOn(TypeId typeId, TypeId id1, TypeId id2) const override;
- bool isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3) const override
- {
- return isBasedOn_(typeId, id1, id2, id3);
- }
+ bool isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3) const override;
- bool isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4) const override
- {
- return isBasedOn_(typeId, id1, id2, id3, id4);
- }
+ bool isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4) const override;
- bool isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4, TypeId id5) const override
- {
- return isBasedOn_(typeId, id1, id2, id3, id4, id5);
- }
+ bool isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4, TypeId id5) const override;
- bool isBasedOn(
- TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4, TypeId id5, TypeId id6) const override
- {
- return isBasedOn_(typeId, id1, id2, id3, id4, id5, id6);
- }
+ bool isBasedOn(TypeId typeId, TypeId id1, TypeId id2, TypeId id3, TypeId id4, TypeId id5, TypeId id6)
+ const override;
bool isBasedOn(TypeId typeId,
TypeId id1,
@@ -851,361 +222,62 @@ public:
TypeId id4,
TypeId id5,
TypeId id6,
- TypeId id7) const override
- {
- return isBasedOn_(typeId, id1, id2, id3, id4, id5, id6, id7);
- }
-
- TypeId fetchTypeIdByExportedName(Utils::SmallStringView name) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"is based on"_t,
- projectStorageCategory(),
- keyValue("exported type name", name)};
-
- auto typeId = selectTypeIdByExportedNameStatement.template valueWithTransaction<TypeId>(name);
-
- tracer.end(keyValue("type id", typeId));
-
- return typeId;
- }
-
- TypeId fetchTypeIdByModuleIdsAndExportedName(ModuleIds moduleIds, Utils::SmallStringView name) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch type id by module ids and exported name"_t,
- projectStorageCategory(),
- keyValue("module ids", NanotraceHR::array(moduleIds)),
- keyValue("exported type name", name)};
- auto typeId = selectTypeIdByModuleIdsAndExportedNameStatement.template valueWithTransaction<TypeId>(
- static_cast<void *>(moduleIds.data()), static_cast<long long>(moduleIds.size()), name);
-
- tracer.end(keyValue("type id", typeId));
-
- return typeId;
- }
-
- TypeId fetchTypeIdByName(SourceId sourceId, Utils::SmallStringView name)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch type id by name"_t,
- projectStorageCategory(),
- keyValue("source id", sourceId),
- keyValue("internal type name", name)};
-
- auto typeId = selectTypeIdBySourceIdAndNameStatement
- .template valueWithTransaction<TypeId>(sourceId, name);
-
- tracer.end(keyValue("type id", typeId));
-
- return typeId;
- }
-
- Storage::Synchronization::Type fetchTypeByTypeId(TypeId typeId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch type by type id"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- auto type = Sqlite::withDeferredTransaction(database, [&] {
- auto type = selectTypeByTypeIdStatement.template value<Storage::Synchronization::Type>(
- typeId);
-
- type.exportedTypes = fetchExportedTypes(typeId);
- type.propertyDeclarations = fetchPropertyDeclarations(type.typeId);
- type.functionDeclarations = fetchFunctionDeclarations(type.typeId);
- type.signalDeclarations = fetchSignalDeclarations(type.typeId);
- type.enumerationDeclarations = fetchEnumerationDeclarations(type.typeId);
-
- return type;
- });
-
- tracer.end(keyValue("type", type));
-
- return type;
- }
-
- Storage::Synchronization::Types fetchTypes()
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch types"_t, projectStorageCategory()};
-
- auto types = Sqlite::withDeferredTransaction(database, [&] {
- auto types = selectTypesStatement.template values<Storage::Synchronization::Type, 64>();
-
- for (Storage::Synchronization::Type &type : types) {
- type.exportedTypes = fetchExportedTypes(type.typeId);
- type.propertyDeclarations = fetchPropertyDeclarations(type.typeId);
- type.functionDeclarations = fetchFunctionDeclarations(type.typeId);
- type.signalDeclarations = fetchSignalDeclarations(type.typeId);
- type.enumerationDeclarations = fetchEnumerationDeclarations(type.typeId);
- }
-
- return types;
- });
-
- tracer.end(keyValue("type", types));
-
- return types;
- }
-
- SourceContextId fetchSourceContextIdUnguarded(Utils::SmallStringView sourceContextPath)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch source context id unguarded"_t, projectStorageCategory()};
-
- auto sourceContextId = readSourceContextId(sourceContextPath);
-
- return sourceContextId ? sourceContextId : writeSourceContextId(sourceContextPath);
- }
-
- SourceContextId fetchSourceContextId(Utils::SmallStringView sourceContextPath)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch source context id"_t,
- projectStorageCategory(),
- keyValue("source context path", sourceContextPath)};
-
- SourceContextId sourceContextId;
- try {
- sourceContextId = Sqlite::withDeferredTransaction(database, [&] {
- return fetchSourceContextIdUnguarded(sourceContextPath);
- });
- } catch (const Sqlite::ConstraintPreventsModification &) {
- sourceContextId = fetchSourceContextId(sourceContextPath);
- }
-
- tracer.end(keyValue("source context id", sourceContextId));
-
- return sourceContextId;
- }
-
- Utils::PathString fetchSourceContextPath(SourceContextId sourceContextId) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch source context path"_t,
- projectStorageCategory(),
- keyValue("source context id", sourceContextId)};
-
- auto path = Sqlite::withDeferredTransaction(database, [&] {
- auto optionalSourceContextPath = selectSourceContextPathFromSourceContextsBySourceContextIdStatement
- .template optionalValue<Utils::PathString>(
- sourceContextId);
+ TypeId id7) const override;
- if (!optionalSourceContextPath)
- throw SourceContextIdDoesNotExists();
-
- return std::move(*optionalSourceContextPath);
- });
-
- tracer.end(keyValue("source context path", path));
-
- return path;
- }
-
- auto fetchAllSourceContexts() const
- {
- NanotraceHR::Tracer tracer{"fetch all source contexts"_t, projectStorageCategory()};
-
- return selectAllSourceContextsStatement
- .template valuesWithTransaction<Cache::SourceContext, 128>();
- }
+ TypeId fetchTypeIdByExportedName(Utils::SmallStringView name) const;
- SourceId fetchSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch source id"_t,
- projectStorageCategory(),
- keyValue("source context id", sourceContextId),
- keyValue("source name", sourceName)};
-
- auto sourceId = Sqlite::withDeferredTransaction(database, [&] {
- return fetchSourceIdUnguarded(sourceContextId, sourceName);
- });
-
- tracer.end(keyValue("source id", sourceId));
-
- return sourceId;
- }
-
- auto fetchSourceNameAndSourceContextId(SourceId sourceId) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch source name and source context id"_t,
- projectStorageCategory(),
- keyValue("source id", sourceId)};
-
- auto value = selectSourceNameAndSourceContextIdFromSourcesBySourceIdStatement
- .template valueWithTransaction<Cache::SourceNameAndSourceContextId>(sourceId);
-
- if (!value.sourceContextId)
- throw SourceIdDoesNotExists();
-
- tracer.end(keyValue("source name", value.sourceName),
- keyValue("source context id", value.sourceContextId));
-
- return value;
- }
+ TypeId fetchTypeIdByModuleIdsAndExportedName(ModuleIds moduleIds,
+ Utils::SmallStringView name) const;
- void clearSources()
- {
- Sqlite::withImmediateTransaction(database, [&] {
- deleteAllSourceContextsStatement.execute();
- deleteAllSourcesStatement.execute();
- });
- }
+ TypeId fetchTypeIdByName(SourceId sourceId, Utils::SmallStringView name);
- SourceContextId fetchSourceContextId(SourceId sourceId) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch source context id"_t,
- projectStorageCategory(),
- keyValue("source id", sourceId)};
+ Storage::Synchronization::Type fetchTypeByTypeId(TypeId typeId);
- auto sourceContextId = selectSourceContextIdFromSourcesBySourceIdStatement
- .template valueWithTransaction<SourceContextId>(sourceId);
+ Storage::Synchronization::Types fetchTypes();
- if (!sourceContextId)
- throw SourceIdDoesNotExists();
+ SourceContextId fetchSourceContextIdUnguarded(Utils::SmallStringView sourceContextPath);
- tracer.end(keyValue("source context id", sourceContextId));
+ SourceContextId fetchSourceContextId(Utils::SmallStringView sourceContextPath);
- return sourceContextId;
- }
+ Utils::PathString fetchSourceContextPath(SourceContextId sourceContextId) const;
- auto fetchAllSources() const
- {
- NanotraceHR::Tracer tracer{"fetch all sources"_t, projectStorageCategory()};
+ Cache::SourceContexts fetchAllSourceContexts() const;
- return selectAllSourcesStatement.template valuesWithTransaction<Cache::Source, 1024>();
- }
+ SourceId fetchSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName);
- SourceId fetchSourceIdUnguarded(SourceContextId sourceContextId, Utils::SmallStringView sourceName)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch source id unguarded"_t,
- projectStorageCategory(),
- keyValue("source context id", sourceContextId),
- keyValue("source name", sourceName)};
+ Cache::SourceNameAndSourceContextId fetchSourceNameAndSourceContextId(SourceId sourceId) const;
- auto sourceId = readSourceId(sourceContextId, sourceName);
+ void clearSources();
- if (!sourceId)
- sourceId = writeSourceId(sourceContextId, sourceName);
+ SourceContextId fetchSourceContextId(SourceId sourceId) const;
- tracer.end(keyValue("source id", sourceId));
+ Cache::Sources fetchAllSources() const;
- return sourceId;
- }
+ SourceId fetchSourceIdUnguarded(SourceContextId sourceContextId,
+ Utils::SmallStringView sourceName);
auto fetchAllFileStatuses() const
{
NanotraceHR::Tracer tracer{"fetch all file statuses"_t, projectStorageCategory()};
- return selectAllFileStatusesStatement.template rangeWithTransaction<FileStatus>();
- }
-
- FileStatus fetchFileStatus(SourceId sourceId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch file status"_t,
- projectStorageCategory(),
- keyValue("source id", sourceId)};
-
- auto fileStatus = selectFileStatusesForSourceIdStatement
- .template valueWithTransaction<FileStatus>(sourceId);
-
- tracer.end(keyValue("file status", fileStatus));
-
- return fileStatus;
- }
-
- std::optional<Storage::Synchronization::ProjectData> fetchProjectData(SourceId sourceId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch project data"_t,
- projectStorageCategory(),
- keyValue("source id", sourceId)};
-
- auto projectData = selectProjectDataForSourceIdStatement.template optionalValueWithTransaction<
- Storage::Synchronization::ProjectData>(sourceId);
-
- tracer.end(keyValue("project data", projectData));
-
- return projectData;
- }
-
- Storage::Synchronization::ProjectDatas fetchProjectDatas(SourceId projectSourceId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch project datas by source id"_t,
- projectStorageCategory(),
- keyValue("source id", projectSourceId)};
-
- auto projectDatas = selectProjectDatasForSourceIdStatement
- .template valuesWithTransaction<Storage::Synchronization::ProjectData, 1024>(
- projectSourceId);
-
- tracer.end(keyValue("project datas", projectDatas));
-
- return projectDatas;
- }
-
- Storage::Synchronization::ProjectDatas fetchProjectDatas(const SourceIds &projectSourceIds) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch project datas by source ids"_t,
- projectStorageCategory(),
- keyValue("source ids", projectSourceIds)};
-
- auto projectDatas = selectProjectDatasForSourceIdsStatement
- .template valuesWithTransaction<Storage::Synchronization::ProjectData, 64>(
- toIntegers(projectSourceIds));
-
- tracer.end(keyValue("project datas", projectDatas));
-
- return projectDatas;
+ return selectAllFileStatusesStatement.rangeWithTransaction<FileStatus>();
}
- void setPropertyEditorPathId(TypeId typeId, SourceId pathId)
- {
- Sqlite::ImmediateSessionTransaction transaction{database};
+ FileStatus fetchFileStatus(SourceId sourceId) const override;
- upsertPropertyEditorPathIdStatement.write(typeId, pathId);
+ std::optional<Storage::Synchronization::ProjectData> fetchProjectData(SourceId sourceId) const override;
- transaction.commit();
- }
+ Storage::Synchronization::ProjectDatas fetchProjectDatas(SourceId projectSourceId) const override;
- SourceId propertyEditorPathId(TypeId typeId) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"property editor path id"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
+ Storage::Synchronization::ProjectDatas fetchProjectDatas(const SourceIds &projectSourceIds) const;
- auto sourceId = selectPropertyEditorPathIdStatement.template valueWithTransaction<SourceId>(
- typeId);
+ void setPropertyEditorPathId(TypeId typeId, SourceId pathId);
- tracer.end(keyValue("source id", sourceId));
+ SourceId propertyEditorPathId(TypeId typeId) const override;
- return sourceId;
- }
+ Storage::Imports fetchDocumentImports() const;
- Storage::Imports fetchDocumentImports() const
- {
- NanotraceHR::Tracer tracer{"fetch document imports"_t, projectStorageCategory()};
-
- return selectAllDocumentImportForSourceIdStatement
- .template valuesWithTransaction<Storage::Imports>();
- }
-
- void resetForTestsOnly()
- {
- database.clearAllTablesForTestsOnly();
- commonTypeCache_.clearForTestsOnly();
- moduleCache.clearForTestOnly();
- }
+ void resetForTestsOnly();
private:
class ModuleStorageAdapter
@@ -1233,12 +305,11 @@ private:
}
};
+ using Modules = std::vector<Module>;
+
friend ModuleStorageAdapter;
- static bool moduleNameLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept
- {
- return first < second;
- }
+ static bool moduleNameLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept;
using ModuleCache = StorageCache<Utils::PathString,
Utils::SmallStringView,
@@ -1248,57 +319,13 @@ private:
moduleNameLess,
Module>;
- ModuleId fetchModuleId(Utils::SmallStringView moduleName)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch module id"_t,
- projectStorageCategory(),
- keyValue("module name", moduleName)};
-
- auto moduleId = Sqlite::withDeferredTransaction(database, [&] {
- return fetchModuleIdUnguarded(moduleName);
- });
-
- tracer.end(keyValue("module id", moduleId));
-
- return moduleId;
- }
-
- auto fetchModuleName(ModuleId id)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch module name"_t,
- projectStorageCategory(),
- keyValue("module id", id)};
-
- auto moduleName = Sqlite::withDeferredTransaction(database, [&] {
- return fetchModuleNameUnguarded(id);
- });
-
- tracer.end(keyValue("module name", moduleName));
-
- return moduleName;
- }
-
- auto fetchAllModules() const
- {
- NanotraceHR::Tracer tracer{"fetch all modules"_t, projectStorageCategory()};
+ ModuleId fetchModuleId(Utils::SmallStringView moduleName);
- return selectAllModulesStatement.template valuesWithTransaction<Module, 128>();
- }
+ Utils::PathString fetchModuleName(ModuleId id);
- void callRefreshMetaInfoCallback(const TypeIds &deletedTypeIds)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"call refresh meta info callback"_t,
- projectStorageCategory(),
- keyValue("type ids", deletedTypeIds)};
+ Modules fetchAllModules() const;
- if (deletedTypeIds.size()) {
- for (ProjectStorageObserver *observer : observers)
- observer->removedTypeIds(deletedTypeIds);
- }
- }
+ void callRefreshMetaInfoCallback(const TypeIds &deletedTypeIds);
class AliasPropertyDeclaration
{
@@ -1457,48 +484,14 @@ private:
}
};
- SourceIds filterSourceIdsWithoutType(const SourceIds &updatedSourceIds, SourceIds &sourceIdsOfTypes)
- {
- std::sort(sourceIdsOfTypes.begin(), sourceIdsOfTypes.end());
+ SourceIds filterSourceIdsWithoutType(const SourceIds &updatedSourceIds,
+ SourceIds &sourceIdsOfTypes);
- SourceIds sourceIdsWithoutTypeSourceIds;
- sourceIdsWithoutTypeSourceIds.reserve(updatedSourceIds.size());
- std::set_difference(updatedSourceIds.begin(),
- updatedSourceIds.end(),
- sourceIdsOfTypes.begin(),
- sourceIdsOfTypes.end(),
- std::back_inserter(sourceIdsWithoutTypeSourceIds));
+ TypeIds fetchTypeIds(const SourceIds &sourceIds);
- return sourceIdsWithoutTypeSourceIds;
- }
+ void unique(SourceIds &sourceIds);
- TypeIds fetchTypeIds(const SourceIds &sourceIds)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch type ids"_t,
- projectStorageCategory(),
- keyValue("source ids", sourceIds)};
-
- return selectTypeIdsForSourceIdsStatement.template values<TypeId, 128>(toIntegers(sourceIds));
- }
-
- void unique(SourceIds &sourceIds)
- {
- std::sort(sourceIds.begin(), sourceIds.end());
- auto newEnd = std::unique(sourceIds.begin(), sourceIds.end());
- sourceIds.erase(newEnd, sourceIds.end());
- }
-
- void synchronizeTypeTraits(TypeId typeId, Storage::TypeTraits traits)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"synchronize type traits"_t,
- projectStorageCategory(),
- keyValue("type id", typeId),
- keyValue("type traits", traits)};
-
- updateTypeAnnotationTraitStatement.write(typeId, traits.annotation);
- }
+ void synchronizeTypeTraits(TypeId typeId, Storage::TypeTraits traits);
class TypeAnnotationView
{
@@ -1533,28 +526,7 @@ private:
Utils::PathString hintsJson;
};
- void updateTypeIdInTypeAnnotations(Storage::Synchronization::TypeAnnotations &typeAnnotations)
- {
- NanotraceHR::Tracer tracer{"update type id in type annotations"_t, projectStorageCategory()};
-
- for (auto &annotation : typeAnnotations) {
- annotation.typeId = fetchTypeIdByModuleIdAndExportedName(annotation.moduleId,
- annotation.typeName);
- }
-
- for (auto &annotation : typeAnnotations) {
- if (!annotation.typeId)
- qWarning() << moduleName(annotation.moduleId).toQString()
- << annotation.typeName.toQString();
- }
-
- typeAnnotations.erase(std::remove_if(typeAnnotations.begin(),
- typeAnnotations.end(),
- [](const auto &annotation) {
- return !annotation.typeId;
- }),
- typeAnnotations.end());
- }
+ void updateTypeIdInTypeAnnotations(Storage::Synchronization::TypeAnnotations &typeAnnotations);
template<typename Value>
static Sqlite::ValueView createEmptyAsNull(const Value &value)
@@ -1566,84 +538,9 @@ private:
}
void synchronizeTypeAnnotations(Storage::Synchronization::TypeAnnotations &typeAnnotations,
- const SourceIds &updatedTypeAnnotationSourceIds)
- {
- NanotraceHR::Tracer tracer{"synchronize type annotations"_t, projectStorageCategory()};
-
- using Storage::Synchronization::TypeAnnotation;
-
- updateTypeIdInTypeAnnotations(typeAnnotations);
-
- auto compareKey = [](auto &&first, auto &&second) { return first.typeId - second.typeId; };
-
- std::sort(typeAnnotations.begin(), typeAnnotations.end(), [&](auto &&first, auto &&second) {
- return first.typeId < second.typeId;
- });
-
- auto range = selectTypeAnnotationsForSourceIdsStatement.template range<TypeAnnotationView>(
- toIntegers(updatedTypeAnnotationSourceIds));
-
- auto insert = [&](const TypeAnnotation &annotation) {
- if (!annotation.sourceId)
- throw TypeAnnotationHasInvalidSourceId{};
-
- synchronizeTypeTraits(annotation.typeId, annotation.traits);
-
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert type annotations"_t,
- projectStorageCategory(),
- keyValue("type annotation", annotation)};
-
- insertTypeAnnotationStatement.write(annotation.typeId,
- annotation.sourceId,
- annotation.directorySourceId,
- annotation.iconPath,
- createEmptyAsNull(annotation.itemLibraryJson),
- createEmptyAsNull(annotation.hintsJson));
- };
-
- auto update = [&](const TypeAnnotationView &annotationFromDatabase,
- const TypeAnnotation &annotation) {
- synchronizeTypeTraits(annotation.typeId, annotation.traits);
-
- if (annotationFromDatabase.iconPath != annotation.iconPath
- || annotationFromDatabase.itemLibraryJson != annotation.itemLibraryJson
- || annotationFromDatabase.hintsJson != annotation.hintsJson) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"update type annotations"_t,
- projectStorageCategory(),
- keyValue("type annotation from database",
- annotationFromDatabase),
- keyValue("type annotation", annotation)};
-
- updateTypeAnnotationStatement.write(annotation.typeId,
- annotation.iconPath,
- createEmptyAsNull(annotation.itemLibraryJson),
- createEmptyAsNull(annotation.hintsJson));
- return Sqlite::UpdateChange::Update;
- }
-
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const TypeAnnotationView &annotationFromDatabase) {
- synchronizeTypeTraits(annotationFromDatabase.typeId, Storage::TypeTraits{});
-
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove type annotations"_t,
- projectStorageCategory(),
- keyValue("type annotation", annotationFromDatabase)};
+ const SourceIds &updatedTypeAnnotationSourceIds);
- deleteTypeAnnotationStatement.write(annotationFromDatabase.typeId);
- };
-
- Sqlite::insertUpdateDelete(range, typeAnnotations, compareKey, insert, update, remove);
- }
-
- void synchronizeTypeTrait(const Storage::Synchronization::Type &type)
- {
- updateTypeTraitStatement.write(type.typeId, type.traits.type);
- }
+ void synchronizeTypeTrait(const Storage::Synchronization::Type &type);
void synchronizeTypes(Storage::Synchronization::Types &types,
TypeIds &updatedTypeIds,
@@ -1653,486 +550,49 @@ private:
PropertyDeclarations &relinkablePropertyDeclarations,
Prototypes &relinkablePrototypes,
Prototypes &relinkableExtensions,
- const SourceIds &updatedSourceIds)
- {
- NanotraceHR::Tracer tracer{"synchronize types"_t, projectStorageCategory()};
-
- Storage::Synchronization::ExportedTypes exportedTypes;
- exportedTypes.reserve(types.size() * 3);
- SourceIds sourceIdsOfTypes;
- sourceIdsOfTypes.reserve(updatedSourceIds.size());
- SourceIds notUpdatedExportedSourceIds;
- notUpdatedExportedSourceIds.reserve(updatedSourceIds.size());
- SourceIds exportedSourceIds;
- exportedSourceIds.reserve(types.size());
-
- for (auto &type : types) {
- if (!type.sourceId)
- throw TypeHasInvalidSourceId{};
-
- TypeId typeId = declareType(type);
- synchronizeTypeTrait(type);
- sourceIdsOfTypes.push_back(type.sourceId);
- updatedTypeIds.push_back(typeId);
- if (type.changeLevel != Storage::Synchronization::ChangeLevel::ExcludeExportedTypes) {
- exportedSourceIds.push_back(type.sourceId);
- extractExportedTypes(typeId, type, exportedTypes);
- }
- }
-
- std::sort(types.begin(), types.end(), [](const auto &first, const auto &second) {
- return first.typeId < second.typeId;
- });
-
- unique(exportedSourceIds);
-
- SourceIds sourceIdsWithoutType = filterSourceIdsWithoutType(updatedSourceIds,
- sourceIdsOfTypes);
- exportedSourceIds.insert(exportedSourceIds.end(),
- sourceIdsWithoutType.begin(),
- sourceIdsWithoutType.end());
- TypeIds exportedTypeIds = fetchTypeIds(exportedSourceIds);
- synchronizeExportedTypes(exportedTypeIds,
- exportedTypes,
- relinkableAliasPropertyDeclarations,
- relinkablePropertyDeclarations,
- relinkablePrototypes,
- relinkableExtensions);
-
- syncPrototypesAndExtensions(types, relinkablePrototypes, relinkableExtensions);
- resetDefaultPropertiesIfChanged(types);
- resetRemovedAliasPropertyDeclarationsToNull(types, relinkableAliasPropertyDeclarations);
- syncDeclarations(types,
- insertedAliasPropertyDeclarations,
- updatedAliasPropertyDeclarations,
- relinkablePropertyDeclarations);
- syncDefaultProperties(types);
- }
+ const SourceIds &updatedSourceIds);
void synchronizeProjectDatas(Storage::Synchronization::ProjectDatas &projectDatas,
- const SourceIds &updatedProjectSourceIds)
- {
- NanotraceHR::Tracer tracer{"synchronize project datas"_t, projectStorageCategory()};
-
- auto compareKey = [](auto &&first, auto &&second) {
- auto projectSourceIdDifference = first.projectSourceId - second.projectSourceId;
- if (projectSourceIdDifference != 0)
- return projectSourceIdDifference;
-
- return first.sourceId - second.sourceId;
- };
-
- std::sort(projectDatas.begin(), projectDatas.end(), [&](auto &&first, auto &&second) {
- return std::tie(first.projectSourceId, first.sourceId)
- < std::tie(second.projectSourceId, second.sourceId);
- });
+ const SourceIds &updatedProjectSourceIds);
- auto range = selectProjectDatasForSourceIdsStatement
- .template range<Storage::Synchronization::ProjectData>(
- toIntegers(updatedProjectSourceIds));
-
- auto insert = [&](const Storage::Synchronization::ProjectData &projectData) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert project data"_t,
- projectStorageCategory(),
- keyValue("project data", projectData)};
-
- if (!projectData.projectSourceId)
- throw ProjectDataHasInvalidProjectSourceId{};
- if (!projectData.sourceId)
- throw ProjectDataHasInvalidSourceId{};
-
- insertProjectDataStatement.write(projectData.projectSourceId,
- projectData.sourceId,
- projectData.moduleId,
- projectData.fileType);
- };
-
- auto update = [&](const Storage::Synchronization::ProjectData &projectDataFromDatabase,
- const Storage::Synchronization::ProjectData &projectData) {
- if (projectDataFromDatabase.fileType != projectData.fileType
- || !compareInvalidAreTrue(projectDataFromDatabase.moduleId, projectData.moduleId)) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"update project data"_t,
- projectStorageCategory(),
- keyValue("project data", projectData),
- keyValue("project data from database",
- projectDataFromDatabase)};
-
- updateProjectDataStatement.write(projectData.projectSourceId,
- projectData.sourceId,
- projectData.moduleId,
- projectData.fileType);
- return Sqlite::UpdateChange::Update;
- }
-
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const Storage::Synchronization::ProjectData &projectData) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove project data"_t,
- projectStorageCategory(),
- keyValue("project data", projectData)};
-
- deleteProjectDataStatement.write(projectData.projectSourceId, projectData.sourceId);
- };
-
- Sqlite::insertUpdateDelete(range, projectDatas, compareKey, insert, update, remove);
- }
-
- void synchronizeFileStatuses(FileStatuses &fileStatuses, const SourceIds &updatedSourceIds)
- {
- NanotraceHR::Tracer tracer{"synchronize file statuses"_t, projectStorageCategory()};
-
- auto compareKey = [](auto &&first, auto &&second) {
- return first.sourceId - second.sourceId;
- };
-
- std::sort(fileStatuses.begin(), fileStatuses.end(), [&](auto &&first, auto &&second) {
- return first.sourceId < second.sourceId;
- });
-
- auto range = selectFileStatusesForSourceIdsStatement.template range<FileStatus>(
- toIntegers(updatedSourceIds));
-
- auto insert = [&](const FileStatus &fileStatus) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert file status"_t,
- projectStorageCategory(),
- keyValue("file status", fileStatus)};
-
- if (!fileStatus.sourceId)
- throw FileStatusHasInvalidSourceId{};
- insertFileStatusStatement.write(fileStatus.sourceId,
- fileStatus.size,
- fileStatus.lastModified);
- };
-
- auto update = [&](const FileStatus &fileStatusFromDatabase, const FileStatus &fileStatus) {
- if (fileStatusFromDatabase.lastModified != fileStatus.lastModified
- || fileStatusFromDatabase.size != fileStatus.size) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"update file status"_t,
- projectStorageCategory(),
- keyValue("file status", fileStatus),
- keyValue("file status from database",
- fileStatusFromDatabase)};
-
- updateFileStatusStatement.write(fileStatus.sourceId,
- fileStatus.size,
- fileStatus.lastModified);
- return Sqlite::UpdateChange::Update;
- }
-
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const FileStatus &fileStatus) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove file status"_t,
- projectStorageCategory(),
- keyValue("file status", fileStatus)};
-
- deleteFileStatusStatement.write(fileStatus.sourceId);
- };
-
- Sqlite::insertUpdateDelete(range, fileStatuses, compareKey, insert, update, remove);
- }
+ void synchronizeFileStatuses(FileStatuses &fileStatuses, const SourceIds &updatedSourceIds);
void synchronizeImports(Storage::Imports &imports,
const SourceIds &updatedSourceIds,
Storage::Imports &moduleDependencies,
const SourceIds &updatedModuleDependencySourceIds,
Storage::Synchronization::ModuleExportedImports &moduleExportedImports,
- const ModuleIds &updatedModuleIds)
- {
- NanotraceHR::Tracer tracer{"synchronize imports"_t, projectStorageCategory()};
-
- synchromizeModuleExportedImports(moduleExportedImports, updatedModuleIds);
- NanotraceHR::Tracer importTracer{"synchronize qml document imports"_t,
- projectStorageCategory()};
- synchronizeDocumentImports(imports,
- updatedSourceIds,
- Storage::Synchronization::ImportKind::Import);
- importTracer.end();
- NanotraceHR::Tracer moduleDependenciesTracer{"synchronize module depdencies"_t,
- projectStorageCategory()};
- synchronizeDocumentImports(moduleDependencies,
- updatedModuleDependencySourceIds,
- Storage::Synchronization::ImportKind::ModuleDependency);
- moduleDependenciesTracer.end();
- }
+ const ModuleIds &updatedModuleIds);
void synchromizeModuleExportedImports(
Storage::Synchronization::ModuleExportedImports &moduleExportedImports,
- const ModuleIds &updatedModuleIds)
- {
- NanotraceHR::Tracer tracer{"synchronize module exported imports"_t, projectStorageCategory()};
- std::sort(moduleExportedImports.begin(),
- moduleExportedImports.end(),
- [](auto &&first, auto &&second) {
- return std::tie(first.moduleId, first.exportedModuleId)
- < std::tie(second.moduleId, second.exportedModuleId);
- });
-
- auto range = selectModuleExportedImportsForSourceIdStatement
- .template range<Storage::Synchronization::ModuleExportedImportView>(
- toIntegers(updatedModuleIds));
-
- auto compareKey = [](const Storage::Synchronization::ModuleExportedImportView &view,
- const Storage::Synchronization::ModuleExportedImport &import) -> long long {
- auto moduleIdDifference = view.moduleId - import.moduleId;
- if (moduleIdDifference != 0)
- return moduleIdDifference;
-
- return view.exportedModuleId - import.exportedModuleId;
- };
-
- auto insert = [&](const Storage::Synchronization::ModuleExportedImport &import) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert module exported import"_t,
- projectStorageCategory(),
- keyValue("module exported import", import),
- keyValue("module id", import.moduleId)};
- tracer.tick("exported module"_t, keyValue("module id", import.exportedModuleId));
-
- if (import.version.minor) {
- insertModuleExportedImportWithVersionStatement.write(import.moduleId,
- import.exportedModuleId,
- import.isAutoVersion,
- import.version.major.value,
- import.version.minor.value);
- } else if (import.version.major) {
- insertModuleExportedImportWithMajorVersionStatement.write(import.moduleId,
- import.exportedModuleId,
- import.isAutoVersion,
- import.version.major.value);
- } else {
- insertModuleExportedImportWithoutVersionStatement.write(import.moduleId,
- import.exportedModuleId,
- import.isAutoVersion);
- }
- };
-
- auto update = [](const Storage::Synchronization::ModuleExportedImportView &,
- const Storage::Synchronization::ModuleExportedImport &) {
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const Storage::Synchronization::ModuleExportedImportView &view) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove module exported import"_t,
- projectStorageCategory(),
- keyValue("module exported import view", view),
- keyValue("module id", view.moduleId)};
- tracer.tick("exported module"_t, keyValue("module id", view.exportedModuleId));
-
- deleteModuleExportedImportStatement.write(view.moduleExportedImportId);
- };
-
- Sqlite::insertUpdateDelete(range, moduleExportedImports, compareKey, insert, update, remove);
- }
-
- ModuleId fetchModuleIdUnguarded(Utils::SmallStringView name) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch module id ungarded"_t,
- projectStorageCategory(),
- keyValue("module name", name)};
-
- auto moduleId = selectModuleIdByNameStatement.template value<ModuleId>(name);
-
- if (!moduleId)
- moduleId = insertModuleNameStatement.template value<ModuleId>(name);
-
- tracer.end(keyValue("module id", moduleId));
-
- return moduleId;
- }
+ const ModuleIds &updatedModuleIds);
- auto fetchModuleNameUnguarded(ModuleId id) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch module name ungarded"_t,
- projectStorageCategory(),
- keyValue("module id", id)};
-
- auto moduleName = selectModuleNameStatement.template value<Utils::PathString>(id);
-
- if (moduleName.empty())
- throw ModuleDoesNotExists{};
+ ModuleId fetchModuleIdUnguarded(Utils::SmallStringView name) const override;
- tracer.end(keyValue("module name", moduleName));
-
- return moduleName;
- }
+ Utils::PathString fetchModuleNameUnguarded(ModuleId id) const;
void handleAliasPropertyDeclarationsWithPropertyType(
- TypeId typeId, AliasPropertyDeclarations &relinkableAliasPropertyDeclarations)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"handle alias property declarations with property type"_t,
- projectStorageCategory(),
- keyValue("type id", typeId),
- keyValue("relinkable alias property declarations",
- relinkableAliasPropertyDeclarations)};
-
- auto callback = [&](TypeId typeId_,
- PropertyDeclarationId propertyDeclarationId,
- ImportedTypeNameId propertyImportedTypeNameId,
- PropertyDeclarationId aliasPropertyDeclarationId,
- PropertyDeclarationId aliasPropertyDeclarationTailId) {
- auto aliasPropertyName = selectPropertyNameStatement.template value<Utils::SmallString>(
- aliasPropertyDeclarationId);
- Utils::SmallString aliasPropertyNameTail;
- if (aliasPropertyDeclarationTailId)
- aliasPropertyNameTail = selectPropertyNameStatement.template value<Utils::SmallString>(
- aliasPropertyDeclarationTailId);
-
- relinkableAliasPropertyDeclarations
- .emplace_back(TypeId{typeId_},
- PropertyDeclarationId{propertyDeclarationId},
- ImportedTypeNameId{propertyImportedTypeNameId},
- std::move(aliasPropertyName),
- std::move(aliasPropertyNameTail));
-
- updateAliasPropertyDeclarationToNullStatement.write(propertyDeclarationId);
- };
-
- selectAliasPropertiesDeclarationForPropertiesWithTypeIdStatement.readCallback(callback,
- typeId);
- }
+ TypeId typeId, AliasPropertyDeclarations &relinkableAliasPropertyDeclarations);
void handlePropertyDeclarationWithPropertyType(TypeId typeId,
- PropertyDeclarations &relinkablePropertyDeclarations)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"handle property declarations with property type"_t,
- projectStorageCategory(),
- keyValue("type id", typeId),
- keyValue("relinkable property declarations",
- relinkablePropertyDeclarations)};
+ PropertyDeclarations &relinkablePropertyDeclarations);
- updatesPropertyDeclarationPropertyTypeToNullStatement.readTo(relinkablePropertyDeclarations,
- typeId);
- }
+ void handlePrototypes(TypeId prototypeId, Prototypes &relinkablePrototypes);
- void handlePrototypes(TypeId prototypeId, Prototypes &relinkablePrototypes)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"handle prototypes"_t,
- projectStorageCategory(),
- keyValue("type id", prototypeId),
- keyValue("relinkable prototypes", relinkablePrototypes)};
-
- auto callback = [&](TypeId typeId, ImportedTypeNameId prototypeNameId) {
- relinkablePrototypes.emplace_back(typeId, prototypeNameId);
- };
-
- updatePrototypeIdToNullStatement.readCallback(callback, prototypeId);
- }
-
- void handleExtensions(TypeId extensionId, Prototypes &relinkableExtensions)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"handle extension"_t,
- projectStorageCategory(),
- keyValue("type id", extensionId),
- keyValue("relinkable extensions", relinkableExtensions)};
-
- auto callback = [&](TypeId typeId, ImportedTypeNameId extensionNameId) {
- relinkableExtensions.emplace_back(typeId, extensionNameId);
- };
-
- updateExtensionIdToNullStatement.readCallback(callback, extensionId);
- }
+ void handleExtensions(TypeId extensionId, Prototypes &relinkableExtensions);
void deleteType(TypeId typeId,
AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
PropertyDeclarations &relinkablePropertyDeclarations,
Prototypes &relinkablePrototypes,
- Prototypes &relinkableExtensions)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"delete type"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- handlePropertyDeclarationWithPropertyType(typeId, relinkablePropertyDeclarations);
- handleAliasPropertyDeclarationsWithPropertyType(typeId, relinkableAliasPropertyDeclarations);
- handlePrototypes(typeId, relinkablePrototypes);
- handleExtensions(typeId, relinkableExtensions);
- deleteTypeNamesByTypeIdStatement.write(typeId);
- deleteEnumerationDeclarationByTypeIdStatement.write(typeId);
- deletePropertyDeclarationByTypeIdStatement.write(typeId);
- deleteFunctionDeclarationByTypeIdStatement.write(typeId);
- deleteSignalDeclarationByTypeIdStatement.write(typeId);
- deleteTypeStatement.write(typeId);
- }
+ Prototypes &relinkableExtensions);
void relinkAliasPropertyDeclarations(AliasPropertyDeclarations &aliasPropertyDeclarations,
- const TypeIds &deletedTypeIds)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"relink alias properties"_t,
- projectStorageCategory(),
- keyValue("alias property declarations", aliasPropertyDeclarations),
- keyValue("deleted type ids", deletedTypeIds)};
-
- std::sort(aliasPropertyDeclarations.begin(), aliasPropertyDeclarations.end());
-
- Utils::set_greedy_difference(
- aliasPropertyDeclarations.cbegin(),
- aliasPropertyDeclarations.cend(),
- deletedTypeIds.begin(),
- deletedTypeIds.end(),
- [&](const AliasPropertyDeclaration &alias) {
- auto typeId = fetchTypeId(alias.aliasImportedTypeNameId);
-
- if (!typeId)
- throw TypeNameDoesNotExists{fetchImportedTypeName(alias.aliasImportedTypeNameId)};
-
- auto [propertyTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeIdAndNameUngarded(
- typeId, alias.aliasPropertyName);
-
- updatePropertyDeclarationWithAliasAndTypeStatement.write(alias.propertyDeclarationId,
- propertyTypeId,
- propertyTraits,
- alias.aliasImportedTypeNameId,
- aliasId);
- },
- TypeCompare<AliasPropertyDeclaration>{});
- }
+ const TypeIds &deletedTypeIds);
void relinkPropertyDeclarations(PropertyDeclarations &relinkablePropertyDeclaration,
- const TypeIds &deletedTypeIds)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"relink property declarations"_t,
- projectStorageCategory(),
- keyValue("relinkable property declarations",
- relinkablePropertyDeclaration),
- keyValue("deleted type ids", deletedTypeIds)};
-
- std::sort(relinkablePropertyDeclaration.begin(), relinkablePropertyDeclaration.end());
-
- Utils::set_greedy_difference(
- relinkablePropertyDeclaration.cbegin(),
- relinkablePropertyDeclaration.cend(),
- deletedTypeIds.begin(),
- deletedTypeIds.end(),
- [&](const PropertyDeclaration &property) {
- TypeId propertyTypeId = fetchTypeId(property.importedTypeNameId);
-
- if (!propertyTypeId)
- throw TypeNameDoesNotExists{fetchImportedTypeName(property.importedTypeNameId)};
-
- updatePropertyDeclarationTypeStatement.write(property.propertyDeclarationId,
- propertyTypeId);
- },
- TypeCompare<PropertyDeclaration>{});
- }
+ const TypeIds &deletedTypeIds);
template<typename Callable>
void relinkPrototypes(Prototypes &relinkablePrototypes,
@@ -2171,435 +631,66 @@ private:
PropertyDeclarations &relinkablePropertyDeclarations,
Prototypes &relinkablePrototypes,
Prototypes &relinkableExtensions,
- TypeIds &deletedTypeIds)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"delete not updated types"_t,
- projectStorageCategory(),
- keyValue("updated type ids", updatedTypeIds),
- keyValue("updated source ids", updatedSourceIds),
- keyValue("type ids to be deleted", typeIdsToBeDeleted)};
-
- auto callback = [&](TypeId typeId) {
- deletedTypeIds.push_back(typeId);
- deleteType(typeId,
- relinkableAliasPropertyDeclarations,
- relinkablePropertyDeclarations,
- relinkablePrototypes,
- relinkableExtensions);
- };
-
- selectNotUpdatedTypesInSourcesStatement.readCallback(callback,
- toIntegers(updatedSourceIds),
- toIntegers(updatedTypeIds));
- for (TypeId typeIdToBeDeleted : typeIdsToBeDeleted)
- callback(typeIdToBeDeleted);
- }
+ TypeIds &deletedTypeIds);
void relink(AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
PropertyDeclarations &relinkablePropertyDeclarations,
Prototypes &relinkablePrototypes,
Prototypes &relinkableExtensions,
- TypeIds &deletedTypeIds)
- {
- NanotraceHR::Tracer tracer{"relink"_t, projectStorageCategory()};
-
- std::sort(deletedTypeIds.begin(), deletedTypeIds.end());
-
- relinkPrototypes(relinkablePrototypes, deletedTypeIds, [&](TypeId typeId, TypeId prototypeId) {
- updateTypePrototypeStatement.write(typeId, prototypeId);
- });
- relinkPrototypes(relinkableExtensions, deletedTypeIds, [&](TypeId typeId, TypeId prototypeId) {
- updateTypeExtensionStatement.write(typeId, prototypeId);
- });
- relinkPropertyDeclarations(relinkablePropertyDeclarations, deletedTypeIds);
- relinkAliasPropertyDeclarations(relinkableAliasPropertyDeclarations, deletedTypeIds);
- }
+ TypeIds &deletedTypeIds);
PropertyDeclarationId fetchAliasId(TypeId aliasTypeId,
Utils::SmallStringView aliasPropertyName,
- Utils::SmallStringView aliasPropertyNameTail)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch alias id"_t,
- projectStorageCategory(),
- keyValue("alias type id", aliasTypeId),
- keyValue("alias property name", aliasPropertyName),
- keyValue("alias property name tail", aliasPropertyNameTail)};
-
- if (aliasPropertyNameTail.empty())
- return fetchPropertyDeclarationIdByTypeIdAndNameUngarded(aliasTypeId, aliasPropertyName);
-
- auto stemAlias = fetchPropertyDeclarationByTypeIdAndNameUngarded(aliasTypeId,
- aliasPropertyName);
-
- return fetchPropertyDeclarationIdByTypeIdAndNameUngarded(stemAlias.propertyTypeId,
- aliasPropertyNameTail);
- }
-
- void linkAliasPropertyDeclarationAliasIds(const AliasPropertyDeclarations &aliasDeclarations)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"link alias property declarations alias ids"_t,
- projectStorageCategory(),
- keyValue("alias property declarations", aliasDeclarations)};
+ Utils::SmallStringView aliasPropertyNameTail);
- for (const auto &aliasDeclaration : aliasDeclarations) {
- auto aliasTypeId = fetchTypeId(aliasDeclaration.aliasImportedTypeNameId);
+ void linkAliasPropertyDeclarationAliasIds(const AliasPropertyDeclarations &aliasDeclarations);
- if (!aliasTypeId) {
- throw TypeNameDoesNotExists{
- fetchImportedTypeName(aliasDeclaration.aliasImportedTypeNameId)};
- }
+ void updateAliasPropertyDeclarationValues(const AliasPropertyDeclarations &aliasDeclarations);
- auto aliasId = fetchAliasId(aliasTypeId,
- aliasDeclaration.aliasPropertyName,
- aliasDeclaration.aliasPropertyNameTail);
-
- updatePropertyDeclarationAliasIdAndTypeNameIdStatement
- .write(aliasDeclaration.propertyDeclarationId,
- aliasId,
- aliasDeclaration.aliasImportedTypeNameId);
- }
- }
-
- void updateAliasPropertyDeclarationValues(const AliasPropertyDeclarations &aliasDeclarations)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"update alias property declarations"_t,
- projectStorageCategory(),
- keyValue("alias property declarations", aliasDeclarations)};
-
- for (const auto &aliasDeclaration : aliasDeclarations) {
- updatetPropertiesDeclarationValuesOfAliasStatement.write(
- aliasDeclaration.propertyDeclarationId);
- updatePropertyAliasDeclarationRecursivelyStatement.write(
- aliasDeclaration.propertyDeclarationId);
- }
- }
-
- void checkAliasPropertyDeclarationCycles(const AliasPropertyDeclarations &aliasDeclarations)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"check alias property declarations cycles"_t,
- projectStorageCategory(),
- keyValue("alias property declarations", aliasDeclarations)};
- for (const auto &aliasDeclaration : aliasDeclarations)
- checkForAliasChainCycle(aliasDeclaration.propertyDeclarationId);
- }
+ void checkAliasPropertyDeclarationCycles(const AliasPropertyDeclarations &aliasDeclarations);
void linkAliases(const AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
- const AliasPropertyDeclarations &updatedAliasPropertyDeclarations)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"link aliases"_t, projectStorageCategory()};
-
- linkAliasPropertyDeclarationAliasIds(insertedAliasPropertyDeclarations);
- linkAliasPropertyDeclarationAliasIds(updatedAliasPropertyDeclarations);
-
- checkAliasPropertyDeclarationCycles(insertedAliasPropertyDeclarations);
- checkAliasPropertyDeclarationCycles(updatedAliasPropertyDeclarations);
-
- updateAliasPropertyDeclarationValues(insertedAliasPropertyDeclarations);
- updateAliasPropertyDeclarationValues(updatedAliasPropertyDeclarations);
- }
+ const AliasPropertyDeclarations &updatedAliasPropertyDeclarations);
void synchronizeExportedTypes(const TypeIds &updatedTypeIds,
Storage::Synchronization::ExportedTypes &exportedTypes,
AliasPropertyDeclarations &relinkableAliasPropertyDeclarations,
PropertyDeclarations &relinkablePropertyDeclarations,
Prototypes &relinkablePrototypes,
- Prototypes &relinkableExtensions)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"synchronize exported types"_t, projectStorageCategory()};
-
- std::sort(exportedTypes.begin(), exportedTypes.end(), [](auto &&first, auto &&second) {
- if (first.moduleId < second.moduleId)
- return true;
- else if (first.moduleId > second.moduleId)
- return false;
-
- auto nameCompare = Sqlite::compare(first.name, second.name);
-
- if (nameCompare < 0)
- return true;
- else if (nameCompare > 0)
- return false;
-
- return first.version < second.version;
- });
-
- auto range = selectExportedTypesForSourceIdsStatement
- .template range<Storage::Synchronization::ExportedTypeView>(
- toIntegers(updatedTypeIds));
-
- auto compareKey = [](const Storage::Synchronization::ExportedTypeView &view,
- const Storage::Synchronization::ExportedType &type) -> long long {
- auto moduleIdDifference = view.moduleId - type.moduleId;
- if (moduleIdDifference != 0)
- return moduleIdDifference;
-
- auto nameDifference = Sqlite::compare(view.name, type.name);
- if (nameDifference != 0)
- return nameDifference;
-
- auto versionDifference = view.version.major.value - type.version.major.value;
- if (versionDifference != 0)
- return versionDifference;
-
- return view.version.minor.value - type.version.minor.value;
- };
-
- auto insert = [&](const Storage::Synchronization::ExportedType &type) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert exported type"_t,
- projectStorageCategory(),
- keyValue("exported type", type),
- keyValue("type id", type.typeId),
- keyValue("module id", type.moduleId)};
- if (!type.moduleId)
- throw QmlDesigner::ModuleDoesNotExists{};
-
- try {
- if (type.version) {
- insertExportedTypeNamesWithVersionStatement.write(type.moduleId,
- type.name,
- type.version.major.value,
- type.version.minor.value,
- type.typeId);
-
- } else if (type.version.major) {
- insertExportedTypeNamesWithMajorVersionStatement.write(type.moduleId,
- type.name,
- type.version.major.value,
- type.typeId);
- } else {
- insertExportedTypeNamesWithoutVersionStatement.write(type.moduleId,
- type.name,
- type.typeId);
- }
- } catch (const Sqlite::ConstraintPreventsModification &) {
- throw QmlDesigner::ExportedTypeCannotBeInserted{type.name};
- }
- };
-
- auto update = [&](const Storage::Synchronization::ExportedTypeView &view,
- const Storage::Synchronization::ExportedType &type) {
- if (view.typeId != type.typeId) {
- NanotraceHR::Tracer tracer{"update exported type"_t,
- projectStorageCategory(),
- keyValue("exported type", type),
- keyValue("exported type view", view),
- keyValue("type id", type.typeId),
- keyValue("module id", type.typeId)};
-
- handlePropertyDeclarationWithPropertyType(view.typeId, relinkablePropertyDeclarations);
- handleAliasPropertyDeclarationsWithPropertyType(view.typeId,
- relinkableAliasPropertyDeclarations);
- handlePrototypes(view.typeId, relinkablePrototypes);
- handleExtensions(view.typeId, relinkableExtensions);
- updateExportedTypeNameTypeIdStatement.write(view.exportedTypeNameId, type.typeId);
- return Sqlite::UpdateChange::Update;
- }
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const Storage::Synchronization::ExportedTypeView &view) {
- NanotraceHR::Tracer tracer{"remove exported type"_t,
- projectStorageCategory(),
- keyValue("exported type", view),
- keyValue("type id", view.typeId),
- keyValue("module id", view.moduleId)};
-
- handlePropertyDeclarationWithPropertyType(view.typeId, relinkablePropertyDeclarations);
- handleAliasPropertyDeclarationsWithPropertyType(view.typeId,
- relinkableAliasPropertyDeclarations);
- handlePrototypes(view.typeId, relinkablePrototypes);
- handleExtensions(view.typeId, relinkableExtensions);
- deleteExportedTypeNameStatement.write(view.exportedTypeNameId);
- };
-
- Sqlite::insertUpdateDelete(range, exportedTypes, compareKey, insert, update, remove);
- }
+ Prototypes &relinkableExtensions);
void synchronizePropertyDeclarationsInsertAlias(
AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
const Storage::Synchronization::PropertyDeclaration &value,
SourceId sourceId,
- TypeId typeId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert property declaration to alias"_t,
- projectStorageCategory(),
- keyValue("property declaration", value)};
-
- auto callback = [&](PropertyDeclarationId propertyDeclarationId) {
- insertedAliasPropertyDeclarations.emplace_back(typeId,
- propertyDeclarationId,
- fetchImportedTypeNameId(value.typeName,
- sourceId),
- value.aliasPropertyName,
- value.aliasPropertyNameTail);
- return Sqlite::CallbackControl::Abort;
- };
-
- insertAliasPropertyDeclarationStatement.readCallback(callback, typeId, value.name);
- }
+ TypeId typeId);
- auto fetchPropertyDeclarationIds(TypeId baseTypeId) const
- {
- QVarLengthArray<PropertyDeclarationId, 128> propertyDeclarationIds;
-
- selectLocalPropertyDeclarationIdsForTypeStatement.readTo(propertyDeclarationIds, baseTypeId);
-
- auto range = selectPrototypeAndExtensionIdsStatement.template range<TypeId>(baseTypeId);
-
- for (TypeId prototype : range) {
- selectLocalPropertyDeclarationIdsForTypeStatement.readTo(propertyDeclarationIds,
- prototype);
- }
-
- return propertyDeclarationIds;
- }
+ QVarLengthArray<PropertyDeclarationId, 128> fetchPropertyDeclarationIds(TypeId baseTypeId) const;
PropertyDeclarationId fetchNextPropertyDeclarationId(TypeId baseTypeId,
- Utils::SmallStringView propertyName) const
- {
- auto range = selectPrototypeAndExtensionIdsStatement.template range<TypeId>(baseTypeId);
-
- for (TypeId prototype : range) {
- auto propertyDeclarationId = selectPropertyDeclarationIdByTypeIdAndNameStatement
- .template value<PropertyDeclarationId>(prototype,
- propertyName);
-
- if (propertyDeclarationId)
- return propertyDeclarationId;
- }
-
- return PropertyDeclarationId{};
- }
+ Utils::SmallStringView propertyName) const;
PropertyDeclarationId fetchPropertyDeclarationId(TypeId typeId,
- Utils::SmallStringView propertyName) const
- {
- auto propertyDeclarationId = selectPropertyDeclarationIdByTypeIdAndNameStatement
- .template value<PropertyDeclarationId>(typeId, propertyName);
-
- if (propertyDeclarationId)
- return propertyDeclarationId;
-
- return fetchNextPropertyDeclarationId(typeId, propertyName);
- }
-
- PropertyDeclarationId fetchNextDefaultPropertyDeclarationId(TypeId baseTypeId) const
- {
- auto range = selectPrototypeAndExtensionIdsStatement.template range<TypeId>(baseTypeId);
-
- for (TypeId prototype : range) {
- auto propertyDeclarationId = selectDefaultPropertyDeclarationIdStatement
- .template value<PropertyDeclarationId>(prototype);
+ Utils::SmallStringView propertyName) const;
- if (propertyDeclarationId)
- return propertyDeclarationId;
- }
-
- return PropertyDeclarationId{};
- }
+ PropertyDeclarationId fetchNextDefaultPropertyDeclarationId(TypeId baseTypeId) const;
- PropertyDeclarationId fetchDefaultPropertyDeclarationId(TypeId typeId) const
- {
- auto propertyDeclarationId = selectDefaultPropertyDeclarationIdStatement
- .template value<PropertyDeclarationId>(typeId);
-
- if (propertyDeclarationId)
- return propertyDeclarationId;
-
- return fetchNextDefaultPropertyDeclarationId(typeId);
- }
+ PropertyDeclarationId fetchDefaultPropertyDeclarationId(TypeId typeId) const;
void synchronizePropertyDeclarationsInsertProperty(
- const Storage::Synchronization::PropertyDeclaration &value, SourceId sourceId, TypeId typeId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert property declaration"_t,
- projectStorageCategory(),
- keyValue("property declaration", value)};
-
- auto propertyImportedTypeNameId = fetchImportedTypeNameId(value.typeName, sourceId);
- auto propertyTypeId = fetchTypeId(propertyImportedTypeNameId);
-
- if (!propertyTypeId)
- throw TypeNameDoesNotExists{fetchImportedTypeName(propertyImportedTypeNameId), sourceId};
-
- auto propertyDeclarationId = insertPropertyDeclarationStatement.template value<PropertyDeclarationId>(
- typeId, value.name, propertyTypeId, value.traits, propertyImportedTypeNameId);
-
- auto nextPropertyDeclarationId = fetchNextPropertyDeclarationId(typeId, value.name);
- if (nextPropertyDeclarationId) {
- updateAliasIdPropertyDeclarationStatement.write(nextPropertyDeclarationId,
- propertyDeclarationId);
- updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement
- .write(propertyDeclarationId, propertyTypeId, value.traits);
- }
- }
+ const Storage::Synchronization::PropertyDeclaration &value, SourceId sourceId, TypeId typeId);
void synchronizePropertyDeclarationsUpdateAlias(
AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
const Storage::Synchronization::PropertyDeclarationView &view,
const Storage::Synchronization::PropertyDeclaration &value,
- SourceId sourceId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"update property declaration to alias"_t,
- projectStorageCategory(),
- keyValue("property declaration", value),
- keyValue("property declaration view", view)};
-
- updatedAliasPropertyDeclarations.emplace_back(view.typeId,
- view.id,
- fetchImportedTypeNameId(value.typeName, sourceId),
- value.aliasPropertyName,
- value.aliasPropertyNameTail,
- view.aliasId);
- }
+ SourceId sourceId);
- auto synchronizePropertyDeclarationsUpdateProperty(
+ Sqlite::UpdateChange synchronizePropertyDeclarationsUpdateProperty(
const Storage::Synchronization::PropertyDeclarationView &view,
const Storage::Synchronization::PropertyDeclaration &value,
SourceId sourceId,
- PropertyDeclarationIds &propertyDeclarationIds)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"update property declaration"_t,
- projectStorageCategory(),
- keyValue("property declaration", value),
- keyValue("property declaration view", view)};
-
- auto propertyImportedTypeNameId = fetchImportedTypeNameId(value.typeName, sourceId);
-
- auto propertyTypeId = fetchTypeId(propertyImportedTypeNameId);
-
- if (!propertyTypeId)
- throw TypeNameDoesNotExists{fetchImportedTypeName(propertyImportedTypeNameId), sourceId};
-
- if (view.traits == value.traits && propertyTypeId == view.typeId
- && propertyImportedTypeNameId == view.typeNameId)
- return Sqlite::UpdateChange::No;
-
- updatePropertyDeclarationStatement.write(view.id,
- propertyTypeId,
- value.traits,
- propertyImportedTypeNameId);
- updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement.write(view.id,
- propertyTypeId,
- value.traits);
- propertyDeclarationIds.push_back(view.id);
-
- tracer.end(keyValue("updated", "yes"));
-
- return Sqlite::UpdateChange::Update;
- }
+ PropertyDeclarationIds &propertyDeclarationIds);
void synchronizePropertyDeclarations(
TypeId typeId,
@@ -2607,73 +698,7 @@ private:
SourceId sourceId,
AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
- PropertyDeclarationIds &propertyDeclarationIds)
- {
- NanotraceHR::Tracer tracer{"synchronize property declaration"_t, projectStorageCategory()};
-
- std::sort(propertyDeclarations.begin(),
- propertyDeclarations.end(),
- [](auto &&first, auto &&second) {
- return Sqlite::compare(first.name, second.name) < 0;
- });
-
- auto range = selectPropertyDeclarationsForTypeIdStatement
- .template range<Storage::Synchronization::PropertyDeclarationView>(typeId);
-
- auto compareKey = [](const Storage::Synchronization::PropertyDeclarationView &view,
- const Storage::Synchronization::PropertyDeclaration &value) {
- return Sqlite::compare(view.name, value.name);
- };
-
- auto insert = [&](const Storage::Synchronization::PropertyDeclaration &value) {
- if (value.kind == Storage::Synchronization::PropertyKind::Alias) {
- synchronizePropertyDeclarationsInsertAlias(insertedAliasPropertyDeclarations,
- value,
- sourceId,
- typeId);
- } else {
- synchronizePropertyDeclarationsInsertProperty(value, sourceId, typeId);
- }
- };
-
- auto update = [&](const Storage::Synchronization::PropertyDeclarationView &view,
- const Storage::Synchronization::PropertyDeclaration &value) {
- if (value.kind == Storage::Synchronization::PropertyKind::Alias) {
- synchronizePropertyDeclarationsUpdateAlias(updatedAliasPropertyDeclarations,
- view,
- value,
- sourceId);
- propertyDeclarationIds.push_back(view.id);
- } else {
- return synchronizePropertyDeclarationsUpdateProperty(view,
- value,
- sourceId,
- propertyDeclarationIds);
- }
-
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const Storage::Synchronization::PropertyDeclarationView &view) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove property declaration"_t,
- projectStorageCategory(),
- keyValue("property declaratio viewn", view)};
-
- auto nextPropertyDeclarationId = fetchNextPropertyDeclarationId(typeId, view.name);
-
- if (nextPropertyDeclarationId) {
- updateAliasPropertyDeclarationByAliasPropertyDeclarationIdStatement
- .write(nextPropertyDeclarationId, view.id);
- }
-
- updateDefaultPropertyIdToNullStatement.write(view.id);
- deletePropertyDeclarationStatement.write(view.id);
- propertyDeclarationIds.push_back(view.id);
- };
-
- Sqlite::insertUpdateDelete(range, propertyDeclarations, compareKey, insert, update, remove);
- }
+ PropertyDeclarationIds &propertyDeclarationIds);
class AliasPropertyDeclarationView
{
@@ -2706,237 +731,27 @@ private:
};
void resetRemovedAliasPropertyDeclarationsToNull(Storage::Synchronization::Type &type,
- PropertyDeclarationIds &propertyDeclarationIds)
- {
- NanotraceHR::Tracer tracer{"reset removed alias property declaration to null"_t,
- projectStorageCategory()};
-
- if (type.changeLevel == Storage::Synchronization::ChangeLevel::Minimal)
- return;
-
- Storage::Synchronization::PropertyDeclarations &aliasDeclarations = type.propertyDeclarations;
-
- std::sort(aliasDeclarations.begin(), aliasDeclarations.end(), [](auto &&first, auto &&second) {
- return Sqlite::compare(first.name, second.name) < 0;
- });
-
- auto range = selectPropertyDeclarationsWithAliasForTypeIdStatement
- .template range<AliasPropertyDeclarationView>(type.typeId);
-
- auto compareKey = [](const AliasPropertyDeclarationView &view,
- const Storage::Synchronization::PropertyDeclaration &value) {
- return Sqlite::compare(view.name, value.name);
- };
-
- auto insert = [&](const Storage::Synchronization::PropertyDeclaration &) {};
-
- auto update = [&](const AliasPropertyDeclarationView &,
- const Storage::Synchronization::PropertyDeclaration &) {
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const AliasPropertyDeclarationView &view) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"reset removed alias property declaration to null"_t,
- projectStorageCategory(),
- keyValue("alias property declaration view", view)};
-
- updatePropertyDeclarationAliasIdToNullStatement.write(view.id);
- propertyDeclarationIds.push_back(view.id);
- };
-
- Sqlite::insertUpdateDelete(range, aliasDeclarations, compareKey, insert, update, remove);
- }
+ PropertyDeclarationIds &propertyDeclarationIds);
void resetRemovedAliasPropertyDeclarationsToNull(
Storage::Synchronization::Types &types,
- AliasPropertyDeclarations &relinkableAliasPropertyDeclarations)
- {
- NanotraceHR::Tracer tracer{"reset removed alias properties to null"_t,
- projectStorageCategory()};
-
- PropertyDeclarationIds propertyDeclarationIds;
- propertyDeclarationIds.reserve(types.size());
-
- for (auto &&type : types)
- resetRemovedAliasPropertyDeclarationsToNull(type, propertyDeclarationIds);
-
- removeRelinkableEntries(relinkableAliasPropertyDeclarations,
- propertyDeclarationIds,
- PropertyCompare<AliasPropertyDeclaration>{});
- }
+ AliasPropertyDeclarations &relinkableAliasPropertyDeclarations);
ImportId insertDocumentImport(const Storage::Import &import,
Storage::Synchronization::ImportKind importKind,
ModuleId sourceModuleId,
- ImportId parentImportId)
- {
- if (import.version.minor) {
- return insertDocumentImportWithVersionStatement
- .template value<ImportId>(import.sourceId,
- import.moduleId,
- sourceModuleId,
- importKind,
- import.version.major.value,
- import.version.minor.value,
- parentImportId);
- } else if (import.version.major) {
- return insertDocumentImportWithMajorVersionStatement
- .template value<ImportId>(import.sourceId,
- import.moduleId,
- sourceModuleId,
- importKind,
- import.version.major.value,
- parentImportId);
- } else {
- return insertDocumentImportWithoutVersionStatement.template value<ImportId>(
- import.sourceId, import.moduleId, sourceModuleId, importKind, parentImportId);
- }
- }
+ ImportId parentImportId);
void synchronizeDocumentImports(Storage::Imports &imports,
const SourceIds &updatedSourceIds,
- Storage::Synchronization::ImportKind importKind)
- {
- std::sort(imports.begin(), imports.end(), [](auto &&first, auto &&second) {
- return std::tie(first.sourceId, first.moduleId, first.version)
- < std::tie(second.sourceId, second.moduleId, second.version);
- });
-
- auto range = selectDocumentImportForSourceIdStatement
- .template range<Storage::Synchronization::ImportView>(toIntegers(
- updatedSourceIds),
- importKind);
-
- auto compareKey = [](const Storage::Synchronization::ImportView &view,
- const Storage::Import &import) -> long long {
- auto sourceIdDifference = view.sourceId - import.sourceId;
- if (sourceIdDifference != 0)
- return sourceIdDifference;
-
- auto moduleIdDifference = view.moduleId - import.moduleId;
- if (moduleIdDifference != 0)
- return moduleIdDifference;
-
- auto versionDifference = view.version.major.value - import.version.major.value;
- if (versionDifference != 0)
- return versionDifference;
+ Storage::Synchronization::ImportKind importKind);
- return view.version.minor.value - import.version.minor.value;
- };
-
- auto insert = [&](const Storage::Import &import) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert import"_t,
- projectStorageCategory(),
- keyValue("import", import),
- keyValue("import kind", importKind),
- keyValue("source id", import.sourceId),
- keyValue("module id", import.moduleId)};
-
- auto importId = insertDocumentImport(import, importKind, import.moduleId, ImportId{});
- auto callback = [&](ModuleId exportedModuleId, int majorVersion, int minorVersion) {
- Storage::Import additionImport{exportedModuleId,
- Storage::Version{majorVersion, minorVersion},
- import.sourceId};
-
- auto exportedImportKind = importKind == Storage::Synchronization::ImportKind::Import
- ? Storage::Synchronization::ImportKind::ModuleExportedImport
- : Storage::Synchronization::ImportKind::ModuleExportedModuleDependency;
-
- NanotraceHR::Tracer tracer{"insert indirect import"_t,
- projectStorageCategory(),
- keyValue("import", import),
- keyValue("import kind", exportedImportKind),
- keyValue("source id", import.sourceId),
- keyValue("module id", import.moduleId)};
-
- auto indirectImportId = insertDocumentImport(additionImport,
- exportedImportKind,
- import.moduleId,
- importId);
-
- tracer.end(keyValue("import id", indirectImportId));
- };
-
- selectModuleExportedImportsForModuleIdStatement.readCallback(callback,
- import.moduleId,
- import.version.major.value,
- import.version.minor.value);
- tracer.end(keyValue("import id", importId));
- };
-
- auto update = [](const Storage::Synchronization::ImportView &, const Storage::Import &) {
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const Storage::Synchronization::ImportView &view) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove import"_t,
- projectStorageCategory(),
- keyValue("import", view),
- keyValue("import id", view.importId),
- keyValue("source id", view.sourceId),
- keyValue("module id", view.moduleId)};
-
- deleteDocumentImportStatement.write(view.importId);
- deleteDocumentImportsWithParentImportIdStatement.write(view.sourceId, view.importId);
- };
-
- Sqlite::insertUpdateDelete(range, imports, compareKey, insert, update, remove);
- }
-
- static Utils::PathString createJson(const Storage::Synchronization::ParameterDeclarations &parameters)
- {
- NanotraceHR::Tracer tracer{"create json from parameter declarations"_t,
- projectStorageCategory()};
-
- Utils::PathString json;
- json.append("[");
-
- Utils::SmallStringView comma{""};
-
- for (const auto &parameter : parameters) {
- json.append(comma);
- comma = ",";
- json.append(R"({"n":")");
- json.append(parameter.name);
- json.append(R"(","tn":")");
- json.append(parameter.typeName);
- if (parameter.traits == Storage::PropertyDeclarationTraits::None) {
- json.append("\"}");
- } else {
- json.append(R"(","tr":)");
- json.append(Utils::SmallString::number(to_underlying(parameter.traits)));
- json.append("}");
- }
- }
-
- json.append("]");
-
- return json;
- }
+ static Utils::PathString createJson(const Storage::Synchronization::ParameterDeclarations &parameters);
TypeId fetchTypeIdByModuleIdAndExportedName(ModuleId moduleId,
- Utils::SmallStringView name) const override
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch type id by module id and exported name"_t,
- projectStorageCategory(),
- keyValue("module id", moduleId),
- keyValue("exported name", name)};
+ Utils::SmallStringView name) const override;
- return selectTypeIdByModuleIdAndExportedNameStatement.template value<TypeId>(moduleId, name);
- }
-
- void addTypeIdToPropertyEditorQmlPaths(Storage::Synchronization::PropertyEditorQmlPaths &paths)
- {
- NanotraceHR::Tracer tracer{"add type id to property editor qml paths"_t,
- projectStorageCategory()};
-
- for (auto &path : paths)
- path.typeId = fetchTypeIdByModuleIdAndExportedName(path.moduleId, path.typeName);
- }
+ void addTypeIdToPropertyEditorQmlPaths(Storage::Synchronization::PropertyEditorQmlPaths &paths);
class PropertyEditorQmlPathView
{
@@ -2967,358 +782,33 @@ private:
};
void synchronizePropertyEditorPaths(Storage::Synchronization::PropertyEditorQmlPaths &paths,
- SourceIds updatedPropertyEditorQmlPathsSourceIds)
- {
- using Storage::Synchronization::PropertyEditorQmlPath;
- std::sort(paths.begin(), paths.end(), [](auto &&first, auto &&second) {
- return first.typeId < second.typeId;
- });
-
- auto range = selectPropertyEditorPathsForForSourceIdsStatement
- .template range<PropertyEditorQmlPathView>(
- toIntegers(updatedPropertyEditorQmlPathsSourceIds));
-
- auto compareKey = [](const PropertyEditorQmlPathView &view,
- const PropertyEditorQmlPath &value) -> long long {
- return view.typeId - value.typeId;
- };
-
- auto insert = [&](const PropertyEditorQmlPath &path) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert property editor paths"_t,
- projectStorageCategory(),
- keyValue("property editor qml path", path)};
-
- if (path.typeId)
- insertPropertyEditorPathStatement.write(path.typeId, path.pathId, path.directoryId);
- };
-
- auto update = [&](const PropertyEditorQmlPathView &view, const PropertyEditorQmlPath &value) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"update property editor paths"_t,
- projectStorageCategory(),
- keyValue("property editor qml path", value),
- keyValue("property editor qml path view", view)};
-
- if (value.pathId != view.pathId || value.directoryId != view.directoryId) {
- updatePropertyEditorPathsStatement.write(value.typeId, value.pathId, value.directoryId);
-
- tracer.end(keyValue("updated", "yes"));
-
- return Sqlite::UpdateChange::Update;
- }
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const PropertyEditorQmlPathView &view) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove property editor paths"_t,
- projectStorageCategory(),
- keyValue("property editor qml path view", view)};
-
- deletePropertyEditorPathStatement.write(view.typeId);
- };
-
- Sqlite::insertUpdateDelete(range, paths, compareKey, insert, update, remove);
- }
+ SourceIds updatedPropertyEditorQmlPathsSourceIds);
void synchronizePropertyEditorQmlPaths(Storage::Synchronization::PropertyEditorQmlPaths &paths,
- SourceIds updatedPropertyEditorQmlPathsSourceIds)
- {
- NanotraceHR::Tracer tracer{"synchronize property editor qml paths"_t,
- projectStorageCategory()};
-
- addTypeIdToPropertyEditorQmlPaths(paths);
- synchronizePropertyEditorPaths(paths, updatedPropertyEditorQmlPathsSourceIds);
- }
+ SourceIds updatedPropertyEditorQmlPathsSourceIds);
void synchronizeFunctionDeclarations(
- TypeId typeId, Storage::Synchronization::FunctionDeclarations &functionsDeclarations)
- {
- NanotraceHR::Tracer tracer{"synchronize function declaration"_t, projectStorageCategory()};
-
- std::sort(functionsDeclarations.begin(),
- functionsDeclarations.end(),
- [](auto &&first, auto &&second) {
- auto compare = Sqlite::compare(first.name, second.name);
-
- if (compare == 0) {
- Utils::PathString firstSignature{createJson(first.parameters)};
- Utils::PathString secondSignature{createJson(second.parameters)};
-
- return Sqlite::compare(firstSignature, secondSignature) < 0;
- }
-
- return compare < 0;
- });
-
- auto range = selectFunctionDeclarationsForTypeIdStatement
- .template range<Storage::Synchronization::FunctionDeclarationView>(typeId);
-
- auto compareKey = [](const Storage::Synchronization::FunctionDeclarationView &view,
- const Storage::Synchronization::FunctionDeclaration &value) {
- auto nameKey = Sqlite::compare(view.name, value.name);
- if (nameKey != 0)
- return nameKey;
-
- Utils::PathString valueSignature{createJson(value.parameters)};
-
- return Sqlite::compare(view.signature, valueSignature);
- };
-
- auto insert = [&](const Storage::Synchronization::FunctionDeclaration &value) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert function declaration"_t,
- projectStorageCategory(),
- keyValue("function declaration", value)};
-
- Utils::PathString signature{createJson(value.parameters)};
-
- insertFunctionDeclarationStatement.write(typeId, value.name, value.returnTypeName, signature);
- };
-
- auto update = [&](const Storage::Synchronization::FunctionDeclarationView &view,
- const Storage::Synchronization::FunctionDeclaration &value) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"update function declaration"_t,
- projectStorageCategory(),
- keyValue("function declaration", value),
- keyValue("function declaration view", view)};
-
- Utils::PathString signature{createJson(value.parameters)};
-
- if (value.returnTypeName == view.returnTypeName)
- return Sqlite::UpdateChange::No;
-
- updateFunctionDeclarationStatement.write(view.id, value.returnTypeName);
-
- tracer.end(keyValue("updated", "yes"));
-
- return Sqlite::UpdateChange::Update;
- };
-
- auto remove = [&](const Storage::Synchronization::FunctionDeclarationView &view) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove function declaration"_t,
- projectStorageCategory(),
- keyValue("function declaration view", view)};
-
- deleteFunctionDeclarationStatement.write(view.id);
- };
-
- Sqlite::insertUpdateDelete(range, functionsDeclarations, compareKey, insert, update, remove);
- }
+ TypeId typeId, Storage::Synchronization::FunctionDeclarations &functionsDeclarations);
void synchronizeSignalDeclarations(TypeId typeId,
- Storage::Synchronization::SignalDeclarations &signalDeclarations)
- {
- NanotraceHR::Tracer tracer{"synchronize signal declaration"_t, projectStorageCategory()};
-
- std::sort(signalDeclarations.begin(), signalDeclarations.end(), [](auto &&first, auto &&second) {
- auto compare = Sqlite::compare(first.name, second.name);
-
- if (compare == 0) {
- Utils::PathString firstSignature{createJson(first.parameters)};
- Utils::PathString secondSignature{createJson(second.parameters)};
-
- return Sqlite::compare(firstSignature, secondSignature) < 0;
- }
-
- return compare < 0;
- });
-
- auto range = selectSignalDeclarationsForTypeIdStatement
- .template range<Storage::Synchronization::SignalDeclarationView>(typeId);
-
- auto compareKey = [](const Storage::Synchronization::SignalDeclarationView &view,
- const Storage::Synchronization::SignalDeclaration &value) {
- auto nameKey = Sqlite::compare(view.name, value.name);
- if (nameKey != 0)
- return nameKey;
-
- Utils::PathString valueSignature{createJson(value.parameters)};
-
- return Sqlite::compare(view.signature, valueSignature);
- };
-
- auto insert = [&](const Storage::Synchronization::SignalDeclaration &value) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert signal declaration"_t,
- projectStorageCategory(),
- keyValue("signal declaration", value)};
-
- Utils::PathString signature{createJson(value.parameters)};
-
- insertSignalDeclarationStatement.write(typeId, value.name, signature);
- };
-
- auto update = [&]([[maybe_unused]] const Storage::Synchronization::SignalDeclarationView &view,
- [[maybe_unused]] const Storage::Synchronization::SignalDeclaration &value) {
- return Sqlite::UpdateChange::No;
- };
-
- auto remove = [&](const Storage::Synchronization::SignalDeclarationView &view) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove signal declaration"_t,
- projectStorageCategory(),
- keyValue("signal declaration view", view)};
-
- deleteSignalDeclarationStatement.write(view.id);
- };
-
- Sqlite::insertUpdateDelete(range, signalDeclarations, compareKey, insert, update, remove);
- }
+ Storage::Synchronization::SignalDeclarations &signalDeclarations);
static Utils::PathString createJson(
- const Storage::Synchronization::EnumeratorDeclarations &enumeratorDeclarations)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"create json from enumerator declarations"_t,
- projectStorageCategory()};
-
- Utils::PathString json;
- json.append("{");
-
- Utils::SmallStringView comma{"\""};
-
- for (const auto &enumerator : enumeratorDeclarations) {
- json.append(comma);
- comma = ",\"";
- json.append(enumerator.name);
- if (enumerator.hasValue) {
- json.append("\":\"");
- json.append(Utils::SmallString::number(enumerator.value));
- json.append("\"");
- } else {
- json.append("\":null");
- }
- }
-
- json.append("}");
-
- return json;
- }
+ const Storage::Synchronization::EnumeratorDeclarations &enumeratorDeclarations);
void synchronizeEnumerationDeclarations(
- TypeId typeId, Storage::Synchronization::EnumerationDeclarations &enumerationDeclarations)
- {
- NanotraceHR::Tracer tracer{"synchronize enumeration declaration"_t, projectStorageCategory()};
-
- std::sort(enumerationDeclarations.begin(),
- enumerationDeclarations.end(),
- [](auto &&first, auto &&second) {
- return Sqlite::compare(first.name, second.name) < 0;
- });
-
- auto range = selectEnumerationDeclarationsForTypeIdStatement
- .template range<Storage::Synchronization::EnumerationDeclarationView>(typeId);
-
- auto compareKey = [](const Storage::Synchronization::EnumerationDeclarationView &view,
- const Storage::Synchronization::EnumerationDeclaration &value) {
- return Sqlite::compare(view.name, value.name);
- };
-
- auto insert = [&](const Storage::Synchronization::EnumerationDeclaration &value) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"insert enumeration declaration"_t,
- projectStorageCategory(),
- keyValue("enumeration declaration", value)};
-
- Utils::PathString signature{createJson(value.enumeratorDeclarations)};
-
- insertEnumerationDeclarationStatement.write(typeId, value.name, signature);
- };
-
- auto update = [&](const Storage::Synchronization::EnumerationDeclarationView &view,
- const Storage::Synchronization::EnumerationDeclaration &value) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"update enumeration declaration"_t,
- projectStorageCategory(),
- keyValue("enumeration declaration", value),
- keyValue("enumeration declaration view", view)};
-
- Utils::PathString enumeratorDeclarations{createJson(value.enumeratorDeclarations)};
-
- if (enumeratorDeclarations == view.enumeratorDeclarations)
- return Sqlite::UpdateChange::No;
-
- updateEnumerationDeclarationStatement.write(view.id, enumeratorDeclarations);
-
- tracer.end(keyValue("updated", "yes"));
-
- return Sqlite::UpdateChange::Update;
- };
-
- auto remove = [&](const Storage::Synchronization::EnumerationDeclarationView &view) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"remove enumeration declaration"_t,
- projectStorageCategory(),
- keyValue("enumeration declaration view", view)};
-
- deleteEnumerationDeclarationStatement.write(view.id);
- };
-
- Sqlite::insertUpdateDelete(range, enumerationDeclarations, compareKey, insert, update, remove);
- }
+ TypeId typeId, Storage::Synchronization::EnumerationDeclarations &enumerationDeclarations);
void extractExportedTypes(TypeId typeId,
const Storage::Synchronization::Type &type,
- Storage::Synchronization::ExportedTypes &exportedTypes)
- {
- for (const auto &exportedType : type.exportedTypes)
- exportedTypes.emplace_back(exportedType.name,
- exportedType.version,
- typeId,
- exportedType.moduleId);
- }
-
- TypeId declareType(Storage::Synchronization::Type &type)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"declare type"_t,
- projectStorageCategory(),
- keyValue("source id", type.sourceId),
- keyValue("type name", type.typeName)};
-
- if (type.typeName.isEmpty()) {
- type.typeId = selectTypeIdBySourceIdStatement.template value<TypeId>(type.sourceId);
+ Storage::Synchronization::ExportedTypes &exportedTypes);
- tracer.end(keyValue("type id", type.typeId));
-
- return type.typeId;
- }
-
- type.typeId = insertTypeStatement.template value<TypeId>(type.sourceId, type.typeName);
-
- if (!type.typeId)
- type.typeId = selectTypeIdBySourceIdAndNameStatement.template value<TypeId>(type.sourceId,
- type.typeName);
-
- tracer.end(keyValue("type id", type.typeId));
-
- return type.typeId;
- }
+ TypeId declareType(Storage::Synchronization::Type &type);
void syncDeclarations(Storage::Synchronization::Type &type,
AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
- PropertyDeclarationIds &propertyDeclarationIds)
- {
- NanotraceHR::Tracer tracer{"synchronize declaration per type"_t, projectStorageCategory()};
-
- if (type.changeLevel == Storage::Synchronization::ChangeLevel::Minimal)
- return;
-
- synchronizePropertyDeclarations(type.typeId,
- type.propertyDeclarations,
- type.sourceId,
- insertedAliasPropertyDeclarations,
- updatedAliasPropertyDeclarations,
- propertyDeclarationIds);
- synchronizeFunctionDeclarations(type.typeId, type.functionDeclarations);
- synchronizeSignalDeclarations(type.typeId, type.signalDeclarations);
- synchronizeEnumerationDeclarations(type.typeId, type.enumerationDeclarations);
- }
+ PropertyDeclarationIds &propertyDeclarationIds);
template<typename Relinkable, typename Ids, typename Compare>
void removeRelinkableEntries(std::vector<Relinkable> &relinkables, Ids &ids, Compare compare)
@@ -3345,23 +835,7 @@ private:
void syncDeclarations(Storage::Synchronization::Types &types,
AliasPropertyDeclarations &insertedAliasPropertyDeclarations,
AliasPropertyDeclarations &updatedAliasPropertyDeclarations,
- PropertyDeclarations &relinkablePropertyDeclarations)
- {
- NanotraceHR::Tracer tracer{"synchronize declaration"_t, projectStorageCategory()};
-
- PropertyDeclarationIds propertyDeclarationIds;
- propertyDeclarationIds.reserve(types.size() * 10);
-
- for (auto &&type : types)
- syncDeclarations(type,
- insertedAliasPropertyDeclarations,
- updatedAliasPropertyDeclarations,
- propertyDeclarationIds);
-
- removeRelinkableEntries(relinkablePropertyDeclarations,
- propertyDeclarationIds,
- PropertyCompare<PropertyDeclaration>{});
- }
+ PropertyDeclarations &relinkablePropertyDeclarations);
class TypeWithDefaultPropertyView
{
@@ -3386,279 +860,27 @@ private:
PropertyDeclarationId defaultPropertyId;
};
- void syncDefaultProperties(Storage::Synchronization::Types &types)
- {
- NanotraceHR::Tracer tracer{"synchronize default properties"_t, projectStorageCategory()};
-
- auto range = selectTypesWithDefaultPropertyStatement.template range<TypeWithDefaultPropertyView>();
-
- auto compareKey = [](const TypeWithDefaultPropertyView &view,
- const Storage::Synchronization::Type &value) {
- return view.typeId - value.typeId;
- };
+ void syncDefaultProperties(Storage::Synchronization::Types &types);
- auto insert = [&](const Storage::Synchronization::Type &) {
+ void resetDefaultPropertiesIfChanged(Storage::Synchronization::Types &types);
- };
+ void checkForPrototypeChainCycle(TypeId typeId) const;
- auto update = [&](const TypeWithDefaultPropertyView &view,
- const Storage::Synchronization::Type &value) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"synchronize default properties by update"_t,
- projectStorageCategory(),
- keyValue("type id", value.typeId),
- keyValue("value", value),
- keyValue("view", view)};
-
- PropertyDeclarationId valueDefaultPropertyId;
- if (value.defaultPropertyName.size())
- valueDefaultPropertyId = fetchPropertyDeclarationByTypeIdAndNameUngarded(
- value.typeId, value.defaultPropertyName)
- .propertyDeclarationId;
-
- if (compareInvalidAreTrue(valueDefaultPropertyId, view.defaultPropertyId))
- return Sqlite::UpdateChange::No;
-
- updateDefaultPropertyIdStatement.write(value.typeId, valueDefaultPropertyId);
-
- tracer.end(keyValue("updated", "yes"),
- keyValue("default property id", valueDefaultPropertyId));
-
- return Sqlite::UpdateChange::Update;
- };
-
- auto remove = [&](const TypeWithDefaultPropertyView &) {};
-
- Sqlite::insertUpdateDelete(range, types, compareKey, insert, update, remove);
- }
-
- void resetDefaultPropertiesIfChanged(Storage::Synchronization::Types &types)
- {
- NanotraceHR::Tracer tracer{"reset changed default properties"_t, projectStorageCategory()};
-
- auto range = selectTypesWithDefaultPropertyStatement.template range<TypeWithDefaultPropertyView>();
-
- auto compareKey = [](const TypeWithDefaultPropertyView &view,
- const Storage::Synchronization::Type &value) {
- return view.typeId - value.typeId;
- };
-
- auto insert = [&](const Storage::Synchronization::Type &) {
-
- };
-
- auto update = [&](const TypeWithDefaultPropertyView &view,
- const Storage::Synchronization::Type &value) {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"reset changed default properties by update"_t,
- projectStorageCategory(),
- keyValue("type id", value.typeId),
- keyValue("value", value),
- keyValue("view", view)};
-
- PropertyDeclarationId valueDefaultPropertyId;
- if (value.defaultPropertyName.size()) {
- auto optionalValueDefaultPropertyId = fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(
- value.typeId, value.defaultPropertyName);
- if (optionalValueDefaultPropertyId)
- valueDefaultPropertyId = optionalValueDefaultPropertyId->propertyDeclarationId;
- }
-
- if (compareInvalidAreTrue(valueDefaultPropertyId, view.defaultPropertyId))
- return Sqlite::UpdateChange::No;
-
- updateDefaultPropertyIdStatement.write(value.typeId, Sqlite::NullValue{});
-
- tracer.end(keyValue("updated", "yes"));
-
- return Sqlite::UpdateChange::Update;
- };
-
- auto remove = [&](const TypeWithDefaultPropertyView &) {};
-
- Sqlite::insertUpdateDelete(range, types, compareKey, insert, update, remove);
- }
-
- void checkForPrototypeChainCycle(TypeId typeId) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"check for prototype chain cycle"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- auto callback = [=](TypeId currentTypeId) {
- if (typeId == currentTypeId)
- throw PrototypeChainCycle{};
- };
-
- selectPrototypeAndExtensionIdsStatement.readCallback(callback, typeId);
- }
-
- void checkForAliasChainCycle(PropertyDeclarationId propertyDeclarationId) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"check for alias chain cycle"_t,
- projectStorageCategory(),
- keyValue("property declaration id", propertyDeclarationId)};
- auto callback = [=](PropertyDeclarationId currentPropertyDeclarationId) {
- if (propertyDeclarationId == currentPropertyDeclarationId)
- throw AliasChainCycle{};
- };
-
- selectPropertyDeclarationIdsForAliasChainStatement.readCallback(callback,
- propertyDeclarationId);
- }
+ void checkForAliasChainCycle(PropertyDeclarationId propertyDeclarationId) const;
std::pair<TypeId, ImportedTypeNameId> fetchImportedTypeNameIdAndTypeId(
- const Storage::Synchronization::ImportedTypeName &typeName, SourceId sourceId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch imported type name id and type id"_t,
- projectStorageCategory(),
- keyValue("imported type name", typeName),
- keyValue("source id", sourceId)};
-
- TypeId typeId;
- ImportedTypeNameId typeNameId;
- if (!std::visit([](auto &&typeName_) -> bool { return typeName_.name.isEmpty(); }, typeName)) {
- typeNameId = fetchImportedTypeNameId(typeName, sourceId);
-
- typeId = fetchTypeId(typeNameId);
+ const Storage::Synchronization::ImportedTypeName &typeName, SourceId sourceId);
- tracer.end(keyValue("type id", typeId), keyValue("type name id", typeNameId));
-
- if (!typeId)
- throw TypeNameDoesNotExists{fetchImportedTypeName(typeNameId), sourceId};
- }
-
- return {typeId, typeNameId};
- }
-
- void syncPrototypeAndExtension(Storage::Synchronization::Type &type, TypeIds &typeIds)
- {
- if (type.changeLevel == Storage::Synchronization::ChangeLevel::Minimal)
- return;
-
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"synchronize prototype and extension"_t,
- projectStorageCategory(),
- keyValue("prototype", type.prototype),
- keyValue("extension", type.extension),
- keyValue("type id", type.typeId),
- keyValue("source id", type.sourceId)};
-
- auto [prototypeId, prototypeTypeNameId] = fetchImportedTypeNameIdAndTypeId(type.prototype,
- type.sourceId);
- auto [extensionId, extensionTypeNameId] = fetchImportedTypeNameIdAndTypeId(type.extension,
- type.sourceId);
-
- updatePrototypeAndExtensionStatement.write(type.typeId,
- prototypeId,
- prototypeTypeNameId,
- extensionId,
- extensionTypeNameId);
-
- if (prototypeId || extensionId)
- checkForPrototypeChainCycle(type.typeId);
-
- typeIds.push_back(type.typeId);
-
- tracer.end(keyValue("prototype id", prototypeId),
- keyValue("prototype type name id", prototypeTypeNameId),
- keyValue("extension id", extensionId),
- keyValue("extension type name id", extensionTypeNameId));
- }
+ void syncPrototypeAndExtension(Storage::Synchronization::Type &type, TypeIds &typeIds);
void syncPrototypesAndExtensions(Storage::Synchronization::Types &types,
Prototypes &relinkablePrototypes,
- Prototypes &relinkableExtensions)
- {
- NanotraceHR::Tracer tracer{"synchronize prototypes and extensions"_t,
- projectStorageCategory()};
+ Prototypes &relinkableExtensions);
- TypeIds typeIds;
- typeIds.reserve(types.size());
-
- for (auto &type : types)
- syncPrototypeAndExtension(type, typeIds);
-
- removeRelinkableEntries(relinkablePrototypes, typeIds, TypeCompare<Prototype>{});
- removeRelinkableEntries(relinkableExtensions, typeIds, TypeCompare<Prototype>{});
- }
-
- ImportId fetchImportId(SourceId sourceId, const Storage::Import &import) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch imported type name id"_t,
- projectStorageCategory(),
- keyValue("import", import),
- keyValue("source id", sourceId)};
-
- ImportId importId;
- if (import.version) {
- importId = selectImportIdBySourceIdAndModuleIdAndVersionStatement.template value<ImportId>(
- sourceId, import.moduleId, import.version.major.value, import.version.minor.value);
- } else if (import.version.major) {
- importId = selectImportIdBySourceIdAndModuleIdAndMajorVersionStatement
- .template value<ImportId>(sourceId,
- import.moduleId,
- import.version.major.value);
- } else {
- importId = selectImportIdBySourceIdAndModuleIdStatement
- .template value<ImportId>(sourceId, import.moduleId);
- }
-
- tracer.end(keyValue("import id", importId));
-
- return importId;
- }
+ ImportId fetchImportId(SourceId sourceId, const Storage::Import &import) const;
ImportedTypeNameId fetchImportedTypeNameId(const Storage::Synchronization::ImportedTypeName &name,
- SourceId sourceId)
- {
- struct Inspect
- {
- auto operator()(const Storage::Synchronization::ImportedType &importedType)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch imported type name id"_t,
- projectStorageCategory(),
- keyValue("imported type name", importedType.name),
- keyValue("source id", sourceId),
- keyValue("type name kind", "exported"sv)};
-
- return storage.fetchImportedTypeNameId(Storage::Synchronization::TypeNameKind::Exported,
- sourceId,
- importedType.name);
- }
-
- auto operator()(const Storage::Synchronization::QualifiedImportedType &importedType)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch imported type name id"_t,
- projectStorageCategory(),
- keyValue("imported type name", importedType.name),
- keyValue("import", importedType.import),
- keyValue("type name kind", "qualified exported"sv)};
-
- ImportId importId = storage.fetchImportId(sourceId, importedType.import);
-
- auto importedTypeNameId = storage.fetchImportedTypeNameId(
- Storage::Synchronization::TypeNameKind::QualifiedExported,
- importId,
- importedType.name);
-
- tracer.end(keyValue("import id", importId), keyValue("source id", sourceId));
-
- return importedTypeNameId;
- }
-
- ProjectStorage &storage;
- SourceId sourceId;
- };
-
- return std::visit(Inspect{*this, sourceId}, name);
- }
+ SourceId sourceId);
template<typename Id>
ImportedTypeNameId fetchImportedTypeNameId(Storage::Synchronization::TypeNameKind kind,
@@ -3671,60 +893,26 @@ private:
keyValue("imported type name", typeName),
keyValue("kind", kind)};
- auto importedTypeNameId = selectImportedTypeNameIdStatement
- .template value<ImportedTypeNameId>(kind, id, typeName);
+ auto importedTypeNameId = selectImportedTypeNameIdStatement.value<ImportedTypeNameId>(kind,
+ id,
+ typeName);
if (!importedTypeNameId)
- importedTypeNameId = insertImportedTypeNameIdStatement
- .template value<ImportedTypeNameId>(kind, id, typeName);
+ importedTypeNameId = insertImportedTypeNameIdStatement.value<ImportedTypeNameId>(kind,
+ id,
+ typeName);
tracer.end(keyValue("imported type name id", importedTypeNameId));
return importedTypeNameId;
}
- TypeId fetchTypeId(ImportedTypeNameId typeNameId) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch type id with type name kind"_t,
- projectStorageCategory(),
- keyValue("type name id", typeNameId)};
-
- auto kind = selectKindFromImportedTypeNamesStatement
- .template value<Storage::Synchronization::TypeNameKind>(typeNameId);
-
- auto typeId = fetchTypeId(typeNameId, kind);
-
- tracer.end(keyValue("type id", typeId), keyValue("type name kind", kind));
-
- return typeId;
- }
-
- Utils::SmallString fetchImportedTypeName(ImportedTypeNameId typeNameId) const
- {
- return selectNameFromImportedTypeNamesStatement.template value<Utils::SmallString>(typeNameId);
- }
+ TypeId fetchTypeId(ImportedTypeNameId typeNameId) const;
- TypeId fetchTypeId(ImportedTypeNameId typeNameId, Storage::Synchronization::TypeNameKind kind) const
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch type id"_t,
- projectStorageCategory(),
- keyValue("type name id", typeNameId),
- keyValue("type name kind", kind)};
+ Utils::SmallString fetchImportedTypeName(ImportedTypeNameId typeNameId) const;
- TypeId typeId;
- if (kind == Storage::Synchronization::TypeNameKind::Exported) {
- typeId = selectTypeIdForImportedTypeNameNamesStatement.template value<TypeId>(typeNameId);
- } else {
- typeId = selectTypeIdForQualifiedImportedTypeNameNamesStatement.template value<TypeId>(
- typeNameId);
- }
-
- tracer.end(keyValue("type id", typeId));
-
- return typeId;
- }
+ TypeId fetchTypeId(ImportedTypeNameId typeNameId,
+ Storage::Synchronization::TypeNameKind kind) const;
class FetchPropertyDeclarationResult
{
@@ -3755,641 +943,41 @@ private:
Storage::PropertyDeclarationTraits propertyTraits;
};
- auto fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(TypeId typeId,
- Utils::SmallStringView name)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch optional property declaration by type id and name ungarded"_t,
- projectStorageCategory(),
- keyValue("type id", typeId),
- keyValue("property name", name)};
-
- auto propertyDeclarationId = fetchPropertyDeclarationId(typeId, name);
- auto propertyDeclaration = selectPropertyDeclarationResultByPropertyDeclarationIdStatement
- .template optionalValue<FetchPropertyDeclarationResult>(
- propertyDeclarationId);
-
- tracer.end(keyValue("property declaration", propertyDeclaration));
-
- return propertyDeclaration;
- }
+ std::optional<FetchPropertyDeclarationResult> fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(
+ TypeId typeId, Utils::SmallStringView name);
FetchPropertyDeclarationResult fetchPropertyDeclarationByTypeIdAndNameUngarded(
- TypeId typeId, Utils::SmallStringView name)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch property declaration by type id and name ungarded"_t,
- projectStorageCategory(),
- keyValue("type id", typeId),
- keyValue("property name", name)};
-
- auto propertyDeclaration = fetchOptionalPropertyDeclarationByTypeIdAndNameUngarded(typeId,
- name);
- tracer.end(keyValue("property declaration", propertyDeclaration));
-
- if (propertyDeclaration)
- return *propertyDeclaration;
-
- throw PropertyNameDoesNotExists{};
- }
+ TypeId typeId, Utils::SmallStringView name);
PropertyDeclarationId fetchPropertyDeclarationIdByTypeIdAndNameUngarded(TypeId typeId,
- Utils::SmallStringView name)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch property declaration id by type id and name ungarded"_t,
- projectStorageCategory(),
- keyValue("type id", typeId),
- keyValue("property name", name)};
-
- auto propertyDeclarationId = fetchPropertyDeclarationId(typeId, name);
-
- tracer.end(keyValue("property declaration id", propertyDeclarationId));
-
- if (propertyDeclarationId)
- return propertyDeclarationId;
-
- throw PropertyNameDoesNotExists{};
- }
-
- SourceContextId readSourceContextId(Utils::SmallStringView sourceContextPath)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"read source context id"_t,
- projectStorageCategory(),
- keyValue("source context path", sourceContextPath)};
-
- auto sourceContextId = selectSourceContextIdFromSourceContextsBySourceContextPathStatement
- .template value<SourceContextId>(sourceContextPath);
-
- tracer.end(keyValue("source context id", sourceContextId));
-
- return sourceContextId;
- }
-
- SourceContextId writeSourceContextId(Utils::SmallStringView sourceContextPath)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"write source context id"_t,
- projectStorageCategory(),
- keyValue("source context path", sourceContextPath)};
-
- insertIntoSourceContextsStatement.write(sourceContextPath);
-
- auto sourceContextId = SourceContextId::create(database.lastInsertedRowId());
-
- tracer.end(keyValue("source context id", sourceContextId));
-
- return sourceContextId;
- }
-
- SourceId writeSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"write source id"_t,
- projectStorageCategory(),
- keyValue("source context id", sourceContextId),
- keyValue("source name", sourceName)};
-
- insertIntoSourcesStatement.write(sourceContextId, sourceName);
-
- auto sourceId = SourceId::create(database.lastInsertedRowId());
-
- tracer.end(keyValue("source id", sourceId));
-
- return sourceId;
- }
-
- SourceId readSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"read source id"_t,
- projectStorageCategory(),
- keyValue("source context id", sourceContextId),
- keyValue("source name", sourceName)};
-
- auto sourceId = selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatement
- .template value<SourceId>(sourceContextId, sourceName);
-
- tracer.end(keyValue("source id", sourceId));
-
- return sourceId;
- }
-
- auto fetchExportedTypes(TypeId typeId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch exported type"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- auto typeIds = selectExportedTypesByTypeIdStatement
- .template values<Storage::Synchronization::ExportedType, 12>(typeId);
-
- tracer.end(keyValue("type ids", typeIds));
-
- return typeIds;
- }
-
- auto fetchPropertyDeclarations(TypeId typeId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch property declarations"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- auto propertyDeclarations = selectPropertyDeclarationsByTypeIdStatement
- .template values<Storage::Synchronization::PropertyDeclaration, 24>(
- typeId);
-
- tracer.end(keyValue("property declarations", propertyDeclarations));
-
- return propertyDeclarations;
- }
-
- auto fetchFunctionDeclarations(TypeId typeId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch signal declarations"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- Storage::Synchronization::FunctionDeclarations functionDeclarations;
-
- auto callback = [&](Utils::SmallStringView name,
- Utils::SmallStringView returnType,
- FunctionDeclarationId functionDeclarationId) {
- auto &functionDeclaration = functionDeclarations.emplace_back(name, returnType);
- functionDeclaration.parameters = selectFunctionParameterDeclarationsStatement
- .template values<Storage::Synchronization::ParameterDeclaration,
- 8>(functionDeclarationId);
- };
-
- selectFunctionDeclarationsForTypeIdWithoutSignatureStatement.readCallback(callback, typeId);
+ Utils::SmallStringView name);
- tracer.end(keyValue("function declarations", functionDeclarations));
+ SourceContextId readSourceContextId(Utils::SmallStringView sourceContextPath);
- return functionDeclarations;
- }
-
- auto fetchSignalDeclarations(TypeId typeId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch signal declarations"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- Storage::Synchronization::SignalDeclarations signalDeclarations;
-
- auto callback = [&](Utils::SmallStringView name, SignalDeclarationId signalDeclarationId) {
- auto &signalDeclaration = signalDeclarations.emplace_back(name);
- signalDeclaration.parameters = selectSignalParameterDeclarationsStatement
- .template values<Storage::Synchronization::ParameterDeclaration,
- 8>(signalDeclarationId);
- };
-
- selectSignalDeclarationsForTypeIdWithoutSignatureStatement.readCallback(callback, typeId);
-
- tracer.end(keyValue("signal declarations", signalDeclarations));
-
- return signalDeclarations;
- }
-
- auto fetchEnumerationDeclarations(TypeId typeId)
- {
- using NanotraceHR::keyValue;
- NanotraceHR::Tracer tracer{"fetch enumeration declarations"_t,
- projectStorageCategory(),
- keyValue("type id", typeId)};
-
- Storage::Synchronization::EnumerationDeclarations enumerationDeclarations;
-
- auto callback = [&](Utils::SmallStringView name,
- EnumerationDeclarationId enumerationDeclarationId) {
- enumerationDeclarations.emplace_back(
- name,
- selectEnumeratorDeclarationStatement
- .template values<Storage::Synchronization::EnumeratorDeclaration, 8>(
- enumerationDeclarationId));
- };
-
- selectEnumerationDeclarationsForTypeIdWithoutEnumeratorDeclarationsStatement
- .readCallback(callback, typeId);
-
- tracer.end(keyValue("enumeration declarations", enumerationDeclarations));
-
- return enumerationDeclarations;
- }
-
- class Initializer
- {
- public:
- Initializer(Database &database, bool isInitialized)
- {
- if (!isInitialized) {
- auto moduleIdColumn = createModulesTable(database);
- createSourceContextsTable(database);
- createSourcesTable(database);
- createTypesAndePropertyDeclarationsTables(database, moduleIdColumn);
- createExportedTypeNamesTable(database, moduleIdColumn);
- createImportedTypeNamesTable(database);
- createEnumerationsTable(database);
- createFunctionsTable(database);
- createSignalsTable(database);
- createModuleExportedImportsTable(database, moduleIdColumn);
- createDocumentImportsTable(database, moduleIdColumn);
- createFileStatusesTable(database);
- createProjectDatasTable(database);
- createPropertyEditorPathsTable(database);
- createTypeAnnotionsTable(database);
- }
- database.setIsInitialized(true);
- }
-
- void createSourceContextsTable(Database &database)
- {
- Sqlite::Table table;
- table.setUseIfNotExists(true);
- table.setName("sourceContexts");
- table.addColumn("sourceContextId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
- const Sqlite::Column &sourceContextPathColumn = table.addColumn("sourceContextPath");
-
- table.addUniqueIndex({sourceContextPathColumn});
-
- table.initialize(database);
- }
-
- void createSourcesTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("sources");
- table.addColumn("sourceId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}});
- const auto &sourceContextIdColumn = table.addColumn(
- "sourceContextId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::NotNull{},
- Sqlite::ForeignKey{"sourceContexts",
- "sourceContextId",
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Cascade}});
- const auto &sourceNameColumn = table.addColumn("sourceName",
- Sqlite::StrictColumnType::Text);
- table.addUniqueIndex({sourceContextIdColumn, sourceNameColumn});
-
- table.initialize(database);
- }
-
- void createTypesAndePropertyDeclarationsTables(
- Database &database, [[maybe_unused]] const Sqlite::StrictColumn &foreignModuleIdColumn)
- {
- Sqlite::StrictTable typesTable;
- typesTable.setUseIfNotExists(true);
- typesTable.setName("types");
- typesTable.addColumn("typeId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}});
- auto &sourceIdColumn = typesTable.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
- auto &typesNameColumn = typesTable.addColumn("name", Sqlite::StrictColumnType::Text);
- typesTable.addColumn("traits", Sqlite::StrictColumnType::Integer);
- auto &prototypeIdColumn = typesTable.addForeignKeyColumn("prototypeId",
- typesTable,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Restrict);
- typesTable.addColumn("prototypeNameId", Sqlite::StrictColumnType::Integer);
- auto &extensionIdColumn = typesTable.addForeignKeyColumn("extensionId",
- typesTable,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Restrict);
- typesTable.addColumn("extensionNameId", Sqlite::StrictColumnType::Integer);
- auto &defaultPropertyIdColumn = typesTable.addColumn("defaultPropertyId",
- Sqlite::StrictColumnType::Integer);
- typesTable.addColumn("annotationTraits", Sqlite::StrictColumnType::Integer);
- typesTable.addUniqueIndex({sourceIdColumn, typesNameColumn});
- typesTable.addIndex({defaultPropertyIdColumn});
- typesTable.addIndex({prototypeIdColumn});
- typesTable.addIndex({extensionIdColumn});
-
- typesTable.initialize(database);
-
- {
- Sqlite::StrictTable propertyDeclarationTable;
- propertyDeclarationTable.setUseIfNotExists(true);
- propertyDeclarationTable.setName("propertyDeclarations");
- propertyDeclarationTable.addColumn("propertyDeclarationId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{}});
- auto &typeIdColumn = propertyDeclarationTable.addColumn("typeId");
- auto &nameColumn = propertyDeclarationTable.addColumn("name");
- auto &propertyTypeIdColumn = propertyDeclarationTable.addForeignKeyColumn(
- "propertyTypeId",
- typesTable,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Restrict);
- propertyDeclarationTable.addColumn("propertyTraits",
- Sqlite::StrictColumnType::Integer);
- propertyDeclarationTable.addColumn("propertyImportedTypeNameId",
- Sqlite::StrictColumnType::Integer);
- auto &aliasPropertyDeclarationIdColumn = propertyDeclarationTable.addForeignKeyColumn(
- "aliasPropertyDeclarationId",
- propertyDeclarationTable,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Restrict);
- auto &aliasPropertyDeclarationTailIdColumn = propertyDeclarationTable.addForeignKeyColumn(
- "aliasPropertyDeclarationTailId",
- propertyDeclarationTable,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Restrict);
-
- propertyDeclarationTable.addUniqueIndex({typeIdColumn, nameColumn});
- propertyDeclarationTable.addIndex({propertyTypeIdColumn});
- propertyDeclarationTable.addIndex({aliasPropertyDeclarationIdColumn},
- "aliasPropertyDeclarationId IS NOT NULL");
- propertyDeclarationTable.addIndex({aliasPropertyDeclarationTailIdColumn},
- "aliasPropertyDeclarationTailId IS NOT NULL");
-
- propertyDeclarationTable.initialize(database);
- }
- }
-
- void createExportedTypeNamesTable(Database &database,
- const Sqlite::StrictColumn &foreignModuleIdColumn)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("exportedTypeNames");
- table.addColumn("exportedTypeNameId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{}});
- auto &moduleIdColumn = table.addForeignKeyColumn("moduleId",
- foreignModuleIdColumn,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::NoAction);
- auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
- auto &typeIdColumn = table.addColumn("typeId", Sqlite::StrictColumnType::Integer);
- auto &majorVersionColumn = table.addColumn("majorVersion",
- Sqlite::StrictColumnType::Integer);
- auto &minorVersionColumn = table.addColumn("minorVersion",
- Sqlite::StrictColumnType::Integer);
-
- table.addUniqueIndex({moduleIdColumn, nameColumn},
- "majorVersion IS NULL AND minorVersion IS NULL");
- table.addUniqueIndex({moduleIdColumn, nameColumn, majorVersionColumn},
- "majorVersion IS NOT NULL AND minorVersion IS NULL");
- table.addUniqueIndex({moduleIdColumn, nameColumn, majorVersionColumn, minorVersionColumn},
- "majorVersion IS NOT NULL AND minorVersion IS NOT NULL");
-
- table.addIndex({typeIdColumn});
- table.addIndex({moduleIdColumn, nameColumn});
-
- table.initialize(database);
- }
+ SourceContextId writeSourceContextId(Utils::SmallStringView sourceContextPath);
- void createImportedTypeNamesTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("importedTypeNames");
- table.addColumn("importedTypeNameId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{}});
- auto &importOrSourceIdColumn = table.addColumn("importOrSourceId");
- auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
- auto &kindColumn = table.addColumn("kind", Sqlite::StrictColumnType::Integer);
-
- table.addUniqueIndex({kindColumn, importOrSourceIdColumn, nameColumn});
- table.addIndex({nameColumn});
-
- table.initialize(database);
- }
-
- void createEnumerationsTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("enumerationDeclarations");
- table.addColumn("enumerationDeclarationId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{}});
- auto &typeIdColumn = table.addColumn("typeId", Sqlite::StrictColumnType::Integer);
- auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
- table.addColumn("enumeratorDeclarations", Sqlite::StrictColumnType::Text);
-
- table.addUniqueIndex({typeIdColumn, nameColumn});
-
- table.initialize(database);
- }
+ SourceId writeSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName);
- void createFunctionsTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("functionDeclarations");
- table.addColumn("functionDeclarationId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{}});
- auto &typeIdColumn = table.addColumn("typeId", Sqlite::StrictColumnType::Integer);
- auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
- auto &signatureColumn = table.addColumn("signature", Sqlite::StrictColumnType::Text);
- table.addColumn("returnTypeName");
-
- table.addUniqueIndex({typeIdColumn, nameColumn, signatureColumn});
-
- table.initialize(database);
- }
+ SourceId readSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName);
- void createSignalsTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("signalDeclarations");
- table.addColumn("signalDeclarationId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{}});
- auto &typeIdColumn = table.addColumn("typeId", Sqlite::StrictColumnType::Integer);
- auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
- auto &signatureColumn = table.addColumn("signature", Sqlite::StrictColumnType::Text);
-
- table.addUniqueIndex({typeIdColumn, nameColumn, signatureColumn});
-
- table.initialize(database);
- }
+ Storage::Synchronization::ExportedTypes fetchExportedTypes(TypeId typeId);
- Sqlite::StrictColumn createModulesTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("modules");
- auto &modelIdColumn = table.addColumn("moduleId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{}});
- auto &nameColumn = table.addColumn("name", Sqlite::StrictColumnType::Text);
+ Storage::Synchronization::PropertyDeclarations fetchPropertyDeclarations(TypeId typeId);
- table.addUniqueIndex({nameColumn});
+ Storage::Synchronization::FunctionDeclarations fetchFunctionDeclarations(TypeId typeId);
- table.initialize(database);
+ Storage::Synchronization::SignalDeclarations fetchSignalDeclarations(TypeId typeId);
- return std::move(modelIdColumn);
- }
+ Storage::Synchronization::EnumerationDeclarations fetchEnumerationDeclarations(TypeId typeId);
- void createModuleExportedImportsTable(Database &database,
- const Sqlite::StrictColumn &foreignModuleIdColumn)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("moduleExportedImports");
- table.addColumn("moduleExportedImportId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{}});
- auto &moduleIdColumn = table.addForeignKeyColumn("moduleId",
- foreignModuleIdColumn,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Cascade,
- Sqlite::Enforment::Immediate);
- auto &sourceIdColumn = table.addColumn("exportedModuleId",
- Sqlite::StrictColumnType::Integer);
- table.addColumn("isAutoVersion", Sqlite::StrictColumnType::Integer);
- table.addColumn("majorVersion", Sqlite::StrictColumnType::Integer);
- table.addColumn("minorVersion", Sqlite::StrictColumnType::Integer);
-
- table.addUniqueIndex({sourceIdColumn, moduleIdColumn});
-
- table.initialize(database);
- }
-
- void createDocumentImportsTable(Database &database,
- const Sqlite::StrictColumn &foreignModuleIdColumn)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("documentImports");
- table.addColumn("importId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}});
- auto &sourceIdColumn = table.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
- auto &moduleIdColumn = table.addForeignKeyColumn("moduleId",
- foreignModuleIdColumn,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Cascade,
- Sqlite::Enforment::Immediate);
- auto &sourceModuleIdColumn = table.addForeignKeyColumn("sourceModuleId",
- foreignModuleIdColumn,
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Cascade,
- Sqlite::Enforment::Immediate);
- auto &kindColumn = table.addColumn("kind", Sqlite::StrictColumnType::Integer);
- auto &majorVersionColumn = table.addColumn("majorVersion",
- Sqlite::StrictColumnType::Integer);
- auto &minorVersionColumn = table.addColumn("minorVersion",
- Sqlite::StrictColumnType::Integer);
- auto &parentImportIdColumn = table.addColumn("parentImportId",
- Sqlite::StrictColumnType::Integer);
-
- table.addUniqueIndex({sourceIdColumn,
- moduleIdColumn,
- kindColumn,
- sourceModuleIdColumn,
- parentImportIdColumn},
- "majorVersion IS NULL AND minorVersion IS NULL");
- table.addUniqueIndex({sourceIdColumn,
- moduleIdColumn,
- kindColumn,
- sourceModuleIdColumn,
- majorVersionColumn,
- parentImportIdColumn},
- "majorVersion IS NOT NULL AND minorVersion IS NULL");
- table.addUniqueIndex({sourceIdColumn,
- moduleIdColumn,
- kindColumn,
- sourceModuleIdColumn,
- majorVersionColumn,
- minorVersionColumn,
- parentImportIdColumn},
- "majorVersion IS NOT NULL AND minorVersion IS NOT NULL");
-
- table.addIndex({sourceIdColumn, kindColumn});
-
- table.initialize(database);
- }
-
- void createFileStatusesTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setName("fileStatuses");
- table.addColumn("sourceId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{},
- Sqlite::ForeignKey{"sources",
- "sourceId",
- Sqlite::ForeignKeyAction::NoAction,
- Sqlite::ForeignKeyAction::Cascade}});
- table.addColumn("size", Sqlite::StrictColumnType::Integer);
- table.addColumn("lastModified", Sqlite::StrictColumnType::Integer);
-
- table.initialize(database);
- }
-
- void createProjectDatasTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setUseWithoutRowId(true);
- table.setName("projectDatas");
- auto &projectSourceIdColumn = table.addColumn("projectSourceId",
- Sqlite::StrictColumnType::Integer);
- auto &sourceIdColumn = table.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
- table.addColumn("moduleId", Sqlite::StrictColumnType::Integer);
- table.addColumn("fileType", Sqlite::StrictColumnType::Integer);
-
- table.addPrimaryKeyContraint({projectSourceIdColumn, sourceIdColumn});
- table.addUniqueIndex({sourceIdColumn});
-
- table.initialize(database);
- }
-
- void createPropertyEditorPathsTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setUseWithoutRowId(true);
- table.setName("propertyEditorPaths");
- table.addColumn("typeId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}});
- table.addColumn("pathSourceId", Sqlite::StrictColumnType::Integer);
- auto &directoryIdColumn = table.addColumn("directoryId",
- Sqlite::StrictColumnType::Integer);
-
- table.addIndex({directoryIdColumn});
-
- table.initialize(database);
- }
-
- void createTypeAnnotionsTable(Database &database)
- {
- Sqlite::StrictTable table;
- table.setUseIfNotExists(true);
- table.setUseWithoutRowId(true);
- table.setName("typeAnnotations");
- auto &typeIdColumn = table.addColumn("typeId",
- Sqlite::StrictColumnType::Integer,
- {Sqlite::PrimaryKey{}});
- auto &sourceIdColumn = table.addColumn("sourceId", Sqlite::StrictColumnType::Integer);
- auto &directorySourceIdColumn = table.addColumn("directorySourceId",
- Sqlite::StrictColumnType::Integer);
-
- table.addColumn("iconPath", Sqlite::StrictColumnType::Text);
- table.addColumn("itemLibrary", Sqlite::StrictColumnType::Text);
- table.addColumn("hints", Sqlite::StrictColumnType::Text);
-
- table.addUniqueIndex({sourceIdColumn, typeIdColumn});
- table.addIndex({directorySourceIdColumn});
-
- table.initialize(database);
- }
- };
+ class Initializer;
public:
Database &database;
Sqlite::ExclusiveNonThrowingDestructorTransaction<Database> exclusiveTransaction;
- Initializer initializer;
+ std::unique_ptr<Initializer> initializer;
mutable ModuleCache moduleCache{ModuleStorageAdapter{*this}};
- Storage::Info::CommonTypeCache<ProjectStorageInterface> commonTypeCache_{*this};
+ Storage::Info::CommonTypeCache<ProjectStorageType> commonTypeCache_{*this};
QVarLengthArray<ProjectStorageObserver *, 24> observers;
ReadWriteStatement<1, 2> insertTypeStatement{
"INSERT OR IGNORE INTO types(sourceId, name) VALUES(?1, ?2) RETURNING typeId", database};
@@ -4564,8 +1152,10 @@ public:
"INSERT INTO functionDeclarations(typeId, name, returnTypeName, signature) VALUES(?1, ?2, "
"?3, ?4)",
database};
- WriteStatement<2> updateFunctionDeclarationStatement{
- "UPDATE functionDeclarations SET returnTypeName=?2 WHERE functionDeclarationId=?1", database};
+ WriteStatement<3> updateFunctionDeclarationStatement{"UPDATE functionDeclarations "
+ "SET returnTypeName=?2, signature=?3 "
+ "WHERE functionDeclarationId=?1",
+ database};
WriteStatement<1> deleteFunctionDeclarationStatement{
"DELETE FROM functionDeclarations WHERE functionDeclarationId=?", database};
mutable ReadStatement<3, 1> selectSignalDeclarationsForTypeIdStatement{
@@ -5078,6 +1668,5 @@ public:
database};
};
-extern template class ProjectStorage<Sqlite::Database>;
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h
index b33c609509..cbb7d4265a 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h
@@ -11,7 +11,6 @@ namespace QmlDesigner {
class ProjectStorageInterface;
class SourcePathCacheInterface;
-template<typename Database>
class ProjectStorage;
template<typename Type>
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h
index 20d988f7aa..971e635517 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h
@@ -84,7 +84,7 @@ public:
virtual std::optional<Storage::Synchronization::ProjectData> fetchProjectData(SourceId sourceId) const = 0;
virtual SourceId propertyEditorPathId(TypeId typeId) const = 0;
- virtual const Storage::Info::CommonTypeCache<ProjectStorageInterface> &commonTypeCache() const = 0;
+ virtual const Storage::Info::CommonTypeCache<ProjectStorageType> &commonTypeCache() const = 0;
template<const char *moduleName, const char *typeName>
TypeId commonTypeId() const
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h
index e21531deea..640969fe99 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h
@@ -32,7 +32,6 @@ class ProjectStorageInterface;
template<typename ProjectStorage, typename Mutex>
class SourcePathCache;
class FileStatusCache;
-template<typename Database>
class ProjectStorage;
class QmlDocumentParserInterface;
class QmlTypesParserInterface;
@@ -40,7 +39,7 @@ class QmlTypesParserInterface;
class ProjectStorageUpdater final : public ProjectStoragePathWatcherNotifierInterface
{
public:
- using PathCache = SourcePathCache<ProjectStorage<Sqlite::Database>, NonLockingMutex>;
+ using PathCache = SourcePathCache<ProjectStorage, NonLockingMutex>;
ProjectStorageUpdater(FileSystemInterface &fileSystem,
ProjectStorageType &projectStorage,
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h
index b8ab4ec4b1..1b494a2f69 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h
@@ -15,7 +15,7 @@ class SourcePathCache;
class QmlDocumentParser final : public QmlDocumentParserInterface
{
public:
- using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
+ using ProjectStorage = QmlDesigner::ProjectStorage;
using PathCache = QmlDesigner::SourcePathCache<ProjectStorage, NonLockingMutex>;
#ifdef QDS_BUILD_QMLPARSER
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h
index 7c41925f30..4a6427501b 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h
@@ -4,6 +4,7 @@
#pragma once
#include "nonlockingmutex.h"
+#include "projectstoragefwd.h"
#include "qmltypesparserinterface.h"
namespace Sqlite {
@@ -12,17 +13,13 @@ class Database;
namespace QmlDesigner {
-template<typename Database>
-class ProjectStorage;
-
template<typename ProjectStorage, typename Mutex>
class SourcePathCache;
class QmlTypesParser final : public QmlTypesParserInterface
{
public:
- using ProjectStorage = QmlDesigner::ProjectStorage<Sqlite::Database>;
-
+ using ProjectStorage = QmlDesigner::ProjectStorage;
#ifdef QDS_BUILD_QMLPARSER
QmlTypesParser(ProjectStorage &storage)
: m_storage{storage}
diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h
index 5feaf30d00..1ef8ba7f21 100644
--- a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h
+++ b/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h
@@ -125,4 +125,6 @@ public:
SourceContextId sourceContextId;
};
+using SourceNameAndSourceContextIds = std::vector<SourceNameAndSourceContextId>;
+
} // namespace QmlDesigner::Cache