forked from qt-creator/qt-creator
QmlDesigner: Relink alias properties
There are still some corner cases but this will be done in follow-up patches. The link information moved to the typenames table so only indirections are saved in the propertyDeclarations table. Otherwise the duplication would increase the database size too much. Task-number: QDS-4551 Change-Id: I4aca85dd2d803b43aa9860183e500ced2d91141f Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -83,7 +83,8 @@ enum class BasicIdType {
|
|||||||
FunctionDeclaration,
|
FunctionDeclaration,
|
||||||
SignalDeclaration,
|
SignalDeclaration,
|
||||||
EnumerationDeclaration,
|
EnumerationDeclaration,
|
||||||
Import
|
Import,
|
||||||
|
TypeName
|
||||||
};
|
};
|
||||||
|
|
||||||
using TypeId = BasicId<BasicIdType::Type>;
|
using TypeId = BasicId<BasicIdType::Type>;
|
||||||
@@ -110,4 +111,7 @@ using SourceIds = std::vector<SourceId>;
|
|||||||
using ImportId = BasicId<BasicIdType::Import>;
|
using ImportId = BasicId<BasicIdType::Import>;
|
||||||
using ImportIds = std::vector<ImportId>;
|
using ImportIds = std::vector<ImportId>;
|
||||||
|
|
||||||
|
using TypeNameId = BasicId<BasicIdType::TypeName>;
|
||||||
|
using TypeNameIds = std::vector<TypeNameId>;
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -70,6 +70,9 @@ public:
|
|||||||
updatedTypeIds.push_back(declareType(type));
|
updatedTypeIds.push_back(declareType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &&type : types)
|
||||||
|
syncPrototypes(type);
|
||||||
|
|
||||||
for (auto &&type : types)
|
for (auto &&type : types)
|
||||||
synchronizeAliasPropertyDeclarationsRemoval(type);
|
synchronizeAliasPropertyDeclarationsRemoval(type);
|
||||||
|
|
||||||
@@ -94,6 +97,16 @@ public:
|
|||||||
transaction.commit();
|
transaction.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void synchronizeDocuments(Storage::Documents documents)
|
||||||
|
{
|
||||||
|
Sqlite::ImmediateTransaction transaction{database};
|
||||||
|
|
||||||
|
for (auto &&document : documents)
|
||||||
|
synchronizeDocumentImports(document.sourceId, document.importIds);
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
|
||||||
ImportIds fetchImportIds(const Storage::Imports &imports)
|
ImportIds fetchImportIds(const Storage::Imports &imports)
|
||||||
{
|
{
|
||||||
ImportIds importIds;
|
ImportIds importIds;
|
||||||
@@ -108,6 +121,11 @@ public:
|
|||||||
return importIds;
|
return importIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImportIds fetchImportIds(SourceId sourceId)
|
||||||
|
{
|
||||||
|
return selectImportIdsForSourceIdStatement.template valeWithTransaction(16, &sourceId);
|
||||||
|
}
|
||||||
|
|
||||||
ImportIds fetchImportDependencyIds(ImportIds importIds) const
|
ImportIds fetchImportDependencyIds(ImportIds importIds) const
|
||||||
{
|
{
|
||||||
return fetchImportDependencyIdsStatement.template valuesWithTransaction<ImportId>(
|
return fetchImportDependencyIdsStatement.template valuesWithTransaction<ImportId>(
|
||||||
@@ -417,9 +435,108 @@ private:
|
|||||||
return selectImportIdByNameStatement.template value<ImportId>(import.name);
|
return selectImportIdByNameStatement.template value<ImportId>(import.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteType(TypeId typeId)
|
class AliasPropertyDeclaration
|
||||||
{
|
{
|
||||||
deleteExportTypesByTypeIdStatement.write(&typeId);
|
public:
|
||||||
|
explicit AliasPropertyDeclaration(PropertyDeclarationId propertyDeclarationId,
|
||||||
|
Storage::TypeName aliasTypeName,
|
||||||
|
Utils::SmallString &&aliasPropertyName,
|
||||||
|
SourceId sourceId)
|
||||||
|
: propertyDeclarationId{propertyDeclarationId}
|
||||||
|
, aliasTypeName{std::move(aliasTypeName)}
|
||||||
|
, aliasPropertyName{std::move(aliasPropertyName)}
|
||||||
|
, sourceId{sourceId}
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
PropertyDeclarationId propertyDeclarationId;
|
||||||
|
Storage::TypeName aliasTypeName;
|
||||||
|
Utils::SmallString aliasPropertyName;
|
||||||
|
SourceId sourceId;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PropertyDeclaration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PropertyDeclaration(PropertyDeclarationId propertyDeclarationId,
|
||||||
|
Storage::TypeName typeName,
|
||||||
|
SourceId sourceId)
|
||||||
|
: propertyDeclarationId{propertyDeclarationId}
|
||||||
|
, typeName{std::move(typeName)}
|
||||||
|
, sourceId{sourceId}
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
PropertyDeclarationId propertyDeclarationId;
|
||||||
|
Storage::TypeName typeName;
|
||||||
|
SourceId sourceId;
|
||||||
|
};
|
||||||
|
|
||||||
|
Storage::TypeName fetchTypeName(TypeNameId typeNameId)
|
||||||
|
{
|
||||||
|
Storage::TypeName typeName;
|
||||||
|
|
||||||
|
auto callback = [&](Utils::SmallStringView name, long long kind) {
|
||||||
|
typeName = createTypeName(kind, name);
|
||||||
|
return Sqlite::CallbackControl::Abort;
|
||||||
|
};
|
||||||
|
|
||||||
|
selectTypeNameStatement.readCallback(callback, &typeNameId);
|
||||||
|
|
||||||
|
return typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleAliasPropertyDeclarationsWithPropertyType(
|
||||||
|
TypeId typeId, std::vector<AliasPropertyDeclaration> &relinkableAliasPropertyDeclarations)
|
||||||
|
{
|
||||||
|
auto callback = [&](long long propertyDeclarationId,
|
||||||
|
long long propertyTypeNameId,
|
||||||
|
long long typeIdFromProperty,
|
||||||
|
long long aliasPropertyDeclarationId) {
|
||||||
|
auto sourceId = selectSourceIdForTypeIdStatement.template value<SourceId>(
|
||||||
|
typeIdFromProperty);
|
||||||
|
|
||||||
|
auto aliasPropertyName = selectPropertyNameStatement.template value<Utils::SmallString>(
|
||||||
|
aliasPropertyDeclarationId);
|
||||||
|
|
||||||
|
relinkableAliasPropertyDeclarations
|
||||||
|
.emplace_back(PropertyDeclarationId{propertyDeclarationId},
|
||||||
|
fetchTypeName(TypeNameId{propertyTypeNameId}),
|
||||||
|
std::move(aliasPropertyName),
|
||||||
|
sourceId);
|
||||||
|
|
||||||
|
updateAliasPropertyDeclarationToNullStatement.write(propertyDeclarationId);
|
||||||
|
|
||||||
|
return Sqlite::CallbackControl::Continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
selectAliasPropertiesDeclarationForPropertiesWithTypeIdStatement.readCallback(callback,
|
||||||
|
&typeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handlePropertyDeclarationWithPropertyType(
|
||||||
|
TypeId typeId, std::vector<PropertyDeclaration> &relinkablePropertyDeclarations)
|
||||||
|
{
|
||||||
|
auto callback = [&](long long propertyDeclarationId, long long propertyTypeNameId) {
|
||||||
|
auto sourceId = selectSourceIdForTypeIdStatement.template value<SourceId>(&typeId);
|
||||||
|
|
||||||
|
relinkablePropertyDeclarations.emplace_back(PropertyDeclarationId{propertyDeclarationId},
|
||||||
|
fetchTypeName(TypeNameId{propertyTypeNameId}),
|
||||||
|
sourceId);
|
||||||
|
|
||||||
|
return Sqlite::CallbackControl::Continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
updatesPropertyDeclarationPropertyTypeToNullStatement.readCallback(callback, &typeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteType(TypeId typeId,
|
||||||
|
std::vector<AliasPropertyDeclaration> &relinkableAliasPropertyDeclarations,
|
||||||
|
std::vector<PropertyDeclaration> &relinkablePropertyDeclarations)
|
||||||
|
{
|
||||||
|
handlePropertyDeclarationWithPropertyType(typeId, relinkablePropertyDeclarations);
|
||||||
|
handleAliasPropertyDeclarationsWithPropertyType(typeId, relinkableAliasPropertyDeclarations);
|
||||||
|
deleteTypeNamesByTypeIdStatement.write(&typeId);
|
||||||
deleteEnumerationDeclarationByTypeIdStatement.write(&typeId);
|
deleteEnumerationDeclarationByTypeIdStatement.write(&typeId);
|
||||||
deletePropertyDeclarationByTypeIdStatement.write(&typeId);
|
deletePropertyDeclarationByTypeIdStatement.write(&typeId);
|
||||||
deleteFunctionDeclarationByTypeIdStatement.write(&typeId);
|
deleteFunctionDeclarationByTypeIdStatement.write(&typeId);
|
||||||
@@ -427,8 +544,50 @@ private:
|
|||||||
deleteTypeStatement.write(&typeId);
|
deleteTypeStatement.write(&typeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void relinkAliasPropertyDeclaration(const std::vector<AliasPropertyDeclaration> &aliasPropertyDeclarations)
|
||||||
|
{
|
||||||
|
for (const AliasPropertyDeclaration &alias : aliasPropertyDeclarations) {
|
||||||
|
auto [typeId, aliasTypeNameId] = fetchTypeIdByNameUngarded(alias.aliasTypeName,
|
||||||
|
alias.sourceId);
|
||||||
|
|
||||||
|
auto [propertyTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeIdAndNameUngarded(
|
||||||
|
typeId, alias.aliasPropertyName);
|
||||||
|
|
||||||
|
updatePropertyDeclarationWithAliasStatement.write(&alias.propertyDeclarationId,
|
||||||
|
&propertyTypeId,
|
||||||
|
propertyTraits,
|
||||||
|
&aliasTypeNameId,
|
||||||
|
&aliasId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void relinkPropertyDeclaration(const std::vector<PropertyDeclaration> &relinkablePropertyDeclaration)
|
||||||
|
{
|
||||||
|
for (const PropertyDeclaration &property : relinkablePropertyDeclaration) {
|
||||||
|
auto [propertyTypeId, propertyTypeNameId] = fetchTypeIdByNameUngarded(property.typeName,
|
||||||
|
property.sourceId);
|
||||||
|
|
||||||
|
if (!propertyTypeId) {
|
||||||
|
auto hasPropertyDeclaration = selectPropertyDeclarationIdStatement
|
||||||
|
.template optionalValue<PropertyDeclarationId>(
|
||||||
|
&property.propertyDeclarationId);
|
||||||
|
if (hasPropertyDeclaration)
|
||||||
|
throw TypeNameDoesNotExists{};
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
updatePropertyDeclarationTypeStatement.write(&property.propertyDeclarationId,
|
||||||
|
&propertyTypeId,
|
||||||
|
&propertyTypeNameId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void deleteNotUpdatedTypes(const TypeIds &updatedTypeIds, const SourceIds &sourceIds)
|
void deleteNotUpdatedTypes(const TypeIds &updatedTypeIds, const SourceIds &sourceIds)
|
||||||
{
|
{
|
||||||
|
std::vector<AliasPropertyDeclaration> relinkableAliasPropertyDeclarations;
|
||||||
|
std::vector<PropertyDeclaration> relinkablePropertyDeclarations;
|
||||||
|
|
||||||
auto updatedTypeIdValues = Utils::transform<std::vector>(updatedTypeIds, [](TypeId typeId) {
|
auto updatedTypeIdValues = Utils::transform<std::vector>(updatedTypeIds, [](TypeId typeId) {
|
||||||
return &typeId;
|
return &typeId;
|
||||||
});
|
});
|
||||||
@@ -438,19 +597,27 @@ private:
|
|||||||
});
|
});
|
||||||
|
|
||||||
auto callback = [&](long long typeId) {
|
auto callback = [&](long long typeId) {
|
||||||
deleteType(TypeId{typeId});
|
deleteType(TypeId{typeId},
|
||||||
|
relinkableAliasPropertyDeclarations,
|
||||||
|
relinkablePropertyDeclarations);
|
||||||
return Sqlite::CallbackControl::Continue;
|
return Sqlite::CallbackControl::Continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
selectNotUpdatedTypesInSourcesStatement.readCallback(callback,
|
selectNotUpdatedTypesInSourcesStatement.readCallback(callback,
|
||||||
Utils::span(sourceIdValues),
|
Utils::span(sourceIdValues),
|
||||||
Utils::span(updatedTypeIdValues));
|
Utils::span(updatedTypeIdValues));
|
||||||
|
|
||||||
|
relinkPropertyDeclaration(relinkablePropertyDeclarations);
|
||||||
|
relinkAliasPropertyDeclaration(relinkableAliasPropertyDeclarations);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteTypesForImportId(ImportId importId)
|
void deleteTypesForImportId(ImportId importId)
|
||||||
{
|
{
|
||||||
|
std::vector<AliasPropertyDeclaration> aliasPropertyDeclarations;
|
||||||
|
std::vector<PropertyDeclaration> relinkablePropertyDeclarations;
|
||||||
|
|
||||||
auto callback = [&](long long typeId) {
|
auto callback = [&](long long typeId) {
|
||||||
deleteType(TypeId{typeId});
|
deleteType(TypeId{typeId}, aliasPropertyDeclarations, relinkablePropertyDeclarations);
|
||||||
return Sqlite::CallbackControl::Continue;
|
return Sqlite::CallbackControl::Continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -459,12 +626,23 @@ private:
|
|||||||
|
|
||||||
void upsertExportedType(ImportId importId, Utils::SmallStringView name, TypeId typeId)
|
void upsertExportedType(ImportId importId, Utils::SmallStringView name, TypeId typeId)
|
||||||
{
|
{
|
||||||
upsertExportedTypesStatement.write(&importId, name, &typeId);
|
upsertTypeNamesStatement.write(&importId,
|
||||||
|
name,
|
||||||
|
&typeId,
|
||||||
|
static_cast<long long>(Storage::TypeNameKind::Exported));
|
||||||
|
}
|
||||||
|
|
||||||
|
void upsertNativeType(ImportId importId, Utils::SmallStringView name, TypeId typeId)
|
||||||
|
{
|
||||||
|
upsertTypeNamesStatement.write(&importId,
|
||||||
|
name,
|
||||||
|
&typeId,
|
||||||
|
static_cast<long long>(Storage::TypeNameKind::Native));
|
||||||
}
|
}
|
||||||
|
|
||||||
void synchronizePropertyDeclarations(TypeId typeId,
|
void synchronizePropertyDeclarations(TypeId typeId,
|
||||||
Storage::PropertyDeclarations &propertyDeclarations,
|
Storage::PropertyDeclarations &propertyDeclarations,
|
||||||
ImportIds &importIds)
|
SourceId sourceId)
|
||||||
{
|
{
|
||||||
std::sort(propertyDeclarations.begin(),
|
std::sort(propertyDeclarations.begin(),
|
||||||
propertyDeclarations.end(),
|
propertyDeclarations.end(),
|
||||||
@@ -481,27 +659,60 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto insert = [&](const Storage::PropertyDeclaration &value) {
|
auto insert = [&](const Storage::PropertyDeclaration &value) {
|
||||||
auto propertyTypeId = fetchTypeIdByNameUngarded(value.typeName, importIds);
|
auto [propertyTypeId, propertyTypeNameId] = fetchTypeIdByNameUngarded(value.typeName,
|
||||||
|
sourceId);
|
||||||
|
|
||||||
insertPropertyDeclarationStatement.write(&typeId,
|
if (!propertyTypeId)
|
||||||
value.name,
|
throw TypeNameDoesNotExists{};
|
||||||
&propertyTypeId,
|
|
||||||
static_cast<int>(value.traits));
|
auto propertyDeclarationId = insertPropertyDeclarationStatement.template value<
|
||||||
|
PropertyDeclarationId>(&typeId,
|
||||||
|
value.name,
|
||||||
|
&propertyTypeId,
|
||||||
|
static_cast<int>(value.traits),
|
||||||
|
&propertyTypeNameId);
|
||||||
|
|
||||||
|
auto nextPropertyDeclarationId = selectPropertyDeclarationIdPrototypeChainDownStatement
|
||||||
|
.template value<PropertyDeclarationId>(&typeId,
|
||||||
|
value.name);
|
||||||
|
if (nextPropertyDeclarationId) {
|
||||||
|
updateAliasPropertyDeclarationStatement.write(&nextPropertyDeclarationId,
|
||||||
|
&propertyTypeId,
|
||||||
|
static_cast<int>(value.traits),
|
||||||
|
&propertyDeclarationId);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto update = [&](const Storage::PropertyDeclarationView &view,
|
auto update = [&](const Storage::PropertyDeclarationView &view,
|
||||||
const Storage::PropertyDeclaration &value) {
|
const Storage::PropertyDeclaration &value) {
|
||||||
auto propertyTypeId = fetchTypeIdByNameUngarded(value.typeName, importIds);
|
auto [propertyTypeId, propertyTypeNameId] = fetchTypeIdByNameUngarded(value.typeName,
|
||||||
|
sourceId);
|
||||||
|
|
||||||
if (view.traits == value.traits && propertyTypeId == view.typeId)
|
if (!propertyTypeId)
|
||||||
|
throw TypeNameDoesNotExists{};
|
||||||
|
|
||||||
|
if (view.traits == value.traits && propertyTypeId == view.typeId
|
||||||
|
&& propertyTypeNameId == view.typeNameId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
updatePropertyDeclarationStatement.write(&view.id,
|
updatePropertyDeclarationStatement.write(&view.id,
|
||||||
&propertyTypeId,
|
&propertyTypeId,
|
||||||
static_cast<int>(value.traits));
|
static_cast<int>(value.traits),
|
||||||
|
&propertyTypeNameId);
|
||||||
|
updatePropertyDeclarationWithAliasIdStatement.write(&view.id,
|
||||||
|
&propertyTypeId,
|
||||||
|
static_cast<int>(value.traits));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto remove = [&](const Storage::PropertyDeclarationView &view) {
|
auto remove = [&](const Storage::PropertyDeclarationView &view) {
|
||||||
|
auto nextPropertyDeclarationId = selectPropertyDeclarationIdPrototypeChainDownStatement
|
||||||
|
.template value<PropertyDeclarationId>(&typeId,
|
||||||
|
view.name);
|
||||||
|
if (nextPropertyDeclarationId) {
|
||||||
|
updateAliasPropertyDeclarationByAliasPropertyDeclarationIdStatement
|
||||||
|
.write(&nextPropertyDeclarationId, &view.id);
|
||||||
|
}
|
||||||
|
|
||||||
deletePropertyDeclarationStatement.write(&view.id);
|
deletePropertyDeclarationStatement.write(&view.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -541,7 +752,6 @@ private:
|
|||||||
{
|
{
|
||||||
auto &aliasDeclarations = type.aliasDeclarations;
|
auto &aliasDeclarations = type.aliasDeclarations;
|
||||||
TypeId typeId = type.typeId;
|
TypeId typeId = type.typeId;
|
||||||
ImportIds &importIds = type.importIds;
|
|
||||||
|
|
||||||
std::sort(aliasDeclarations.begin(), aliasDeclarations.end(), [](auto &&first, auto &&second) {
|
std::sort(aliasDeclarations.begin(), aliasDeclarations.end(), [](auto &&first, auto &&second) {
|
||||||
return Sqlite::compare(first.name, second.name) < 0;
|
return Sqlite::compare(first.name, second.name) < 0;
|
||||||
@@ -556,20 +766,31 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto insert = [&](const Storage::AliasPropertyDeclaration &value) {
|
auto insert = [&](const Storage::AliasPropertyDeclaration &value) {
|
||||||
auto [aliasTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeNameAndName(
|
auto [propertyTypeId, aliasTypeNameId] = fetchTypeIdByNameUngarded(value.aliasTypeName,
|
||||||
value.aliasTypeName, value.aliasPropertyName, importIds);
|
type.sourceId);
|
||||||
|
|
||||||
insertPropertyDeclarationWithAliasStatement.write(&typeId,
|
if (!propertyTypeId)
|
||||||
value.name,
|
throw TypeNameDoesNotExists{};
|
||||||
&aliasTypeId,
|
|
||||||
propertyTraits,
|
auto [aliasTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeIdAndNameUngarded(
|
||||||
&aliasId);
|
propertyTypeId, value.aliasPropertyName);
|
||||||
|
|
||||||
|
Utils::SmallStringView aliasTypeName = extractTypeName(value.aliasTypeName);
|
||||||
|
|
||||||
|
insertPropertyDeclarationWithAliasStatement.write(
|
||||||
|
&typeId, value.name, &aliasTypeId, propertyTraits, &aliasTypeNameId, &aliasId);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto update = [&](const Storage::AliasPropertyDeclarationView &view,
|
auto update = [&](const Storage::AliasPropertyDeclarationView &view,
|
||||||
const Storage::AliasPropertyDeclaration &value) {
|
const Storage::AliasPropertyDeclaration &value) {
|
||||||
auto [aliasTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeNameAndName(
|
auto [propertyTypeId, aliasTypeNameId] = fetchTypeIdByNameUngarded(value.aliasTypeName,
|
||||||
value.aliasTypeName, value.aliasPropertyName, importIds);
|
type.sourceId);
|
||||||
|
|
||||||
|
if (!propertyTypeId)
|
||||||
|
throw TypeNameDoesNotExists{};
|
||||||
|
|
||||||
|
auto [aliasTypeId, aliasId, propertyTraits] = fetchPropertyDeclarationByTypeIdAndNameUngarded(
|
||||||
|
propertyTypeId, value.aliasPropertyName);
|
||||||
|
|
||||||
if (view.aliasId == aliasId)
|
if (view.aliasId == aliasId)
|
||||||
return;
|
return;
|
||||||
@@ -577,6 +798,7 @@ private:
|
|||||||
updatePropertyDeclarationWithAliasStatement.write(&view.id,
|
updatePropertyDeclarationWithAliasStatement.write(&view.id,
|
||||||
&aliasTypeId,
|
&aliasTypeId,
|
||||||
propertyTraits,
|
propertyTraits,
|
||||||
|
&aliasTypeNameId,
|
||||||
&aliasId);
|
&aliasId);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -585,6 +807,27 @@ private:
|
|||||||
Sqlite::insertUpdateDelete(range, aliasDeclarations, compareKey, insert, update, remove);
|
Sqlite::insertUpdateDelete(range, aliasDeclarations, compareKey, insert, update, remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void synchronizeDocumentImports(SourceId sourceId, ImportIds &importIds)
|
||||||
|
{
|
||||||
|
std::sort(importIds.begin(), importIds.end());
|
||||||
|
|
||||||
|
auto range = selectImportIdsForSourceIdStatement.template range<ImportId>(&sourceId);
|
||||||
|
|
||||||
|
auto compareKey = [](ImportId first, ImportId second) { return first.id - second.id; };
|
||||||
|
|
||||||
|
auto insert = [&](ImportId importId) {
|
||||||
|
insertImportIdForSourceIdStatement.write(&sourceId, &importId);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto update = [](ImportId, ImportId) {};
|
||||||
|
|
||||||
|
auto remove = [&](ImportId importId) {
|
||||||
|
deleteImportIdForSourceIdStatement.write(&sourceId, &importId);
|
||||||
|
};
|
||||||
|
|
||||||
|
Sqlite::insertUpdateDelete(range, importIds, compareKey, insert, update, remove);
|
||||||
|
}
|
||||||
|
|
||||||
Utils::PathString createJson(const Storage::ParameterDeclarations ¶meters)
|
Utils::PathString createJson(const Storage::ParameterDeclarations ¶meters)
|
||||||
{
|
{
|
||||||
Utils::PathString json;
|
Utils::PathString json;
|
||||||
@@ -762,6 +1005,8 @@ private:
|
|||||||
static_cast<int>(type.accessSemantics),
|
static_cast<int>(type.accessSemantics),
|
||||||
&type.sourceId);
|
&type.sourceId);
|
||||||
|
|
||||||
|
upsertNativeType(type.importId, type.typeName, type.typeId);
|
||||||
|
|
||||||
for (const auto &exportedType : type.exportedTypes)
|
for (const auto &exportedType : type.exportedTypes)
|
||||||
upsertExportedType(type.importId, exportedType.name, type.typeId);
|
upsertExportedType(type.importId, exportedType.name, type.typeId);
|
||||||
|
|
||||||
@@ -772,69 +1017,114 @@ private:
|
|||||||
{
|
{
|
||||||
auto typeId = type.typeId;
|
auto typeId = type.typeId;
|
||||||
|
|
||||||
auto prototypeId = fetchTypeIdByNameUngarded(type.prototype, type.importIds);
|
synchronizePropertyDeclarations(typeId, type.propertyDeclarations, type.sourceId);
|
||||||
|
|
||||||
updatePrototypeStatement.write(&typeId, &prototypeId);
|
|
||||||
|
|
||||||
synchronizePropertyDeclarations(typeId, type.propertyDeclarations, type.importIds);
|
|
||||||
synchronizeFunctionDeclarations(typeId, type.functionDeclarations);
|
synchronizeFunctionDeclarations(typeId, type.functionDeclarations);
|
||||||
synchronizeSignalDeclarations(typeId, type.signalDeclarations);
|
synchronizeSignalDeclarations(typeId, type.signalDeclarations);
|
||||||
synchronizeEnumerationDeclarations(typeId, type.enumerationDeclarations);
|
synchronizeEnumerationDeclarations(typeId, type.enumerationDeclarations);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeId fetchTypeIdByNameUngarded(const Storage::TypeName &name, ImportIds &importIds)
|
void syncPrototypes(Storage::Type &type)
|
||||||
{
|
{
|
||||||
if (Utils::visit([](auto &&type) -> bool { return type.name.isEmpty(); }, name))
|
if (Utils::visit([](auto &&type) -> bool { return type.name.isEmpty(); }, type.prototype)) {
|
||||||
return TypeId{};
|
updatePrototypeStatement.write(&type.typeId, Sqlite::NullValue{});
|
||||||
|
} else {
|
||||||
|
auto [prototypeId, prototypeTypeNameId] = fetchTypeIdByNameUngarded(type.prototype,
|
||||||
|
type.sourceId);
|
||||||
|
|
||||||
|
if (!prototypeId)
|
||||||
|
throw TypeNameDoesNotExists{};
|
||||||
|
|
||||||
|
updatePrototypeStatement.write(&type.typeId, &prototypeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::SmallStringView extractTypeName(const Storage::TypeName &name) const
|
||||||
|
{
|
||||||
|
return Utils::visit([](auto &&typeName) -> Utils::SmallStringView { return typeName.name; },
|
||||||
|
name);
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::TypeName createTypeName(long long typeIndex, Utils::SmallStringView name) const
|
||||||
|
{
|
||||||
|
switch (typeIndex) {
|
||||||
|
case 0:
|
||||||
|
return Utils::variant_alternative_t<0, Storage::TypeName>(name);
|
||||||
|
case 1:
|
||||||
|
return Utils::variant_alternative_t<1, Storage::TypeName>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
class TypeIdAndTypeNameId
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TypeIdAndTypeNameId() = default;
|
||||||
|
TypeIdAndTypeNameId(long long typeId, long long typeNameId)
|
||||||
|
: typeId{typeId}
|
||||||
|
, typeNameId{typeNameId}
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
TypeId typeId;
|
||||||
|
TypeNameId typeNameId;
|
||||||
|
};
|
||||||
|
|
||||||
|
TypeIdAndTypeNameId fetchTypeIdByNameUngarded(const Storage::TypeName &name, SourceId sourceId)
|
||||||
|
{
|
||||||
struct Inspect
|
struct Inspect
|
||||||
{
|
{
|
||||||
TypeId operator()(const Storage::NativeType &nativeType)
|
auto operator()(const Storage::NativeType &nativeType)
|
||||||
{
|
{
|
||||||
return storage.selectTypeIdByImportIdsAndNameStatement
|
return storage.selectTypeIdByImportIdsFromSourceIdAndNameStatement
|
||||||
.template value<TypeId>(static_cast<void *>(importIds.data()),
|
.template value<TypeIdAndTypeNameId>(&sourceId, nativeType.name);
|
||||||
static_cast<long long>(importIds.size()),
|
|
||||||
nativeType.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeId operator()(const Storage::ExportedType &exportedType)
|
auto operator()(const Storage::ExportedType &exportedType)
|
||||||
{
|
{
|
||||||
return storage.selectTypeIdByImportIdsAndExportedNameStatement
|
return storage.selectTypeIdByImportIdsFromSourceIdAndExportedNameStatement
|
||||||
.template value<TypeId>(static_cast<void *>(importIds.data()),
|
.template value<TypeIdAndTypeNameId>(&sourceId, exportedType.name);
|
||||||
static_cast<long long>(importIds.size()),
|
|
||||||
exportedType.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeId operator()(const Storage::ExplicitExportedType &exportedType)
|
auto operator()(const Storage::ExplicitExportedType &exportedType)
|
||||||
{
|
{
|
||||||
return storage.selectTypeIdByImportIdAndExportedNameStatement
|
return storage.selectTypeIdByImportIdAndExportedNameStatement
|
||||||
.template value<TypeId>(&exportedType.importId, exportedType.name);
|
.template value<TypeIdAndTypeNameId>(&exportedType.importId, exportedType.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectStorage &storage;
|
ProjectStorage &storage;
|
||||||
ImportIds &importIds;
|
SourceId sourceId;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto typeId = Utils::visit(Inspect{*this, importIds}, name);
|
return Utils::visit(Inspect{*this, sourceId}, name);
|
||||||
|
|
||||||
if (typeId)
|
|
||||||
return typeId;
|
|
||||||
|
|
||||||
throw TypeNameDoesNotExists{};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
using PropertyDeclarationViewTuple = std::tuple<TypeId, PropertyDeclarationId, long long>;
|
class FetchPropertyDeclarationResult
|
||||||
|
|
||||||
PropertyDeclarationViewTuple fetchPropertyDeclarationByTypeNameAndName(
|
|
||||||
const Storage::TypeName &typeName, Utils::SmallStringView name, ImportIds &importIds)
|
|
||||||
{
|
{
|
||||||
TypeId typeId = fetchTypeIdByNameUngarded(typeName, importIds);
|
public:
|
||||||
|
FetchPropertyDeclarationResult(long long propertyTypeId,
|
||||||
|
long long propertyDeclarationId,
|
||||||
|
long long propertyTraits)
|
||||||
|
: propertyTypeId{propertyTypeId}
|
||||||
|
, propertyDeclarationId{propertyDeclarationId}
|
||||||
|
, propertyTraits{propertyTraits}
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
TypeId propertyTypeId;
|
||||||
|
PropertyDeclarationId propertyDeclarationId;
|
||||||
|
long long propertyTraits;
|
||||||
|
};
|
||||||
|
|
||||||
|
FetchPropertyDeclarationResult fetchPropertyDeclarationByTypeIdAndNameUngarded(
|
||||||
|
TypeId typeId, Utils::SmallStringView name)
|
||||||
|
{
|
||||||
auto propertyDeclaration = selectPropertyDeclarationByTypeIdAndNameStatement
|
auto propertyDeclaration = selectPropertyDeclarationByTypeIdAndNameStatement
|
||||||
.template value<PropertyDeclarationViewTuple>(&typeId, name);
|
.template optionalValue<FetchPropertyDeclarationResult>(&typeId,
|
||||||
|
name);
|
||||||
|
|
||||||
if (auto id = std::get<PropertyDeclarationId>(propertyDeclaration); id)
|
if (propertyDeclaration)
|
||||||
return propertyDeclaration;
|
return *propertyDeclaration;
|
||||||
|
|
||||||
throw PropertyNameDoesNotExists{};
|
throw PropertyNameDoesNotExists{};
|
||||||
}
|
}
|
||||||
@@ -947,10 +1237,11 @@ private:
|
|||||||
createSourceContextsTable(database);
|
createSourceContextsTable(database);
|
||||||
createSourcesTable(database);
|
createSourcesTable(database);
|
||||||
createTypesAndePropertyDeclarationsTables(database);
|
createTypesAndePropertyDeclarationsTables(database);
|
||||||
createExportedTypesTable(database);
|
createTypeNamesTable(database);
|
||||||
createEnumerationsTable(database);
|
createEnumerationsTable(database);
|
||||||
createFunctionsTable(database);
|
createFunctionsTable(database);
|
||||||
createSignalsTable(database);
|
createSignalsTable(database);
|
||||||
|
createSourceImportsTable(database);
|
||||||
|
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
|
||||||
@@ -1024,6 +1315,7 @@ private:
|
|||||||
Sqlite::ForeignKeyAction::NoAction,
|
Sqlite::ForeignKeyAction::NoAction,
|
||||||
Sqlite::ForeignKeyAction::Restrict);
|
Sqlite::ForeignKeyAction::Restrict);
|
||||||
propertyDeclarationTable.addColumn("propertyTraits");
|
propertyDeclarationTable.addColumn("propertyTraits");
|
||||||
|
propertyDeclarationTable.addColumn("propertyTypeNameId");
|
||||||
auto &aliasPropertyDeclarationIdColumn = propertyDeclarationTable.addForeignKeyColumn(
|
auto &aliasPropertyDeclarationIdColumn = propertyDeclarationTable.addForeignKeyColumn(
|
||||||
"aliasPropertyDeclarationId",
|
"aliasPropertyDeclarationId",
|
||||||
propertyDeclarationTable,
|
propertyDeclarationTable,
|
||||||
@@ -1038,17 +1330,18 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void createExportedTypesTable(Database &database)
|
void createTypeNamesTable(Database &database)
|
||||||
{
|
{
|
||||||
Sqlite::Table table;
|
Sqlite::Table table;
|
||||||
table.setUseIfNotExists(true);
|
table.setUseIfNotExists(true);
|
||||||
table.setUseWithoutRowId(true);
|
table.setName("typeNames");
|
||||||
table.setName("exportedTypes");
|
table.addColumn("typeNameId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}});
|
||||||
auto &importIdColumn = table.addColumn("importId");
|
auto &importIdColumn = table.addColumn("importId");
|
||||||
auto &nameColumn = table.addColumn("name");
|
auto &nameColumn = table.addColumn("name");
|
||||||
|
auto &kindColumn = table.addColumn("kind");
|
||||||
table.addColumn("typeId");
|
table.addColumn("typeId");
|
||||||
|
|
||||||
table.addPrimaryKeyContraint({importIdColumn, nameColumn});
|
table.addUniqueIndex({importIdColumn, nameColumn, kindColumn});
|
||||||
|
|
||||||
table.initialize(database);
|
table.initialize(database);
|
||||||
}
|
}
|
||||||
@@ -1131,6 +1424,20 @@ private:
|
|||||||
|
|
||||||
table.initialize(database);
|
table.initialize(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createSourceImportsTable(Database &database)
|
||||||
|
{
|
||||||
|
Sqlite::Table table;
|
||||||
|
table.setUseIfNotExists(true);
|
||||||
|
table.setUseWithoutRowId(true);
|
||||||
|
table.setName("sourceImports");
|
||||||
|
auto &sourceIdColumn = table.addColumn("sourceId");
|
||||||
|
auto &importIdColumn = table.addColumn("importId");
|
||||||
|
|
||||||
|
table.addPrimaryKeyContraint({sourceIdColumn, importIdColumn});
|
||||||
|
|
||||||
|
table.initialize(database);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -1142,10 +1449,10 @@ public:
|
|||||||
"CONFLICT DO UPDATE SET prototypeId=excluded.prototypeId, "
|
"CONFLICT DO UPDATE SET prototypeId=excluded.prototypeId, "
|
||||||
"accessSemantics=excluded.accessSemantics, sourceId=excluded.sourceId RETURNING typeId",
|
"accessSemantics=excluded.accessSemantics, sourceId=excluded.sourceId RETURNING typeId",
|
||||||
database};
|
database};
|
||||||
WriteStatement updatePrototypeStatement{
|
WriteStatement updatePrototypeStatement{"UPDATE types SET prototypeId=?2 WHERE typeId=?1",
|
||||||
"UPDATE types SET prototypeId=nullif(?2, -1) WHERE typeId=?1", database};
|
database};
|
||||||
mutable ReadStatement<1> selectTypeIdByExportedNameStatement{
|
mutable ReadStatement<1> selectTypeIdByExportedNameStatement{
|
||||||
"SELECT typeId FROM exportedTypes WHERE name=?1", database};
|
"SELECT typeId FROM typeNames WHERE name=?1 AND kind=1", database};
|
||||||
mutable ReadStatement<1> selectPrototypeIdStatement{
|
mutable ReadStatement<1> selectPrototypeIdStatement{
|
||||||
"WITH RECURSIVE "
|
"WITH RECURSIVE "
|
||||||
" typeSelection(typeId) AS ("
|
" typeSelection(typeId) AS ("
|
||||||
@@ -1156,33 +1463,36 @@ public:
|
|||||||
database};
|
database};
|
||||||
mutable ReadStatement<1> selectPropertyDeclarationIdByTypeIdAndNameStatement{
|
mutable ReadStatement<1> selectPropertyDeclarationIdByTypeIdAndNameStatement{
|
||||||
"WITH RECURSIVE "
|
"WITH RECURSIVE "
|
||||||
" typeSelection(typeId) AS ("
|
" typeSelection(typeId, level) AS ("
|
||||||
" VALUES(?1) "
|
" VALUES(?1, 0) "
|
||||||
" UNION ALL "
|
" UNION ALL "
|
||||||
" SELECT prototypeId FROM types JOIN typeSelection USING(typeId)) "
|
" SELECT prototypeId, typeSelection.level+1 FROM types JOIN typeSelection "
|
||||||
|
" USING(typeId)) "
|
||||||
"SELECT propertyDeclarationId FROM propertyDeclarations JOIN typeSelection USING(typeId) "
|
"SELECT propertyDeclarationId FROM propertyDeclarations JOIN typeSelection USING(typeId) "
|
||||||
" WHERE name=?2 LIMIT 1",
|
" WHERE name=?2 ORDER BY level LIMIT 1",
|
||||||
database};
|
database};
|
||||||
mutable ReadStatement<3> selectPropertyDeclarationByTypeIdAndNameStatement{
|
mutable ReadStatement<3> selectPropertyDeclarationByTypeIdAndNameStatement{
|
||||||
"WITH RECURSIVE "
|
"WITH RECURSIVE "
|
||||||
" typeSelection(typeId) AS ("
|
" typeSelection(typeId, level) AS ("
|
||||||
" VALUES(?1) "
|
" VALUES(?1, 0) "
|
||||||
" UNION ALL "
|
" UNION ALL "
|
||||||
" SELECT prototypeId FROM types JOIN typeSelection USING(typeId)) "
|
" SELECT prototypeId, typeSelection.level+1 FROM types JOIN typeSelection "
|
||||||
"SELECT propertyTypeId, propertyDeclarationId, propertyTraits FROM propertyDeclarations "
|
" USING(typeId)) "
|
||||||
" JOIN typeSelection USING(typeId) "
|
"SELECT propertyTypeId, propertyDeclarationId, propertyTraits "
|
||||||
" WHERE name=?2 LIMIT 1",
|
" FROM propertyDeclarations JOIN typeSelection USING(typeId) "
|
||||||
|
" WHERE name=?2 ORDER BY level LIMIT 1",
|
||||||
database};
|
database};
|
||||||
WriteStatement upsertExportedTypesStatement{"INSERT INTO exportedTypes(importId, name, typeId) "
|
WriteStatement upsertTypeNamesStatement{"INSERT INTO typeNames(importId, name, typeId, kind) "
|
||||||
"VALUES(?1, ?2, ?3) ON CONFLICT DO NOTHING",
|
"VALUES(?1, ?2, ?3, ?4) ON CONFLICT DO NOTHING",
|
||||||
database};
|
database};
|
||||||
mutable ReadStatement<1> selectPrototypeIdsStatement{
|
mutable ReadStatement<1> selectPrototypeIdsStatement{
|
||||||
"WITH RECURSIVE "
|
"WITH RECURSIVE "
|
||||||
" typeSelection(typeId) AS ("
|
" typeSelection(typeId, level) AS ("
|
||||||
" VALUES(?1) "
|
" VALUES(?1, 0) "
|
||||||
" UNION ALL "
|
" UNION ALL "
|
||||||
" SELECT prototypeId FROM types JOIN typeSelection USING(typeId)) "
|
" SELECT prototypeId, typeSelection.level+1 FROM types JOIN typeSelection "
|
||||||
"SELECT typeId FROM typeSelection",
|
" USING(typeId)) "
|
||||||
|
"SELECT typeId FROM typeSelection ORDER BY level DESC",
|
||||||
database};
|
database};
|
||||||
mutable ReadStatement<1> selectSourceContextIdFromSourceContextsBySourceContextPathStatement{
|
mutable ReadStatement<1> selectSourceContextIdFromSourceContextsBySourceContextPathStatement{
|
||||||
"SELECT sourceContextId FROM sourceContexts WHERE sourceContextPath = ?", database};
|
"SELECT sourceContextId FROM sourceContexts WHERE sourceContextPath = ?", database};
|
||||||
@@ -1204,12 +1514,16 @@ public:
|
|||||||
"SELECT sourceName, sourceContextId, sourceId FROM sources", database};
|
"SELECT sourceName, sourceContextId, sourceId FROM sources", database};
|
||||||
mutable ReadStatement<1> selectTypeIdByImportIdsAndNameStatement{
|
mutable ReadStatement<1> selectTypeIdByImportIdsAndNameStatement{
|
||||||
"SELECT typeId FROM types WHERE importId IN carray(?1, ?2, 'int64') AND name=?3", database};
|
"SELECT typeId FROM types WHERE importId IN carray(?1, ?2, 'int64') AND name=?3", database};
|
||||||
|
mutable ReadStatement<2> selectTypeIdByImportIdsFromSourceIdAndNameStatement{
|
||||||
|
"SELECT typeId, typeNameId FROM typeNames JOIN sourceImports USING(importId) WHERE name=?2 "
|
||||||
|
"AND kind=0 AND sourceImports.sourceId=?1",
|
||||||
|
database};
|
||||||
mutable ReadStatement<5> selectTypeByTypeIdStatement{
|
mutable ReadStatement<5> selectTypeByTypeIdStatement{
|
||||||
"SELECT importId, name, (SELECT name FROM types WHERE typeId=outerTypes.prototypeId), "
|
"SELECT importId, name, (SELECT name FROM types WHERE typeId=outerTypes.prototypeId), "
|
||||||
"accessSemantics, ifnull(sourceId, -1) FROM types AS outerTypes WHERE typeId=?",
|
"accessSemantics, ifnull(sourceId, -1) FROM types AS outerTypes WHERE typeId=?",
|
||||||
database};
|
database};
|
||||||
mutable ReadStatement<1> selectExportedTypesByTypeIdStatement{
|
mutable ReadStatement<1> selectExportedTypesByTypeIdStatement{
|
||||||
"SELECT name FROM exportedTypes WHERE typeId=?", database};
|
"SELECT name FROM typeNames WHERE typeId=? AND kind=1", database};
|
||||||
mutable ReadStatement<6> selectTypesStatement{
|
mutable ReadStatement<6> selectTypesStatement{
|
||||||
"SELECT importId, name, typeId, (SELECT name FROM types WHERE "
|
"SELECT importId, name, typeId, (SELECT name FROM types WHERE "
|
||||||
"typeId=outerTypes.prototypeId), accessSemantics, ifnull(sourceId, -1) FROM types AS "
|
"typeId=outerTypes.prototypeId), accessSemantics, ifnull(sourceId, -1) FROM types AS "
|
||||||
@@ -1218,8 +1532,7 @@ public:
|
|||||||
ReadStatement<1> selectNotUpdatedTypesInSourcesStatement{
|
ReadStatement<1> selectNotUpdatedTypesInSourcesStatement{
|
||||||
"SELECT typeId FROM types WHERE (sourceId IN carray(?1) AND typeId NOT IN carray(?2))",
|
"SELECT typeId FROM types WHERE (sourceId IN carray(?1) AND typeId NOT IN carray(?2))",
|
||||||
database};
|
database};
|
||||||
WriteStatement deleteExportTypesByTypeIdStatement{"DELETE FROM exportedTypes WHERE typeId=?",
|
WriteStatement deleteTypeNamesByTypeIdStatement{"DELETE FROM typeNames WHERE typeId=?", database};
|
||||||
database};
|
|
||||||
WriteStatement deleteEnumerationDeclarationByTypeIdStatement{
|
WriteStatement deleteEnumerationDeclarationByTypeIdStatement{
|
||||||
"DELETE FROM enumerationDeclarations WHERE typeId=?", database};
|
"DELETE FROM enumerationDeclarations WHERE typeId=?", database};
|
||||||
WriteStatement deletePropertyDeclarationByTypeIdStatement{
|
WriteStatement deletePropertyDeclarationByTypeIdStatement{
|
||||||
@@ -1233,18 +1546,23 @@ public:
|
|||||||
"SELECT name, (SELECT name FROM types WHERE typeId=propertyDeclarations.propertyTypeId),"
|
"SELECT name, (SELECT name FROM types WHERE typeId=propertyDeclarations.propertyTypeId),"
|
||||||
"propertyTraits FROM propertyDeclarations WHERE typeId=?",
|
"propertyTraits FROM propertyDeclarations WHERE typeId=?",
|
||||||
database};
|
database};
|
||||||
ReadStatement<4> selectPropertyDeclarationsForTypeIdStatement{
|
ReadStatement<5> selectPropertyDeclarationsForTypeIdStatement{
|
||||||
"SELECT name, propertyTraits, propertyTypeId, propertyDeclarationId FROM "
|
"SELECT name, propertyTraits, propertyTypeId, propertyTypeNameId, propertyDeclarationId "
|
||||||
"propertyDeclarations WHERE typeId=? AND aliasPropertyDeclarationId IS NULL ORDER BY "
|
"FROM propertyDeclarations WHERE typeId=? AND aliasPropertyDeclarationId IS NULL ORDER BY "
|
||||||
"name",
|
"name",
|
||||||
database};
|
database};
|
||||||
WriteStatement insertPropertyDeclarationStatement{
|
ReadWriteStatement<1> insertPropertyDeclarationStatement{
|
||||||
"INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits) "
|
"INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits, "
|
||||||
"VALUES(?1, ?2, ?3, ?4)",
|
"propertyTypeNameId, aliasPropertyDeclarationId) VALUES(?1, ?2, ?3, ?4, ?5, NULL) "
|
||||||
|
"RETURNING propertyDeclarationId",
|
||||||
database};
|
database};
|
||||||
WriteStatement updatePropertyDeclarationStatement{
|
WriteStatement updatePropertyDeclarationStatement{
|
||||||
|
"UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3, "
|
||||||
|
"propertyTypeNameId=?4 WHERE propertyDeclarationId=?1",
|
||||||
|
database};
|
||||||
|
WriteStatement updatePropertyDeclarationWithAliasIdStatement{
|
||||||
"UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3 WHERE "
|
"UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3 WHERE "
|
||||||
"propertyDeclarationId=?1 OR aliasPropertyDeclarationId=?1",
|
"aliasPropertyDeclarationId=?1",
|
||||||
database};
|
database};
|
||||||
WriteStatement deletePropertyDeclarationStatement{
|
WriteStatement deletePropertyDeclarationStatement{
|
||||||
"DELETE FROM propertyDeclarations WHERE propertyDeclarationId=?", database};
|
"DELETE FROM propertyDeclarations WHERE propertyDeclarationId=?", database};
|
||||||
@@ -1252,13 +1570,14 @@ public:
|
|||||||
"SELECT name, propertyDeclarationId, aliasPropertyDeclarationId FROM propertyDeclarations "
|
"SELECT name, propertyDeclarationId, aliasPropertyDeclarationId FROM propertyDeclarations "
|
||||||
"WHERE typeId=? AND aliasPropertyDeclarationId IS NOT NULL ORDER BY name",
|
"WHERE typeId=? AND aliasPropertyDeclarationId IS NOT NULL ORDER BY name",
|
||||||
database};
|
database};
|
||||||
WriteStatement insertPropertyDeclarationWithAliasStatement{
|
|
||||||
"INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits, "
|
|
||||||
"aliasPropertyDeclarationId) VALUES(?1, ?2, ?3, ?4, ?5) ",
|
|
||||||
database};
|
|
||||||
WriteStatement updatePropertyDeclarationWithAliasStatement{
|
WriteStatement updatePropertyDeclarationWithAliasStatement{
|
||||||
"UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3, "
|
"UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3, "
|
||||||
"aliasPropertyDeclarationId=?4 WHERE propertyDeclarationId=?1",
|
"propertyTypeNameId=?4, aliasPropertyDeclarationId=?5 WHERE propertyDeclarationId=?1",
|
||||||
|
database};
|
||||||
|
WriteStatement insertPropertyDeclarationWithAliasStatement{
|
||||||
|
"INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits, "
|
||||||
|
"propertyTypeNameId, aliasPropertyDeclarationId) "
|
||||||
|
"VALUES(?1, ?2, ?3, ?4, ?5, ?6)",
|
||||||
database};
|
database};
|
||||||
mutable ReadStatement<4> selectFunctionDeclarationsForTypeIdStatement{
|
mutable ReadStatement<4> selectFunctionDeclarationsForTypeIdStatement{
|
||||||
"SELECT name, returnTypeName, signature, functionDeclarationId FROM "
|
"SELECT name, returnTypeName, signature, functionDeclarationId FROM "
|
||||||
@@ -1351,10 +1670,15 @@ public:
|
|||||||
mutable ReadStatement<1> selectTypeIdByImportIdAndNameStatement{
|
mutable ReadStatement<1> selectTypeIdByImportIdAndNameStatement{
|
||||||
"SELECT typeId FROM types WHERE importId=?1 and name=?2", database};
|
"SELECT typeId FROM types WHERE importId=?1 and name=?2", database};
|
||||||
mutable ReadStatement<1> selectTypeIdByImportIdsAndExportedNameStatement{
|
mutable ReadStatement<1> selectTypeIdByImportIdsAndExportedNameStatement{
|
||||||
"SELECT typeId FROM exportedTypes WHERE importId IN carray(?1, ?2, 'int64') AND name=?3",
|
"SELECT typeId FROM typeNames WHERE importId IN carray(?1, ?2, 'int64') AND name=?3 AND "
|
||||||
|
"kind=1",
|
||||||
database};
|
database};
|
||||||
mutable ReadStatement<1> selectTypeIdByImportIdAndExportedNameStatement{
|
mutable ReadStatement<2> selectTypeIdByImportIdsFromSourceIdAndExportedNameStatement{
|
||||||
"SELECT typeId FROM exportedTypes WHERE importId=?1 AND name=?2", database};
|
"SELECT typeId, typeNameId FROM typeNames JOIN sourceImports USING(importId) WHERE name=?2 "
|
||||||
|
"AND kind=1 AND sourceImports.sourceId=?1",
|
||||||
|
database};
|
||||||
|
mutable ReadStatement<2> selectTypeIdByImportIdAndExportedNameStatement{
|
||||||
|
"SELECT typeId, typeNameId FROM typeNames WHERE importId=?1 AND name=?2 AND kind=1", database};
|
||||||
mutable ReadStatement<1> fetchImportDependencyIdsStatement{
|
mutable ReadStatement<1> fetchImportDependencyIdsStatement{
|
||||||
"WITH RECURSIVE "
|
"WITH RECURSIVE "
|
||||||
" importIds(importId) AS ("
|
" importIds(importId) AS ("
|
||||||
@@ -1363,6 +1687,59 @@ public:
|
|||||||
" SELECT parentImportId FROM importDependencies JOIN importIds USING(importId)) "
|
" SELECT parentImportId FROM importDependencies JOIN importIds USING(importId)) "
|
||||||
"SELECT importId FROM importIds",
|
"SELECT importId FROM importIds",
|
||||||
database};
|
database};
|
||||||
|
mutable ReadStatement<1> selectImportIdsForSourceIdStatement{
|
||||||
|
"SELECT importId FROM sourceImports WHERE sourceId=? ORDER BY importId", database};
|
||||||
|
WriteStatement insertImportIdForSourceIdStatement{
|
||||||
|
"INSERT INTO sourceImports(sourceId, importId) VALUES (?1, ?2)", database};
|
||||||
|
WriteStatement deleteImportIdForSourceIdStatement{
|
||||||
|
"DELETE FROM sourceImports WHERE sourceId=?1 AND importId=?2", database};
|
||||||
|
ReadStatement<1> selectPropertyDeclarationIdPrototypeChainDownStatement{
|
||||||
|
"WITH RECURSIVE "
|
||||||
|
" typeSelection(typeId, level) AS ("
|
||||||
|
" SELECT prototypeId, 0 FROM types WHERE typeId=?1 AND prototypeId IS NOT NULL"
|
||||||
|
" UNION ALL "
|
||||||
|
" SELECT prototypeId, typeSelection.level+1 FROM types JOIN typeSelection "
|
||||||
|
" USING(typeId) WHERE prototypeId IS NOT NULL)"
|
||||||
|
"SELECT propertyDeclarationId FROM typeSelection JOIN propertyDeclarations "
|
||||||
|
" USING(typeId) WHERE name=?2 ORDER BY level LIMIT 1",
|
||||||
|
database};
|
||||||
|
WriteStatement updateAliasPropertyDeclarationStatement{
|
||||||
|
"UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3, "
|
||||||
|
"aliasPropertyDeclarationId=?4 WHERE aliasPropertyDeclarationId=?1",
|
||||||
|
database};
|
||||||
|
WriteStatement updateAliasPropertyDeclarationByAliasPropertyDeclarationIdStatement{
|
||||||
|
"UPDATE propertyDeclarations SET propertyTypeId=new.propertyTypeId, "
|
||||||
|
"propertyTraits=new.propertyTraits, aliasPropertyDeclarationId=?1 FROM (SELECT "
|
||||||
|
"propertyTypeId, propertyTraits FROM propertyDeclarations WHERE propertyDeclarationId=?1) "
|
||||||
|
"AS new WHERE aliasPropertyDeclarationId=?2",
|
||||||
|
database};
|
||||||
|
WriteStatement updateAliasPropertyDeclarationToNullStatement{
|
||||||
|
"UPDATE propertyDeclarations SET aliasPropertyDeclarationId=NULL, propertyTypeId=NULL, "
|
||||||
|
"propertyTraits=NULL WHERE propertyDeclarationId=?",
|
||||||
|
database};
|
||||||
|
ReadStatement<4> selectAliasPropertiesDeclarationForPropertiesWithTypeIdStatement{
|
||||||
|
"SELECT alias.propertyDeclarationId, alias.propertyTypeNameId, alias.typeId, "
|
||||||
|
"target.propertyDeclarationId FROM propertyDeclarations AS alias JOIN propertyDeclarations "
|
||||||
|
"AS target ON alias.aliasPropertyDeclarationId=target.propertyDeclarationId WHERE "
|
||||||
|
"alias.propertyTypeId=?1",
|
||||||
|
database};
|
||||||
|
ReadWriteStatement<2> updatesPropertyDeclarationPropertyTypeToNullStatement{
|
||||||
|
"UPDATE propertyDeclarations SET propertyTypeId=NULL WHERE propertyTypeId=?1 AND "
|
||||||
|
"aliasPropertyDeclarationId IS NULL RETURNING propertyDeclarationId, propertyTypeNameId",
|
||||||
|
database};
|
||||||
|
ReadStatement<1> selectSourceIdForTypeIdStatement{"SELECT sourceId FROM types WHERE typeId=?",
|
||||||
|
database};
|
||||||
|
ReadStatement<2> selectTypeNameStatement{"SELECT name, kind FROM typeNames WHERE typeNameId=?",
|
||||||
|
database};
|
||||||
|
ReadStatement<1> selectPropertyNameStatement{
|
||||||
|
"SELECT name FROM propertyDeclarations WHERE propertyDeclarationId=?", database};
|
||||||
|
WriteStatement updatePropertyDeclarationTypeStatement{
|
||||||
|
"UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTypeNameId=?3 WHERE "
|
||||||
|
"propertyDeclarationId=?1",
|
||||||
|
database};
|
||||||
|
ReadStatement<1> selectPropertyDeclarationIdStatement{
|
||||||
|
"SELECT propertyDeclarationId FROM propertyDeclarations WHERE propertyDeclarationId=?",
|
||||||
|
database};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -43,6 +43,8 @@ enum class PropertyDeclarationTraits : unsigned int {
|
|||||||
IsList = 1 << 2
|
IsList = 1 << 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class TypeNameKind { Native = 0, Exported = 1 };
|
||||||
|
|
||||||
constexpr PropertyDeclarationTraits operator|(PropertyDeclarationTraits first,
|
constexpr PropertyDeclarationTraits operator|(PropertyDeclarationTraits first,
|
||||||
PropertyDeclarationTraits second)
|
PropertyDeclarationTraits second)
|
||||||
{
|
{
|
||||||
@@ -372,13 +374,12 @@ using PropertyDeclarations = std::vector<PropertyDeclaration>;
|
|||||||
class PropertyDeclarationView
|
class PropertyDeclarationView
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit PropertyDeclarationView(Utils::SmallStringView name,
|
explicit PropertyDeclarationView(
|
||||||
int traits,
|
Utils::SmallStringView name, int traits, long long typeId, long long typeNameId, long long id)
|
||||||
long long typeId,
|
|
||||||
long long id)
|
|
||||||
: name{name}
|
: name{name}
|
||||||
, traits{static_cast<PropertyDeclarationTraits>(traits)}
|
, traits{static_cast<PropertyDeclarationTraits>(traits)}
|
||||||
, typeId{typeId}
|
, typeId{typeId}
|
||||||
|
, typeNameId{typeNameId}
|
||||||
, id{id}
|
, id{id}
|
||||||
|
|
||||||
{}
|
{}
|
||||||
@@ -387,6 +388,7 @@ public:
|
|||||||
Utils::SmallStringView name;
|
Utils::SmallStringView name;
|
||||||
PropertyDeclarationTraits traits = {};
|
PropertyDeclarationTraits traits = {};
|
||||||
TypeId typeId;
|
TypeId typeId;
|
||||||
|
TypeNameId typeNameId;
|
||||||
PropertyDeclarationId id;
|
PropertyDeclarationId id;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -419,7 +421,7 @@ public:
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Utils::SmallString name;
|
Utils::SmallStringView name;
|
||||||
PropertyDeclarationId id;
|
PropertyDeclarationId id;
|
||||||
PropertyDeclarationId aliasId;
|
PropertyDeclarationId aliasId;
|
||||||
};
|
};
|
||||||
@@ -443,7 +445,6 @@ public:
|
|||||||
TypeId typeId = TypeId{})
|
TypeId typeId = TypeId{})
|
||||||
: typeName{typeName}
|
: typeName{typeName}
|
||||||
, prototype{std::move(prototype)}
|
, prototype{std::move(prototype)}
|
||||||
, importIds{std::move(importIds)}
|
|
||||||
, exportedTypes{std::move(exportedTypes)}
|
, exportedTypes{std::move(exportedTypes)}
|
||||||
, propertyDeclarations{std::move(propertyDeclarations)}
|
, propertyDeclarations{std::move(propertyDeclarations)}
|
||||||
, functionDeclarations{std::move(functionDeclarations)}
|
, functionDeclarations{std::move(functionDeclarations)}
|
||||||
@@ -487,7 +488,6 @@ public:
|
|||||||
Utils::SmallString typeName;
|
Utils::SmallString typeName;
|
||||||
TypeName prototype;
|
TypeName prototype;
|
||||||
Utils::SmallString attachedType;
|
Utils::SmallString attachedType;
|
||||||
ImportIds importIds;
|
|
||||||
ExportedTypes exportedTypes;
|
ExportedTypes exportedTypes;
|
||||||
PropertyDeclarations propertyDeclarations;
|
PropertyDeclarations propertyDeclarations;
|
||||||
FunctionDeclarations functionDeclarations;
|
FunctionDeclarations functionDeclarations;
|
||||||
@@ -503,6 +503,22 @@ public:
|
|||||||
|
|
||||||
using Types = std::vector<Type>;
|
using Types = std::vector<Type>;
|
||||||
|
|
||||||
|
class Document
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Document() = default;
|
||||||
|
explicit Document(SourceId sourceId, ImportIds importIds)
|
||||||
|
: importIds{std::move(importIds)}
|
||||||
|
, sourceId{sourceId}
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ImportIds importIds;
|
||||||
|
SourceId sourceId;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Documents = std::vector<Document>;
|
||||||
|
|
||||||
class BasicImport
|
class BasicImport
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@@ -195,7 +195,6 @@ protected:
|
|||||||
ProjectStorageMock storage{databaseMock, true};
|
ProjectStorageMock storage{databaseMock, true};
|
||||||
ReadWriteStatement<1> &upsertTypeStatement = storage.upsertTypeStatement;
|
ReadWriteStatement<1> &upsertTypeStatement = storage.upsertTypeStatement;
|
||||||
ReadStatement<1> &selectTypeIdByExportedNameStatement = storage.selectTypeIdByExportedNameStatement;
|
ReadStatement<1> &selectTypeIdByExportedNameStatement = storage.selectTypeIdByExportedNameStatement;
|
||||||
WriteStatement &upsertExportedTypesStatement = storage.upsertExportedTypesStatement;
|
|
||||||
ReadStatement<1> &selectSourceContextIdFromSourceContextsBySourceContextPathStatement
|
ReadStatement<1> &selectSourceContextIdFromSourceContextsBySourceContextPathStatement
|
||||||
= storage.selectSourceContextIdFromSourceContextsBySourceContextPathStatement;
|
= storage.selectSourceContextIdFromSourceContextsBySourceContextPathStatement;
|
||||||
ReadStatement<1> &selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatment
|
ReadStatement<1> &selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatment
|
||||||
@@ -468,6 +467,11 @@ protected:
|
|||||||
sourceId3 = sourcePathCache.sourceId(path3);
|
sourceId3 = sourcePathCache.sourceId(path3);
|
||||||
sourceId4 = sourcePathCache.sourceId(path4);
|
sourceId4 = sourcePathCache.sourceId(path4);
|
||||||
|
|
||||||
|
storage.synchronizeDocuments({Storage::Document{sourceId1, importIds},
|
||||||
|
Storage::Document{sourceId2, importIds},
|
||||||
|
Storage::Document{sourceId3, importIds},
|
||||||
|
Storage::Document{sourceId4, importIds}});
|
||||||
|
|
||||||
return Storage::Types{
|
return Storage::Types{
|
||||||
Storage::Type{
|
Storage::Type{
|
||||||
importId2,
|
importId2,
|
||||||
@@ -869,7 +873,7 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsNewTypesThrowsWithWrongExport
|
|||||||
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsNewTypesWithMissingImportAndExportedPrototypeName)
|
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsNewTypesWithMissingImportAndExportedPrototypeName)
|
||||||
{
|
{
|
||||||
Storage::Types types{createTypes()};
|
Storage::Types types{createTypes()};
|
||||||
types[0].importIds = {importId1};
|
storage.synchronizeDocuments({Storage::Document{sourceId1, {importId1}}});
|
||||||
types[1].prototype = Storage::ExportedType{"Object"};
|
types[1].prototype = Storage::ExportedType{"Object"};
|
||||||
|
|
||||||
ASSERT_THROW(storage.synchronizeTypes(types, {sourceId1, sourceId2}),
|
ASSERT_THROW(storage.synchronizeTypes(types, {sourceId1, sourceId2}),
|
||||||
@@ -879,7 +883,7 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsNewTypesWithMissingImportAndE
|
|||||||
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsNewTypesWithMissingImport)
|
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddsNewTypesWithMissingImport)
|
||||||
{
|
{
|
||||||
Storage::Types types{createTypes()};
|
Storage::Types types{createTypes()};
|
||||||
types[0].importIds = {importId1};
|
storage.synchronizeDocuments({Storage::Document{sourceId1, {importId1}}});
|
||||||
|
|
||||||
ASSERT_THROW(storage.synchronizeTypes(types, {sourceId1, sourceId2}),
|
ASSERT_THROW(storage.synchronizeTypes(types, {sourceId1, sourceId2}),
|
||||||
QmlDesigner::TypeNameDoesNotExists);
|
QmlDesigner::TypeNameDoesNotExists);
|
||||||
@@ -1154,7 +1158,7 @@ TEST_F(ProjectStorageSlowTest,
|
|||||||
SynchronizeTypesAddPropertyDeclarationsWithMissingImportIdsForNativeTypes)
|
SynchronizeTypesAddPropertyDeclarationsWithMissingImportIdsForNativeTypes)
|
||||||
{
|
{
|
||||||
Storage::Types types{createTypes()};
|
Storage::Types types{createTypes()};
|
||||||
types[0].importIds = {importId2};
|
storage.synchronizeDocuments({Storage::Document{sourceId1, {importId2}}});
|
||||||
types[0].propertyDeclarations.pop_back();
|
types[0].propertyDeclarations.pop_back();
|
||||||
|
|
||||||
ASSERT_THROW(storage.synchronizeTypes(types, {}), QmlDesigner::TypeNameDoesNotExists);
|
ASSERT_THROW(storage.synchronizeTypes(types, {}), QmlDesigner::TypeNameDoesNotExists);
|
||||||
@@ -1164,7 +1168,7 @@ TEST_F(ProjectStorageSlowTest,
|
|||||||
SynchronizeTypesAddPropertyDeclarationsWithMissingImportIdsForExportedTypes)
|
SynchronizeTypesAddPropertyDeclarationsWithMissingImportIdsForExportedTypes)
|
||||||
{
|
{
|
||||||
Storage::Types types{createTypes()};
|
Storage::Types types{createTypes()};
|
||||||
types[0].importIds = {importId1};
|
storage.synchronizeDocuments({Storage::Document{sourceId1, {importId1}}});
|
||||||
types[0].propertyDeclarations[0].typeName = Storage::ExportedType{"Obj"};
|
types[0].propertyDeclarations[0].typeName = Storage::ExportedType{"Obj"};
|
||||||
|
|
||||||
ASSERT_THROW(storage.synchronizeTypes(types, {}), QmlDesigner::TypeNameDoesNotExists);
|
ASSERT_THROW(storage.synchronizeTypes(types, {}), QmlDesigner::TypeNameDoesNotExists);
|
||||||
@@ -1414,7 +1418,7 @@ TEST_F(ProjectStorageSlowTest, BreakingPropertyDeclarationTypeDependencyByDeleti
|
|||||||
types.pop_back();
|
types.pop_back();
|
||||||
|
|
||||||
ASSERT_THROW(storage.synchronizeTypes(types, {sourceId1, sourceId2}),
|
ASSERT_THROW(storage.synchronizeTypes(types, {sourceId1, sourceId2}),
|
||||||
Sqlite::ConstraintPreventsModification);
|
QmlDesigner::TypeNameDoesNotExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddFunctionDeclarations)
|
TEST_F(ProjectStorageSlowTest, SynchronizeTypesAddFunctionDeclarations)
|
||||||
@@ -2702,4 +2706,137 @@ TEST_F(ProjectStorageSlowTest, SynchronizeTypesRemoveTypeAndAliasPropertyDeclara
|
|||||||
Storage::PropertyDeclarationTraits::IsList))))));
|
Storage::PropertyDeclarationTraits::IsList))))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectStorageSlowTest, UpdateAliasPropertyIfPropertyIsOverloaded)
|
||||||
|
{
|
||||||
|
Storage::Types types{createTypesWithAliases()};
|
||||||
|
storage.synchronizeTypes(types, {sourceId1, sourceId2, sourceId3, sourceId4});
|
||||||
|
types[0].propertyDeclarations.push_back(
|
||||||
|
Storage::PropertyDeclaration{"objects",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList
|
||||||
|
| Storage::PropertyDeclarationTraits::IsReadOnly});
|
||||||
|
|
||||||
|
storage.synchronizeTypes({types[0]}, {sourceId1});
|
||||||
|
|
||||||
|
ASSERT_THAT(
|
||||||
|
storage.fetchTypes(),
|
||||||
|
Contains(
|
||||||
|
AllOf(IsStorageType(importId2,
|
||||||
|
"QAliasItem",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
TypeAccessSemantics::Reference,
|
||||||
|
sourceId3),
|
||||||
|
Field(&Storage::Type::propertyDeclarations,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
IsPropertyDeclaration("items",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList
|
||||||
|
| Storage::PropertyDeclarationTraits::IsReadOnly),
|
||||||
|
IsPropertyDeclaration("objects",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList
|
||||||
|
| Storage::PropertyDeclarationTraits::IsReadOnly),
|
||||||
|
IsPropertyDeclaration("data",
|
||||||
|
Storage::NativeType{"QObject"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectStorageSlowTest, AliasPropertyIsOverloaded)
|
||||||
|
{
|
||||||
|
Storage::Types types{createTypesWithAliases()};
|
||||||
|
types[0].propertyDeclarations.push_back(
|
||||||
|
Storage::PropertyDeclaration{"objects",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList
|
||||||
|
| Storage::PropertyDeclarationTraits::IsReadOnly});
|
||||||
|
|
||||||
|
storage.synchronizeTypes(types, {sourceId1, sourceId2, sourceId3, sourceId4});
|
||||||
|
|
||||||
|
ASSERT_THAT(
|
||||||
|
storage.fetchTypes(),
|
||||||
|
Contains(
|
||||||
|
AllOf(IsStorageType(importId2,
|
||||||
|
"QAliasItem",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
TypeAccessSemantics::Reference,
|
||||||
|
sourceId3),
|
||||||
|
Field(&Storage::Type::propertyDeclarations,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
IsPropertyDeclaration("items",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList
|
||||||
|
| Storage::PropertyDeclarationTraits::IsReadOnly),
|
||||||
|
IsPropertyDeclaration("objects",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList
|
||||||
|
| Storage::PropertyDeclarationTraits::IsReadOnly),
|
||||||
|
IsPropertyDeclaration("data",
|
||||||
|
Storage::NativeType{"QObject"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectStorageSlowTest, UpdateAliasPropertyIfOverloadedPropertyIsRemoved)
|
||||||
|
{
|
||||||
|
Storage::Types types{createTypesWithAliases()};
|
||||||
|
types[0].propertyDeclarations.push_back(
|
||||||
|
Storage::PropertyDeclaration{"objects",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList
|
||||||
|
| Storage::PropertyDeclarationTraits::IsReadOnly});
|
||||||
|
storage.synchronizeTypes(types, {sourceId1, sourceId2, sourceId3, sourceId4});
|
||||||
|
types[0].propertyDeclarations.pop_back();
|
||||||
|
|
||||||
|
storage.synchronizeTypes({types[0]}, {sourceId1});
|
||||||
|
|
||||||
|
ASSERT_THAT(storage.fetchTypes(),
|
||||||
|
Contains(AllOf(
|
||||||
|
IsStorageType(importId2,
|
||||||
|
"QAliasItem",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
TypeAccessSemantics::Reference,
|
||||||
|
sourceId3),
|
||||||
|
Field(&Storage::Type::propertyDeclarations,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
IsPropertyDeclaration("items",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList
|
||||||
|
| Storage::PropertyDeclarationTraits::IsReadOnly),
|
||||||
|
IsPropertyDeclaration("objects",
|
||||||
|
Storage::NativeType{"QObject"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList),
|
||||||
|
IsPropertyDeclaration("data",
|
||||||
|
Storage::NativeType{"QObject"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ProjectStorageSlowTest, RelinkAliasProperty)
|
||||||
|
{
|
||||||
|
Storage::Types types{createTypesWithAliases()};
|
||||||
|
types[1].propertyDeclarations[0].typeName = Storage::NativeType{"QObject2"};
|
||||||
|
storage.synchronizeTypes(types, {sourceId1, sourceId2, sourceId3, sourceId4});
|
||||||
|
types[3].importId = importId2;
|
||||||
|
|
||||||
|
storage.synchronizeTypes({types[3]}, {sourceId4});
|
||||||
|
|
||||||
|
ASSERT_THAT(storage.fetchTypes(),
|
||||||
|
Contains(AllOf(
|
||||||
|
IsStorageType(importId2,
|
||||||
|
"QAliasItem",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
TypeAccessSemantics::Reference,
|
||||||
|
sourceId3),
|
||||||
|
Field(&Storage::Type::propertyDeclarations,
|
||||||
|
UnorderedElementsAre(
|
||||||
|
IsPropertyDeclaration("items",
|
||||||
|
Storage::NativeType{"QQuickItem"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList
|
||||||
|
| Storage::PropertyDeclarationTraits::IsReadOnly),
|
||||||
|
IsPropertyDeclaration("objects",
|
||||||
|
Storage::NativeType{"QObject2"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList),
|
||||||
|
IsPropertyDeclaration("data",
|
||||||
|
Storage::NativeType{"QObject"},
|
||||||
|
Storage::PropertyDeclarationTraits::IsList))))));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
Reference in New Issue
Block a user