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

View File

@@ -4041,4 +4041,59 @@ TEST_F(ProjectStorage, ModuleExportedImportWithIndirectDifferentVersions)
UnorderedElementsAre(IsExportedType(myModuleModuleId, "MyItem")))))); 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 } // namespace