QmlDesigner: Add moduleExportedImportId to project storage

If prevents collisions between the same import from different import
statements.

For example if there are to imports which are importing Qml in their
qmldir file you get an collision. So we add this id to prevent it.

Change-Id: I3a6a2331a350146ad1f90c0a95bd73f3bac4807a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2022-02-15 15:30:02 +01:00
parent ad8b8fca9b
commit 7084ee0eab
2 changed files with 102 additions and 27 deletions

View File

@@ -1308,7 +1308,8 @@ private:
void insertDocumentImport(const Storage::Import &import,
Storage::ImportKind importKind,
ModuleId sourceModuleId)
ModuleId sourceModuleId,
ModuleExportedImportId moduleExportedImportId)
{
if (import.version.minor) {
insertDocumentImportWithVersionStatement.write(&import.sourceId,
@@ -1316,18 +1317,21 @@ private:
&sourceModuleId,
to_underlying(importKind),
import.version.major.value,
import.version.minor.value);
import.version.minor.value,
&moduleExportedImportId);
} else if (import.version.major) {
insertDocumentImportWithMajorVersionStatement.write(&import.sourceId,
&import.moduleId,
&sourceModuleId,
to_underlying(importKind),
import.version.major.value);
import.version.major.value,
&moduleExportedImportId);
} else {
insertDocumentImportWithoutVersionStatement.write(&import.sourceId,
&import.moduleId,
&sourceModuleId,
to_underlying(importKind));
to_underlying(importKind),
&moduleExportedImportId);
}
}
@@ -1361,16 +1365,19 @@ private:
};
auto insert = [&](const Storage::Import &import) {
insertDocumentImport(import, importKind, import.moduleId);
auto callback = [&](int exportedModuleId, int majorVersion, int minorVersion) {
insertDocumentImport(import, importKind, import.moduleId, ModuleExportedImportId{});
auto callback = [&](int exportedModuleId,
int majorVersion,
int minorVersion,
long long moduleExportedImportId) {
Storage::Import additionImport{ModuleId{exportedModuleId},
Storage::Version{majorVersion, minorVersion},
import.sourceId};
insertDocumentImport(additionImport,
Storage::ImportKind::ModuleExportedImport,
import.moduleId);
insertDocumentImport(additionImport,
Storage::ImportKind::ModuleExportedImport,
import.moduleId,
ModuleExportedImportId{moduleExportedImportId});
return Sqlite::CallbackControl::Continue;
};
@@ -2194,16 +2201,25 @@ private:
auto &kindColumn = table.addColumn("kind");
auto &majorVersionColumn = table.addColumn("majorVersion");
auto &minorVersionColumn = table.addColumn("minorVersion");
auto &moduleExportedModuleIdColumn = table.addColumn("moduleExportedModuleId");
table.addUniqueIndex({sourceIdColumn, moduleIdColumn, sourceModuleIdColumn},
table.addUniqueIndex({sourceIdColumn,
moduleIdColumn,
sourceModuleIdColumn,
moduleExportedModuleIdColumn},
"majorVersion IS NULL AND minorVersion IS NULL");
table.addUniqueIndex({sourceIdColumn, moduleIdColumn, sourceModuleIdColumn, majorVersionColumn},
table.addUniqueIndex({sourceIdColumn,
moduleIdColumn,
sourceModuleIdColumn,
majorVersionColumn,
moduleExportedModuleIdColumn},
"majorVersion IS NOT NULL AND minorVersion IS NULL");
table.addUniqueIndex({sourceIdColumn,
moduleIdColumn,
sourceModuleIdColumn,
majorVersionColumn,
minorVersionColumn},
minorVersionColumn,
moduleExportedModuleIdColumn},
"majorVersion IS NOT NULL AND minorVersion IS NOT NULL");
table.initialize(database);
@@ -2486,17 +2502,17 @@ public:
"FROM documentImports WHERE sourceId IN carray(?1) AND kind=?2 ORDER BY sourceId, "
"moduleId, majorVersion, minorVersion",
database};
WriteStatement<4> insertDocumentImportWithoutVersionStatement{
"INSERT INTO documentImports(sourceId, moduleId, sourceModuleId, kind) "
"VALUES (?1, ?2, ?3, ?4)",
WriteStatement<5> insertDocumentImportWithoutVersionStatement{
"INSERT INTO documentImports(sourceId, moduleId, sourceModuleId, kind, "
"moduleExportedModuleId) VALUES (?1, ?2, ?3, ?4, ?5)",
database};
WriteStatement<5> insertDocumentImportWithMajorVersionStatement{
"INSERT INTO documentImports(sourceId, moduleId, sourceModuleId, kind, majorVersion) "
"VALUES (?1, ?2, ?3, ?4, ?5)",
database};
WriteStatement<6> insertDocumentImportWithVersionStatement{
WriteStatement<6> insertDocumentImportWithMajorVersionStatement{
"INSERT INTO documentImports(sourceId, moduleId, sourceModuleId, kind, majorVersion, "
"minorVersion) VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
"moduleExportedModuleId) VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
database};
WriteStatement<7> insertDocumentImportWithVersionStatement{
"INSERT INTO documentImports(sourceId, moduleId, sourceModuleId, kind, majorVersion, "
"minorVersion, moduleExportedModuleId) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
database};
WriteStatement<1> deleteDocumentImportStatement{"DELETE FROM documentImports WHERE importId=?1",
database};
@@ -2721,19 +2737,23 @@ public:
database};
WriteStatement<1> deleteModuleExportedImportStatement{
"DELETE FROM moduleExportedImports WHERE moduleExportedImportId=?1", database};
mutable ReadStatement<3, 3> selectModuleExportedImportsForModuleIdStatement{
mutable ReadStatement<4, 3> selectModuleExportedImportsForModuleIdStatement{
"WITH RECURSIVE "
" imports(moduleId, majorVersion, minorVersion) AS ( "
" imports(moduleId, majorVersion, minorVersion, moduleExportedImportId) AS ( "
" SELECT exportedModuleId, "
" iif(isAutoVersion=1, ?2, majorVersion), "
" iif(isAutoVersion=1, ?3, minorVersion)"
" iif(isAutoVersion=1, ?3, minorVersion), "
" moduleExportedImportId "
" FROM moduleExportedImports WHERE moduleId=?1 "
" UNION ALL "
" SELECT exportedModuleId, "
" iif(mei.isAutoVersion=1, i.majorVersion, mei.majorVersion), "
" iif(mei.isAutoVersion=1, i.minorVersion, mei.minorVersion)"
" iif(mei.isAutoVersion=1, i.minorVersion, mei.minorVersion), "
" mei.moduleExportedImportId "
" FROM moduleExportedImports AS mei JOIN imports AS i USING(moduleId)) "
"SELECT moduleId, ifnull(majorVersion, -1), ifnull(minorVersion, -1) FROM imports",
"SELECT moduleId, ifnull(majorVersion, -1), ifnull(minorVersion, -1), "
" moduleExportedImportId "
"FROM imports",
database};
};

View File

@@ -4041,4 +4041,59 @@ TEST_F(ProjectStorage, ModuleExportedImportWithIndirectDifferentVersions)
UnorderedElementsAre(IsExportedType(myModuleModuleId, "MyItem"))))));
}
TEST_F(ProjectStorage, ModuleExportedImportPreventCollisionIfModuleIsIndirectlyReexportedMultipleTimes)
{
ModuleId qtQuick4DModuleId{storage.moduleId("QtQuick4D")};
auto package{createModuleExportedImportSynchronizationPackage()};
package.imports.emplace_back(qtQuickModuleId, Storage::Version{1}, sourceId5);
package.moduleExportedImports.emplace_back(qtQuick4DModuleId,
qtQuickModuleId,
Storage::Version{},
Storage::IsAutoVersion::Yes);
package.moduleExportedImports.emplace_back(qtQuick4DModuleId,
qmlModuleId,
Storage::Version{},
Storage::IsAutoVersion::Yes);
package.updatedModuleIds.push_back(qtQuick4DModuleId);
package.types.push_back(
Storage::Type{"QQuickItem4d",
Storage::ImportedType{"Item"},
TypeAccessSemantics::Reference,
sourceId5,
{Storage::ExportedType{qtQuick4DModuleId, "Item4D", Storage::Version{1, 0}}}});
package.imports.emplace_back(qtQuick4DModuleId, Storage::Version{1}, sourceId4);
storage.synchronize(std::move(package));
ASSERT_THAT(storage.fetchTypes(),
UnorderedElementsAre(
AllOf(IsStorageType(sourceId1,
"QQuickItem",
fetchTypeId(sourceId2, "QObject"),
TypeAccessSemantics::Reference),
Field(&Storage::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(qtQuickModuleId, "Item")))),
AllOf(IsStorageType(sourceId2, "QObject", TypeId{}, TypeAccessSemantics::Reference),
Field(&Storage::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(qmlModuleId, "Object")))),
AllOf(IsStorageType(sourceId3,
"QQuickItem3d",
fetchTypeId(sourceId1, "QQuickItem"),
TypeAccessSemantics::Reference),
Field(&Storage::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(qtQuick3DModuleId, "Item3D")))),
AllOf(IsStorageType(sourceId5,
"QQuickItem4d",
fetchTypeId(sourceId1, "QQuickItem"),
TypeAccessSemantics::Reference),
Field(&Storage::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(qtQuick4DModuleId, "Item4D")))),
AllOf(IsStorageType(sourceId4,
"MyItem",
fetchTypeId(sourceId2, "QObject"),
TypeAccessSemantics::Reference),
Field(&Storage::Type::exportedTypes,
UnorderedElementsAre(IsExportedType(myModuleModuleId, "MyItem"))))));
}
} // namespace