Sqlite: Add compound id

Saving the source context id as part of the source id simplyfies file
path handling. It is now very easy to see if a two source ids have the
same source context id.

Change-Id: I6c86942d9f026fc047c49bbde3fffd6af14d81de
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2024-08-01 14:14:18 +02:00
parent 0d571b5e95
commit 2ae8ae75af
24 changed files with 392 additions and 501 deletions

View File

@@ -77,7 +77,7 @@ public:
void bind(int index, ValueView value); void bind(int index, ValueView value);
void bind(int index, BlobView blobView); void bind(int index, BlobView blobView);
template<typename Type, typename = std::enable_if_t<Type::IsBasicId::value>> template<typename Type, typename std::enable_if_t<Type::IsBasicId::value, bool> = true>
void bind(int index, Type id) void bind(int index, Type id)
{ {
if (!id.isNull()) if (!id.isNull())
@@ -527,8 +527,7 @@ private:
operator BlobView() { return statement.fetchBlobValue(column); } operator BlobView() { return statement.fetchBlobValue(column); }
operator ValueView() { return statement.fetchValueView(column); } operator ValueView() { return statement.fetchValueView(column); }
template<typename ConversionType, template<typename ConversionType, typename = std::enable_if_t<ConversionType::IsBasicId::value>>
typename = std::enable_if_t<ConversionType::IsBasicId::value>>
constexpr operator ConversionType() constexpr operator ConversionType()
{ {
if (statement.fetchType(column) == Type::Integer) { if (statement.fetchType(column) == Type::Integer) {

View File

@@ -15,6 +15,9 @@ namespace Sqlite {
template<auto Type, typename InternalIntegerType = long long> template<auto Type, typename InternalIntegerType = long long>
class BasicId class BasicId
{ {
template<auto, auto>
friend class CompoundBasicId;
public: public:
using IsBasicId = std::true_type; using IsBasicId = std::true_type;
using DatabaseType = InternalIntegerType; using DatabaseType = InternalIntegerType;
@@ -97,6 +100,104 @@ protected:
InternalIntegerType id = 0; InternalIntegerType id = 0;
}; };
template<auto Type, auto ContextType>
class CompoundBasicId
{
public:
using IsBasicId = std::true_type;
using DatabaseType = long long;
using MainId = BasicId<Type, int>;
using ContextId = BasicId<ContextType, int>;
constexpr explicit CompoundBasicId() = default;
static constexpr CompoundBasicId create(MainId id, ContextId contextId)
{
CompoundBasicId compoundId;
compoundId.id = (static_cast<long long>(contextId.id) << 32) | static_cast<long long>(id.id);
return compoundId;
}
static constexpr CompoundBasicId create(long long idNumber)
{
CompoundBasicId id;
id.id = idNumber;
return id;
}
constexpr MainId mainId() const { return MainId::create(id); }
constexpr ContextId contextId() const { return ContextId::create(id >> 32); }
friend constexpr bool compareInvalidAreTrue(CompoundBasicId first, CompoundBasicId second)
{
return first.id, second.id;
}
friend constexpr bool operator==(CompoundBasicId first, CompoundBasicId second)
{
return first.id == second.id;
}
friend constexpr bool operator!=(CompoundBasicId first, CompoundBasicId second)
{
return !(first == second);
}
friend constexpr bool operator<(CompoundBasicId first, CompoundBasicId second)
{
return first.id < second.id;
}
friend constexpr bool operator>(CompoundBasicId first, CompoundBasicId second)
{
return first.id > second.id;
}
friend constexpr bool operator<=(CompoundBasicId first, CompoundBasicId second)
{
return first.id <= second.id;
}
friend constexpr bool operator>=(CompoundBasicId first, CompoundBasicId second)
{
return first.id >= second.id;
}
friend constexpr long long operator-(CompoundBasicId first, CompoundBasicId second)
{
return first.id - second.id;
}
constexpr bool isValid() const { return id != 0; }
constexpr bool isNull() const { return id == 0; }
explicit operator bool() const { return isValid(); }
long long internalId() const { return id; }
explicit operator std::size_t() const { return static_cast<std::size_t>(id | 0xFFFFFFFFULL); }
template<typename String>
friend void convertToString(String &string, CompoundBasicId id)
{
convertToString(string, id.id);
convertToString(string, id.contextId);
}
friend bool compareId(CompoundBasicId first, CompoundBasicId second)
{
return first.id == second.id;
}
protected:
long long id = 0;
};
template<typename Container> template<typename Container>
auto toIntegers(const Container &container) auto toIntegers(const Container &container)
{ {

View File

@@ -15,7 +15,7 @@ enum class BasicIdType {
Type, Type,
PropertyType, PropertyType,
PropertyDeclaration, PropertyDeclaration,
Source, SourceName,
SourceContext, SourceContext,
StorageCacheIndex, StorageCacheIndex,
FunctionDeclaration, FunctionDeclaration,
@@ -51,10 +51,10 @@ using SourceContextIds = std::vector<SourceContextId>;
template<std::size_t size> template<std::size_t size>
using SmallSourceContextIds = QVarLengthArray<SourceContextId, size>; using SmallSourceContextIds = QVarLengthArray<SourceContextId, size>;
using SourceId = Sqlite::BasicId<BasicIdType::Source, int>; using SourceNameId = Sqlite::BasicId<BasicIdType::SourceName, int>;
using SourceIds = std::vector<SourceId>; using SourceNameIds = std::vector<SourceNameId>;
template<std::size_t size> template<std::size_t size>
using SmallSourceIds = QVarLengthArray<SourceId, size>; using SmallSourceNameIds = QVarLengthArray<SourceNameId, size>;
using ModuleId = Sqlite::BasicId<BasicIdType::Module, int>; using ModuleId = Sqlite::BasicId<BasicIdType::Module, int>;
using ModuleIds = std::vector<ModuleId>; using ModuleIds = std::vector<ModuleId>;
@@ -75,4 +75,9 @@ using ExportedTypeNameIds = std::vector<ExportedTypeNameId>;
using ModuleExportedImportId = Sqlite::BasicId<BasicIdType::ModuleExportedImport>; using ModuleExportedImportId = Sqlite::BasicId<BasicIdType::ModuleExportedImport>;
using ModuleExportedImportIds = std::vector<ModuleExportedImportId>; using ModuleExportedImportIds = std::vector<ModuleExportedImportId>;
using SourceId = Sqlite::CompoundBasicId<BasicIdType::SourceName, BasicIdType::SourceContext>;
using SourceIds = std::vector<SourceId>;
template<std::size_t size>
using SmallSourceIds = QVarLengthArray<SourceId, size>;
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -81,16 +81,14 @@ struct ProjectStorage::Statements
"SELECT sourceContextPath, sourceContextId FROM sourceContexts", database}; "SELECT sourceContextPath, sourceContextId FROM sourceContexts", database};
Sqlite::WriteStatement<1> insertIntoSourceContextsStatement{ Sqlite::WriteStatement<1> insertIntoSourceContextsStatement{
"INSERT INTO sourceContexts(sourceContextPath) VALUES (?)", database}; "INSERT INTO sourceContexts(sourceContextPath) VALUES (?)", database};
mutable Sqlite::ReadStatement<1, 2> selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatement{ mutable Sqlite::ReadStatement<1, 1> selectSourceNameIdFromSourceNamesBySourceNameStatement{
"SELECT sourceId FROM sources WHERE sourceContextId = ? AND sourceName = ?", database}; "SELECT sourceNameId FROM sourceNames WHERE sourceName = ?", database};
mutable Sqlite::ReadStatement<2, 1> selectSourceNameAndSourceContextIdFromSourcesBySourceIdStatement{ mutable Sqlite::ReadStatement<1, 1> selectSourceNameFromSourceNamesBySourceNameIdStatement{
"SELECT sourceName, sourceContextId FROM sources WHERE sourceId = ?", database}; "SELECT sourceName FROM sourceNames WHERE sourceNameId = ?", database};
mutable Sqlite::ReadStatement<1, 1> selectSourceContextIdFromSourcesBySourceIdStatement{ Sqlite::WriteStatement<1> insertIntoSourcesStatement{
"SELECT sourceContextId FROM sources WHERE sourceId = ?", database}; "INSERT INTO sourceNames(sourceName) VALUES (?)", database};
Sqlite::WriteStatement<2> insertIntoSourcesStatement{ mutable Sqlite::ReadStatement<2> selectAllSourcesStatement{
"INSERT INTO sources(sourceContextId, sourceName) VALUES (?,?)", database}; "SELECT sourceName, sourceNameId FROM sourceNames", database};
mutable Sqlite::ReadStatement<3> selectAllSourcesStatement{
"SELECT sourceName, sourceContextId, sourceId FROM sources", database};
mutable Sqlite::ReadStatement<8, 1> selectTypeByTypeIdStatement{ mutable Sqlite::ReadStatement<8, 1> selectTypeByTypeIdStatement{
"SELECT sourceId, t.name, t.typeId, prototypeId, extensionId, traits, annotationTraits, " "SELECT sourceId, t.name, t.typeId, prototypeId, extensionId, traits, annotationTraits, "
"pd.name " "pd.name "
@@ -621,7 +619,7 @@ struct ProjectStorage::Statements
"ORDER BY itn.kind, etn.majorVersion DESC NULLS FIRST, etn.minorVersion DESC NULLS FIRST " "ORDER BY itn.kind, etn.majorVersion DESC NULLS FIRST, etn.minorVersion DESC NULLS FIRST "
"LIMIT 1", "LIMIT 1",
database}; database};
Sqlite::WriteStatement<0> deleteAllSourcesStatement{"DELETE FROM sources", database}; Sqlite::WriteStatement<0> deleteAllSourceNamesStatement{"DELETE FROM sourceNames", database};
Sqlite::WriteStatement<0> deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database}; Sqlite::WriteStatement<0> deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database};
mutable Sqlite::ReadStatement<6, 1> selectExportedTypesForSourceIdsStatement{ mutable Sqlite::ReadStatement<6, 1> selectExportedTypesForSourceIdsStatement{
"SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1), typeId, " "SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1), typeId, "
@@ -897,7 +895,7 @@ public:
if (!isInitialized) { if (!isInitialized) {
auto moduleIdColumn = createModulesTable(database); auto moduleIdColumn = createModulesTable(database);
createSourceContextsTable(database); createSourceContextsTable(database);
createSourcesTable(database); createSourceNamesTable(database);
createTypesAndePropertyDeclarationsTables(database, moduleIdColumn); createTypesAndePropertyDeclarationsTables(database, moduleIdColumn);
createExportedTypeNamesTable(database, moduleIdColumn); createExportedTypeNamesTable(database, moduleIdColumn);
createImportedTypeNamesTable(database); createImportedTypeNamesTable(database);
@@ -927,22 +925,14 @@ public:
table.initialize(database); table.initialize(database);
} }
void createSourcesTable(Database &database) void createSourceNamesTable(Database &database)
{ {
Sqlite::StrictTable table; Sqlite::StrictTable table;
table.setUseIfNotExists(true); table.setUseIfNotExists(true);
table.setName("sources"); table.setName("sourceNames");
table.addColumn("sourceId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); table.addColumn("sourceNameId", 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); const auto &sourceNameColumn = table.addColumn("sourceName", Sqlite::StrictColumnType::Text);
table.addUniqueIndex({sourceContextIdColumn, sourceNameColumn}); table.addUniqueIndex({sourceNameColumn});
table.initialize(database); table.initialize(database);
} }
@@ -1217,13 +1207,7 @@ public:
Sqlite::StrictTable table; Sqlite::StrictTable table;
table.setUseIfNotExists(true); table.setUseIfNotExists(true);
table.setName("fileStatuses"); table.setName("fileStatuses");
table.addColumn("sourceId", table.addColumn("sourceId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}});
Sqlite::StrictColumnType::Integer,
{Sqlite::PrimaryKey{},
Sqlite::ForeignKey{"sources",
"sourceId",
Sqlite::ForeignKeyAction::NoAction,
Sqlite::ForeignKeyAction::Cascade}});
table.addColumn("size", Sqlite::StrictColumnType::Integer); table.addColumn("size", Sqlite::StrictColumnType::Integer);
table.addColumn("lastModified", Sqlite::StrictColumnType::Integer); table.addColumn("lastModified", Sqlite::StrictColumnType::Integer);
@@ -2193,89 +2177,66 @@ Cache::SourceContexts ProjectStorage::fetchAllSourceContexts() const
return s->selectAllSourceContextsStatement.valuesWithTransaction<Cache::SourceContext, 128>(); return s->selectAllSourceContextsStatement.valuesWithTransaction<Cache::SourceContext, 128>();
} }
SourceId ProjectStorage::fetchSourceId(SourceContextId sourceContextId, SourceNameId ProjectStorage::fetchSourceNameId(Utils::SmallStringView sourceName)
Utils::SmallStringView sourceName)
{ {
using NanotraceHR::keyValue; using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"fetch source id"_t, NanotraceHR::Tracer tracer{"fetch source id"_t,
projectStorageCategory(), projectStorageCategory(),
keyValue("source context id", sourceContextId),
keyValue("source name", sourceName)}; keyValue("source name", sourceName)};
auto sourceId = Sqlite::withDeferredTransaction(database, [&] { auto sourceNameId = Sqlite::withDeferredTransaction(database, [&] {
return fetchSourceIdUnguarded(sourceContextId, sourceName); return fetchSourceNameIdUnguarded(sourceName);
}); });
tracer.end(keyValue("source id", sourceId)); tracer.end(keyValue("source name id", sourceNameId));
return sourceId; return sourceNameId;
} }
Cache::SourceNameAndSourceContextId ProjectStorage::fetchSourceNameAndSourceContextId(SourceId sourceId) const Utils::SmallString ProjectStorage::fetchSourceName(SourceNameId sourceNameId) const
{ {
using NanotraceHR::keyValue; using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"fetch source name and source context id"_t, NanotraceHR::Tracer tracer{"fetch source name and source context id"_t,
projectStorageCategory(), projectStorageCategory(),
keyValue("source id", sourceId)}; keyValue("source name id", sourceNameId)};
auto value = s->selectSourceNameAndSourceContextIdFromSourcesBySourceIdStatement auto sourceName = s->selectSourceNameFromSourceNamesBySourceNameIdStatement
.valueWithTransaction<Cache::SourceNameAndSourceContextId>(sourceId); .valueWithTransaction<Utils::SmallString>(sourceNameId);
if (!value.sourceContextId) if (sourceName.empty())
throw SourceIdDoesNotExists(); throw SourceNameIdDoesNotExists();
tracer.end(keyValue("source name", value.sourceName), tracer.end(keyValue("source name", sourceName));
keyValue("source context id", value.sourceContextId));
return value; return sourceName;
} }
void ProjectStorage::clearSources() void ProjectStorage::clearSources()
{ {
Sqlite::withImmediateTransaction(database, [&] { Sqlite::withImmediateTransaction(database, [&] {
s->deleteAllSourceContextsStatement.execute(); s->deleteAllSourceContextsStatement.execute();
s->deleteAllSourcesStatement.execute(); s->deleteAllSourceNamesStatement.execute();
}); });
} }
SourceContextId ProjectStorage::fetchSourceContextId(SourceId sourceId) const Cache::SourceNames ProjectStorage::fetchAllSourceNames() const
{
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"fetch source context id"_t,
projectStorageCategory(),
keyValue("source id", sourceId)};
auto sourceContextId = s->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()}; NanotraceHR::Tracer tracer{"fetch all sources"_t, projectStorageCategory()};
return s->selectAllSourcesStatement.valuesWithTransaction<Cache::Source, 1024>(); return s->selectAllSourcesStatement.valuesWithTransaction<Cache::SourceName, 1024>();
} }
SourceId ProjectStorage::fetchSourceIdUnguarded(SourceContextId sourceContextId, SourceNameId ProjectStorage::fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName)
Utils::SmallStringView sourceName)
{ {
using NanotraceHR::keyValue; using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"fetch source id unguarded"_t, NanotraceHR::Tracer tracer{"fetch source id unguarded"_t,
projectStorageCategory(), projectStorageCategory(),
keyValue("source context id", sourceContextId),
keyValue("source name", sourceName)}; keyValue("source name", sourceName)};
auto sourceId = readSourceId(sourceContextId, sourceName); auto sourceId = readSourceNameId(sourceName);
if (!sourceId) if (!sourceId)
sourceId = writeSourceId(sourceContextId, sourceName); sourceId = writeSourceNameId(sourceName);
tracer.end(keyValue("source id", sourceId)); tracer.end(keyValue("source id", sourceId));
@@ -4908,39 +4869,35 @@ SourceContextId ProjectStorage::writeSourceContextId(Utils::SmallStringView sour
return sourceContextId; return sourceContextId;
} }
SourceId ProjectStorage::writeSourceId(SourceContextId sourceContextId, SourceNameId ProjectStorage::writeSourceNameId(Utils::SmallStringView sourceName)
Utils::SmallStringView sourceName)
{ {
using NanotraceHR::keyValue; using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"write source id"_t, NanotraceHR::Tracer tracer{"write source id"_t,
projectStorageCategory(), projectStorageCategory(),
keyValue("source context id", sourceContextId),
keyValue("source name", sourceName)}; keyValue("source name", sourceName)};
s->insertIntoSourcesStatement.write(sourceContextId, sourceName); s->insertIntoSourcesStatement.write(sourceName);
auto sourceId = SourceId::create(static_cast<int>(database.lastInsertedRowId())); auto sourceNameId = SourceNameId::create(static_cast<int>(database.lastInsertedRowId()));
tracer.end(keyValue("source id", sourceId)); tracer.end(keyValue("source name id", sourceNameId));
return sourceId; return sourceNameId;
} }
SourceId ProjectStorage::readSourceId(SourceContextId sourceContextId, SourceNameId ProjectStorage::readSourceNameId(Utils::SmallStringView sourceName)
Utils::SmallStringView sourceName)
{ {
using NanotraceHR::keyValue; using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"read source id"_t, NanotraceHR::Tracer tracer{"read source id"_t,
projectStorageCategory(), projectStorageCategory(),
keyValue("source context id", sourceContextId),
keyValue("source name", sourceName)}; keyValue("source name", sourceName)};
auto sourceId = s->selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatement auto sourceNameId = s->selectSourceNameIdFromSourceNamesBySourceNameStatement.value<SourceNameId>(
.value<SourceId>(sourceContextId, sourceName); sourceName);
tracer.end(keyValue("source id", sourceId)); tracer.end(keyValue("source id", sourceNameId));
return sourceId; return sourceNameId;
} }
Storage::Synchronization::ExportedTypes ProjectStorage::fetchExportedTypes(TypeId typeId) Storage::Synchronization::ExportedTypes ProjectStorage::fetchExportedTypes(TypeId typeId)

View File

@@ -223,18 +223,15 @@ public:
Cache::SourceContexts fetchAllSourceContexts() const; Cache::SourceContexts fetchAllSourceContexts() const;
SourceId fetchSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName); SourceNameId fetchSourceNameId(Utils::SmallStringView sourceName);
Cache::SourceNameAndSourceContextId fetchSourceNameAndSourceContextId(SourceId sourceId) const; Utils::SmallString fetchSourceName(SourceNameId sourceId) const;
void clearSources(); void clearSources();
SourceContextId fetchSourceContextId(SourceId sourceId) const; Cache::SourceNames fetchAllSourceNames() const;
Cache::Sources fetchAllSources() const; SourceNameId fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName);
SourceId fetchSourceIdUnguarded(SourceContextId sourceContextId,
Utils::SmallStringView sourceName);
FileStatuses fetchAllFileStatuses() const; FileStatuses fetchAllFileStatuses() const;
@@ -1009,9 +1006,9 @@ private:
SourceContextId writeSourceContextId(Utils::SmallStringView sourceContextPath); SourceContextId writeSourceContextId(Utils::SmallStringView sourceContextPath);
SourceId writeSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName); SourceNameId writeSourceNameId(Utils::SmallStringView sourceName);
SourceId readSourceId(SourceContextId sourceContextId, Utils::SmallStringView sourceName); SourceNameId readSourceNameId(Utils::SmallStringView sourceName);
Storage::Synchronization::ExportedTypes fetchExportedTypes(TypeId typeId); Storage::Synchronization::ExportedTypes fetchExportedTypes(TypeId typeId);

View File

@@ -8,7 +8,7 @@
namespace QmlDesigner { namespace QmlDesigner {
void ProjectStorageErrorNotifier::typeNameCannotBeResolved(Utils::SmallStringView typeName, void ProjectStorageErrorNotifier::typeNameCannotBeResolved(Utils::SmallStringView typeName,
SourceId sourceId) SourceId sourceId)
{ {
qDebug() << "Missing type name: " << typeName qDebug() << "Missing type name: " << typeName
<< " in file: " << m_pathCache.sourcePath(sourceId).toStringView(); << " in file: " << m_pathCache.sourcePath(sourceId).toStringView();

View File

@@ -47,12 +47,12 @@ const char *SourceContextIdDoesNotExists::what() const noexcept
return "The source context id does not exist in the database!"; return "The source context id does not exist in the database!";
} }
SourceIdDoesNotExists::SourceIdDoesNotExists() SourceNameIdDoesNotExists::SourceNameIdDoesNotExists()
{ {
category().threadEvent("SourceIdDoesNotExists"_t); category().threadEvent("SourceNameIdDoesNotExists"_t);
} }
const char *SourceIdDoesNotExists::what() const noexcept const char *SourceNameIdDoesNotExists::what() const noexcept
{ {
return "The source id does not exist in the database!"; return "The source id does not exist in the database!";
} }

View File

@@ -55,10 +55,10 @@ public:
const char *what() const noexcept override; const char *what() const noexcept override;
}; };
class QMLDESIGNERCORE_EXPORT SourceIdDoesNotExists : public ProjectStorageError class QMLDESIGNERCORE_EXPORT SourceNameIdDoesNotExists : public ProjectStorageError
{ {
public: public:
SourceIdDoesNotExists(); SourceNameIdDoesNotExists();
const char *what() const noexcept override; const char *what() const noexcept override;
}; };

View File

@@ -127,13 +127,16 @@ public:
ids.push_back(id); ids.push_back(id);
outputIterator = std::transform( outputIterator = std::transform(idPath.sourceIds.begin(),
idPath.sourceIds.begin(), idPath.sourceIds.end(), outputIterator, [&](SourceId sourceId) { idPath.sourceIds.end(),
return WatcherEntry{id, outputIterator,
m_pathCache.sourceContextId(sourceId), [&](SourceId sourceId) {
sourceId, return WatcherEntry{id,
m_fileStatusCache.lastModifiedTime(sourceId)}; sourceId.contextId(),
}); sourceId,
m_fileStatusCache.lastModifiedTime(
sourceId)};
});
} }
std::sort(entries.begin(), entries.end()); std::sort(entries.begin(), entries.end());

View File

@@ -483,7 +483,7 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct
auto subdirectorySourceIds = m_projectStorage.fetchSubdirectorySourceIds(directorySourceId); auto subdirectorySourceIds = m_projectStorage.fetchSubdirectorySourceIds(directorySourceId);
auto subdirectories = Utils::transform<Directories>( auto subdirectories = Utils::transform<Directories>(
subdirectorySourceIds, [&](SourceId sourceId) -> Directory { subdirectorySourceIds, [&](SourceId sourceId) -> Directory {
auto sourceContextId = m_pathCache.sourceContextId(sourceId); auto sourceContextId = sourceId.contextId();
auto subdirectoryPath = m_pathCache.sourceContextPath(sourceContextId); auto subdirectoryPath = m_pathCache.sourceContextPath(sourceContextId);
return {subdirectoryPath, sourceContextId, sourceId}; return {subdirectoryPath, sourceContextId, sourceId};
}); });
@@ -495,10 +495,9 @@ void ProjectStorageUpdater::updateSubdirectories(const Utils::PathString &direct
|| subdirectory.endsWith("/QtQuick/Scene3D")) || subdirectory.endsWith("/QtQuick/Scene3D"))
continue; continue;
Utils::PathString subdirectoryPath = subdirectory; Utils::PathString subdirectoryPath = subdirectory;
auto [sourceContextId, sourceId] = m_pathCache.sourceContextAndSourceId( SourceId sourceId = m_pathCache.sourceId(SourcePath{subdirectoryPath + "/."});
SourcePath{subdirectoryPath + "/."}); subdirectories.emplace_back(subdirectoryPath, sourceId.contextId(), sourceId);
subdirectories.emplace_back(subdirectoryPath, sourceContextId, sourceId); existingSubdirecories.emplace_back(subdirectoryPath, sourceId.contextId(), sourceId);
existingSubdirecories.emplace_back(subdirectoryPath, sourceContextId, sourceId);
} }
std::sort(subdirectories.begin(), subdirectories.end()); std::sort(subdirectories.begin(), subdirectories.end());
@@ -828,12 +827,10 @@ void ProjectStorageUpdater::updatePropertyEditorFilePath(
} }
namespace { namespace {
SourceContextIds filterUniqueSourceContextIds(const SourceIds &sourceIds, SourceContextIds filterUniqueSourceContextIds(const SourceIds &sourceIds)
ProjectStorageUpdater::PathCache &pathCache)
{ {
auto sourceContextIds = Utils::transform(sourceIds, [&](SourceId sourceId) { auto sourceContextIds = Utils::transform(sourceIds,
return pathCache.sourceContextId(sourceId); [](SourceId sourceId) { return sourceId.contextId(); });
});
std::sort(sourceContextIds.begin(), sourceContextIds.end()); std::sort(sourceContextIds.begin(), sourceContextIds.end());
auto newEnd = std::unique(sourceContextIds.begin(), sourceContextIds.end()); auto newEnd = std::unique(sourceContextIds.begin(), sourceContextIds.end());
@@ -899,7 +896,7 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &chan
} }
} }
auto directorySourceContextIds = filterUniqueSourceContextIds(directorySourceIds, m_pathCache); auto directorySourceContextIds = filterUniqueSourceContextIds(directorySourceIds);
for (auto sourceContextId : directorySourceContextIds) { for (auto sourceContextId : directorySourceContextIds) {
Utils::PathString directory = m_pathCache.sourceContextPath(sourceContextId); Utils::PathString directory = m_pathCache.sourceContextPath(sourceContextId);
@@ -911,13 +908,13 @@ void ProjectStorageUpdater::pathsWithIdsChanged(const std::vector<IdPaths> &chan
} }
for (SourceId sourceId : filterUniqueSourceIds(qmlDocumentSourceIds)) { for (SourceId sourceId : filterUniqueSourceIds(qmlDocumentSourceIds)) {
if (!contains(directorySourceContextIds, m_pathCache.sourceContextId(sourceId))) if (!contains(directorySourceContextIds, sourceId.contextId()))
parseQmlComponent(sourceId, package, notUpdatedSourceIds); parseQmlComponent(sourceId, package, notUpdatedSourceIds);
} }
try { try {
for (SourceId sourceId : filterUniqueSourceIds(std::move(qmltypesSourceIds))) { for (SourceId sourceId : filterUniqueSourceIds(std::move(qmltypesSourceIds))) {
if (!contains(directorySourceContextIds, m_pathCache.sourceContextId(sourceId))) { if (!contains(directorySourceContextIds, sourceId.contextId())) {
auto qmltypesPath = m_pathCache.sourcePath(sourceId); auto qmltypesPath = m_pathCache.sourcePath(sourceId);
auto directoryInfo = m_projectStorage.fetchDirectoryInfo(sourceId); auto directoryInfo = m_projectStorage.fetchDirectoryInfo(sourceId);
if (directoryInfo) if (directoryInfo)

View File

@@ -32,7 +32,7 @@ class SourcePathCache final : public SourcePathCacheInterface
public: public:
SourcePathCache(ProjectStorage &projectStorage) SourcePathCache(ProjectStorage &projectStorage)
: m_sourceContextStorageAdapter{projectStorage} : m_sourceContextStorageAdapter{projectStorage}
, m_sourceStorageAdapter{projectStorage} , m_sourceNameStorageAdapter{projectStorage}
{ {
populateIfEmpty(); populateIfEmpty();
@@ -58,9 +58,9 @@ public:
Utils::SmallStringView sourceName = sourcePath.name(); Utils::SmallStringView sourceName = sourcePath.name();
auto sourceId = m_sourcePathCache.id({sourceName, sourceContextId}); auto sourceId = m_sourcePathCache.id(sourceName);
return {sourceContextId, sourceId}; return {sourceContextId, SourceId::create(sourceId, sourceContextId)};
} }
SourceId sourceId(SourcePathView sourcePath) const override SourceId sourceId(SourcePathView sourcePath) const override
@@ -71,7 +71,9 @@ public:
SourceId sourceId(SourceContextId sourceContextId, SourceId sourceId(SourceContextId sourceContextId,
Utils::SmallStringView sourceName) const override Utils::SmallStringView sourceName) const override
{ {
return m_sourcePathCache.id({sourceName, sourceContextId}); SourceNameId sourceNameId = m_sourcePathCache.id(sourceName);
return SourceId::create(sourceNameId, sourceContextId);
} }
SourceContextId sourceContextId(Utils::SmallStringView sourceContextPath) const override SourceContextId sourceContextId(Utils::SmallStringView sourceContextPath) const override
@@ -88,11 +90,11 @@ public:
if (Q_UNLIKELY(!sourceId.isValid())) if (Q_UNLIKELY(!sourceId.isValid()))
throw NoSourcePathForInvalidSourceId(); throw NoSourcePathForInvalidSourceId();
auto entry = m_sourcePathCache.value(sourceId); auto sourceName = m_sourcePathCache.value(sourceId.mainId());
Utils::PathString sourceContextPath = m_sourceContextPathCache.value(entry.sourceContextId); Utils::PathString sourceContextPath = m_sourceContextPathCache.value(sourceId.contextId());
return SourcePath{sourceContextPath, entry.sourceName}; return SourcePath{sourceContextPath, sourceName};
} }
Utils::PathString sourceContextPath(SourceContextId sourceContextId) const override Utils::PathString sourceContextPath(SourceContextId sourceContextId) const override
@@ -103,19 +105,11 @@ public:
return m_sourceContextPathCache.value(sourceContextId); return m_sourceContextPathCache.value(sourceContextId);
} }
SourceContextId sourceContextId(SourceId sourceId) const override
{
if (Q_UNLIKELY(!sourceId.isValid()))
throw NoSourcePathForInvalidSourceId();
return m_sourcePathCache.value(sourceId).sourceContextId;
}
private: private:
class SourceContextStorageAdapter class SourceContextStorageAdapter
{ {
public: public:
auto fetchId(const Utils::SmallStringView sourceContextPath) auto fetchId(Utils::SmallStringView sourceContextPath)
{ {
return storage.fetchSourceContextId(sourceContextPath); return storage.fetchSourceContextId(sourceContextPath);
} }
@@ -127,27 +121,22 @@ private:
ProjectStorage &storage; ProjectStorage &storage;
}; };
class SourceStorageAdapter class SourceNameStorageAdapter
{ {
public: public:
auto fetchId(Cache::SourceNameView sourceNameView) auto fetchId(Utils::SmallStringView sourceNameView)
{ {
return storage.fetchSourceId(sourceNameView.sourceContextId, sourceNameView.sourceName); return storage.fetchSourceNameId(sourceNameView);
} }
auto fetchValue(SourceId id) auto fetchValue(SourceNameId id) { return storage.fetchSourceName(id); }
{
auto entry = storage.fetchSourceNameAndSourceContextId(id);
return Cache::SourceNameEntry{std::move(entry.sourceName), entry.sourceContextId}; auto fetchAll() { return storage.fetchAllSourceNames(); }
}
auto fetchAll() { return storage.fetchAllSources(); }
ProjectStorage &storage; ProjectStorage &storage;
}; };
static bool sourceContextLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept static bool sourceLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept
{ {
return std::lexicographical_compare(first.rbegin(), return std::lexicographical_compare(first.rbegin(),
first.rend(), first.rend(),
@@ -155,31 +144,26 @@ private:
second.rend()); second.rend());
} }
static bool sourceLess(Cache::SourceNameView first, Cache::SourceNameView second) noexcept
{
return first < second;
}
using SourceContextPathCache = StorageCache<Utils::PathString, using SourceContextPathCache = StorageCache<Utils::PathString,
Utils::SmallStringView, Utils::SmallStringView,
SourceContextId, SourceContextId,
SourceContextStorageAdapter, SourceContextStorageAdapter,
Mutex, Mutex,
sourceContextLess, sourceLess,
Cache::SourceContext>; Cache::SourceContext>;
using SourceNameCache = StorageCache<Cache::SourceNameEntry, using SourceNameCache = StorageCache<Utils::PathString,
Cache::SourceNameView, Utils::SmallStringView,
SourceId, SourceNameId,
SourceStorageAdapter, SourceNameStorageAdapter,
Mutex, Mutex,
sourceLess, sourceLess,
Cache::Source>; Cache::SourceName>;
private: private:
SourceContextStorageAdapter m_sourceContextStorageAdapter; SourceContextStorageAdapter m_sourceContextStorageAdapter;
SourceStorageAdapter m_sourceStorageAdapter; SourceNameStorageAdapter m_sourceNameStorageAdapter;
mutable SourceContextPathCache m_sourceContextPathCache{m_sourceContextStorageAdapter}; mutable SourceContextPathCache m_sourceContextPathCache{m_sourceContextStorageAdapter};
mutable SourceNameCache m_sourcePathCache{m_sourceStorageAdapter}; mutable SourceNameCache m_sourcePathCache{m_sourceNameStorageAdapter};
}; };
} // namespace QmlDesigner } // namespace QmlDesigner

View File

@@ -36,7 +36,6 @@ public:
virtual SourcePath sourcePath(SourceId sourceId) const = 0; virtual SourcePath sourcePath(SourceId sourceId) const = 0;
virtual Utils::PathString sourceContextPath(SourceContextId sourceContextId) const = 0; virtual Utils::PathString sourceContextPath(SourceContextId sourceContextId) const = 0;
virtual SourceContextId sourceContextId(SourceId sourceId) const = 0;
protected: protected:
~SourcePathCacheInterface() = default; ~SourcePathCacheInterface() = default;

View File

@@ -12,70 +12,6 @@
namespace QmlDesigner::Cache { namespace QmlDesigner::Cache {
class SourceNameView
{
public:
friend bool operator==(const SourceNameView &first, const SourceNameView &second) noexcept
{
return first.sourceContextId == second.sourceContextId
&& first.sourceName == second.sourceName;
}
friend bool operator<(SourceNameView first, SourceNameView second) noexcept
{
return std::tie(first.sourceContextId, first.sourceName)
< std::tie(second.sourceContextId, second.sourceName);
}
public:
Utils::SmallStringView sourceName;
SourceContextId sourceContextId;
};
class SourceNameEntry
{
public:
SourceNameEntry() = default;
SourceNameEntry(Utils::SmallStringView sourceName, SourceContextId sourceContextId)
: sourceName(sourceName)
, sourceContextId(sourceContextId)
{}
SourceNameEntry(SourceNameView view)
: sourceName(view.sourceName)
, sourceContextId(view.sourceContextId)
{}
friend bool operator==(const SourceNameEntry &first, const SourceNameEntry &second) noexcept
{
return first.sourceContextId == second.sourceContextId
&& first.sourceName == second.sourceName;
}
friend bool operator!=(const SourceNameEntry &first, const SourceNameEntry &second) noexcept
{
return !(first == second);
}
friend bool operator==(const SourceNameEntry &first, const SourceNameView &second) noexcept
{
return first.sourceContextId == second.sourceContextId
&& first.sourceName == second.sourceName;
}
friend bool operator!=(const SourceNameEntry &first, const SourceNameView &second) noexcept
{
return !(first == second);
}
operator SourceNameView() const noexcept { return {sourceName, sourceContextId}; }
operator Utils::SmallString() &&noexcept { return std::move(sourceName); }
public:
Utils::SmallString sourceName;
SourceContextId sourceContextId;
};
class SourceContext class SourceContext
: public StorageCacheEntry<Utils::PathString, Utils::SmallStringView, SourceContextId> : public StorageCacheEntry<Utils::PathString, Utils::SmallStringView, SourceContextId>
@@ -93,38 +29,19 @@ public:
using SourceContexts = std::vector<SourceContext>; using SourceContexts = std::vector<SourceContext>;
class Source : public StorageCacheEntry<SourceNameEntry, SourceNameView, SourceId> class SourceName : public StorageCacheEntry<Utils::PathString, Utils::SmallStringView, SourceNameId>
{ {
using Base = StorageCacheEntry<SourceNameEntry, SourceNameView, SourceId>; using Base = StorageCacheEntry<Utils::PathString, Utils::SmallStringView, SourceNameId>;
public: public:
using Base::Base; using Base::Base;
Source(Utils::SmallStringView sourceName, SourceContextId sourceContextId, SourceId sourceId)
: Base{{sourceName, sourceContextId}, sourceId}
{}
friend bool operator==(const Source &first, const Source &second) friend bool operator==(const SourceName &first, const SourceName &second)
{ {
return first.id == second.id && first.value == second.value; return first.id == second.id && first.value == second.value;
} }
}; };
using Sources = std::vector<Source>; using SourceNames = std::vector<SourceName>;
class SourceNameAndSourceContextId
{
public:
constexpr SourceNameAndSourceContextId() = default;
SourceNameAndSourceContextId(Utils::SmallStringView sourceName, SourceContextId sourceContextId)
: sourceName{sourceName}
, sourceContextId{sourceContextId}
{}
Utils::SmallString sourceName;
SourceContextId sourceContextId;
};
using SourceNameAndSourceContextIds = std::vector<SourceNameAndSourceContextId>;
} // namespace QmlDesigner::Cache } // namespace QmlDesigner::Cache

View File

@@ -324,26 +324,21 @@ public:
fetchSourceContextId, fetchSourceContextId,
(::Utils::SmallStringView SourceContextPath), (::Utils::SmallStringView SourceContextPath),
()); ());
MOCK_METHOD(QmlDesigner::SourceId, MOCK_METHOD(QmlDesigner::SourceNameId, fetchSourceNameId, (::Utils::SmallStringView sourceName), ());
fetchSourceId,
(QmlDesigner::SourceContextId SourceContextId, ::Utils::SmallStringView sourceName),
());
MOCK_METHOD(QmlDesigner::SourceContextId, MOCK_METHOD(QmlDesigner::SourceContextId,
fetchSourceContextIdUnguarded, fetchSourceContextIdUnguarded,
(::Utils::SmallStringView SourceContextPath), (::Utils::SmallStringView sourceContextPath),
()); ());
MOCK_METHOD(QmlDesigner::SourceId, MOCK_METHOD(QmlDesigner::SourceNameId,
fetchSourceIdUnguarded, fetchSourceNameIdUnguarded,
(QmlDesigner::SourceContextId SourceContextId, ::Utils::SmallStringView sourceName), (::Utils::SmallStringView sourceName),
()); ());
MOCK_METHOD(::Utils::PathString, MOCK_METHOD(::Utils::PathString,
fetchSourceContextPath, fetchSourceContextPath,
(QmlDesigner::SourceContextId sourceContextId)); (QmlDesigner::SourceContextId sourceContextId));
MOCK_METHOD(QmlDesigner::Cache::SourceNameAndSourceContextId, MOCK_METHOD(Utils::SmallString, fetchSourceName, (QmlDesigner::SourceNameId sourceId));
fetchSourceNameAndSourceContextId,
(QmlDesigner::SourceId sourceId));
MOCK_METHOD(std::vector<QmlDesigner::Cache::SourceContext>, fetchAllSourceContexts, (), ()); MOCK_METHOD(std::vector<QmlDesigner::Cache::SourceContext>, fetchAllSourceContexts, (), ());
MOCK_METHOD(std::vector<QmlDesigner::Cache::Source>, fetchAllSources, (), ()); MOCK_METHOD(std::vector<QmlDesigner::Cache::SourceName>, fetchAllSourceNames, (), ());
MOCK_METHOD(QmlDesigner::SourceId, MOCK_METHOD(QmlDesigner::SourceId,
propertyEditorPathId, propertyEditorPathId,

View File

@@ -41,10 +41,6 @@ public:
sourceContextPath, sourceContextPath,
(QmlDesigner::SourceContextId directoryPathId), (QmlDesigner::SourceContextId directoryPathId),
(const, override)); (const, override));
MOCK_METHOD(QmlDesigner::SourceContextId,
sourceContextId,
(QmlDesigner::SourceId sourceId),
(const, override));
MOCK_METHOD(void, populateIfEmpty, (), (override)); MOCK_METHOD(void, populateIfEmpty, (), (override));
}; };

View File

@@ -69,11 +69,10 @@ public:
(std::size_t), (std::size_t),
()); ());
MOCK_METHOD(std::vector<QmlDesigner::Cache::Source>, valuesReturnCacheSources, (std::size_t), ()); MOCK_METHOD(std::vector<QmlDesigner::Cache::SourceName>,
valuesReturnCacheSourceNames,
MOCK_METHOD(QmlDesigner::Cache::SourceNameAndSourceContextId, (std::size_t),
valueReturnCacheSourceNameAndSourceContextId, ());
(int) );
MOCK_METHOD(Sqlite::TimeStamp, valueWithTransactionReturnsTimeStamp, (Utils::SmallStringView), ()); MOCK_METHOD(Sqlite::TimeStamp, valueWithTransactionReturnsTimeStamp, (Utils::SmallStringView), ());
MOCK_METHOD(int, valueWithTransactionReturnsInt, (Utils::SmallStringView), ()); MOCK_METHOD(int, valueWithTransactionReturnsInt, (Utils::SmallStringView), ());
@@ -162,8 +161,6 @@ public:
else if constexpr (std::is_same_v<ResultType, else if constexpr (std::is_same_v<ResultType,
std::tuple<QmlDesigner::PropertyDeclarationId, QmlDesigner::TypeId>>) std::tuple<QmlDesigner::PropertyDeclarationId, QmlDesigner::TypeId>>)
return valueReturnsPropertyDeclaration(queryValues...); return valueReturnsPropertyDeclaration(queryValues...);
else if constexpr (std::is_same_v<ResultType, QmlDesigner::Cache::SourceNameAndSourceContextId>)
return valueReturnCacheSourceNameAndSourceContextId(queryValues...);
else if constexpr (std::is_same_v<ResultType, QmlDesigner::SourceContextId>) else if constexpr (std::is_same_v<ResultType, QmlDesigner::SourceContextId>)
return valueReturnsSourceContextId(queryValues...); return valueReturnsSourceContextId(queryValues...);
else if constexpr (std::is_same_v<ResultType, QmlDesigner::SourceId>) else if constexpr (std::is_same_v<ResultType, QmlDesigner::SourceId>)
@@ -212,8 +209,8 @@ public:
return valuesReturnRowIds(reserveSize); return valuesReturnRowIds(reserveSize);
else if constexpr (std::is_same_v<ResultType, QmlDesigner::Cache::SourceContext>) else if constexpr (std::is_same_v<ResultType, QmlDesigner::Cache::SourceContext>)
return valuesReturnCacheSourceContexts(reserveSize); return valuesReturnCacheSourceContexts(reserveSize);
else if constexpr (std::is_same_v<ResultType, QmlDesigner::Cache::Source>) else if constexpr (std::is_same_v<ResultType, QmlDesigner::Cache::SourceName>)
return valuesReturnCacheSources(reserveSize); return valuesReturnCacheSourceNames(reserveSize);
else if constexpr (std::is_same_v<ResultType, QmlDesigner::Storage::Synchronization::Type>) else if constexpr (std::is_same_v<ResultType, QmlDesigner::Storage::Synchronization::Type>)
return valuesReturnsStorageTypes(reserveSize, queryValues...); return valuesReturnsStorageTypes(reserveSize, queryValues...);
else if constexpr (std::is_same_v<ResultType, QmlDesigner::Storage::Synchronization::ExportedType>) else if constexpr (std::is_same_v<ResultType, QmlDesigner::Storage::Synchronization::ExportedType>)

View File

@@ -23,6 +23,8 @@ enum class LockingMode : char;
class TimeStamp; class TimeStamp;
template<auto Type, typename InternalIntegerType> template<auto Type, typename InternalIntegerType>
class BasicId; class BasicId;
template<auto Type, auto ContextType>
class CompoundBasicId;
std::ostream &operator<<(std::ostream &out, const Value &value); std::ostream &operator<<(std::ostream &out, const Value &value);
std::ostream &operator<<(std::ostream &out, const ValueView &value); std::ostream &operator<<(std::ostream &out, const ValueView &value);
@@ -37,6 +39,12 @@ std::ostream &operator<<(std::ostream &out, const BasicId<Type, InternalIntegerT
return out << "id=" << id.internalId(); return out << "id=" << id.internalId();
} }
template<auto Type, auto ContextType>
std::ostream &operator<<(std::ostream &out, const CompoundBasicId<Type, ContextType> &id)
{
return out << "id=(" << id.mainId().internalId() << ", " << id.contextId().internalId() << ")";
}
namespace SessionChangeSetInternal { namespace SessionChangeSetInternal {
class ConstIterator; class ConstIterator;
class ConstTupleIterator; class ConstTupleIterator;

View File

@@ -19,8 +19,8 @@
namespace { namespace {
using QmlDesigner::Cache::Source;
using QmlDesigner::Cache::SourceContext; using QmlDesigner::Cache::SourceContext;
using QmlDesigner::Cache::SourceName;
using QmlDesigner::FileStatus; using QmlDesigner::FileStatus;
using QmlDesigner::FileStatuses; using QmlDesigner::FileStatuses;
using QmlDesigner::FlagIs; using QmlDesigner::FlagIs;
@@ -29,6 +29,7 @@ using QmlDesigner::PropertyDeclarationId;
using QmlDesigner::SourceContextId; using QmlDesigner::SourceContextId;
using QmlDesigner::SourceId; using QmlDesigner::SourceId;
using QmlDesigner::SourceIds; using QmlDesigner::SourceIds;
using QmlDesigner::SourceNameId;
using QmlDesigner::Storage::ModuleKind; using QmlDesigner::Storage::ModuleKind;
using QmlDesigner::Storage::Synchronization::SynchronizationPackage; using QmlDesigner::Storage::Synchronization::SynchronizationPackage;
using QmlDesigner::Storage::Synchronization::TypeAnnotations; using QmlDesigner::Storage::Synchronization::TypeAnnotations;
@@ -66,18 +67,6 @@ MATCHER_P2(IsSourceContext,
return sourceContext.id == id && sourceContext.value == value; return sourceContext.id == id && sourceContext.value == value;
} }
MATCHER_P2(IsSourceNameAndSourceContextId,
name,
id,
std::string(negation ? "isn't " : "is ")
+ PrintToString(QmlDesigner::Cache::SourceNameAndSourceContextId{name, id}))
{
const QmlDesigner::Cache::SourceNameAndSourceContextId &sourceNameAndSourceContextId = arg;
return sourceNameAndSourceContextId.sourceName == name
&& sourceNameAndSourceContextId.sourceContextId == id;
}
MATCHER_P4(IsStorageType, MATCHER_P4(IsStorageType,
sourceId, sourceId,
typeName, typeName,
@@ -352,18 +341,14 @@ protected:
void addSomeDummyData() void addSomeDummyData()
{ {
auto sourceContextId1 = storage.fetchSourceContextId("/path/dummy"); storage.fetchSourceContextId("/path/dummy");
auto sourceContextId2 = storage.fetchSourceContextId("/path/dummy2"); storage.fetchSourceContextId("/path/dummy2");
auto sourceContextId3 = storage.fetchSourceContextId("/path/"); storage.fetchSourceContextId("/path/");
storage.fetchSourceId(sourceContextId1, "foo"); storage.fetchSourceNameId("foo");
storage.fetchSourceId(sourceContextId1, "dummy"); storage.fetchSourceNameId("dummy");
storage.fetchSourceId(sourceContextId2, "foo"); storage.fetchSourceNameId("bar");
storage.fetchSourceId(sourceContextId2, "bar"); storage.fetchSourceNameId("bar");
storage.fetchSourceId(sourceContextId3, "foo");
storage.fetchSourceId(sourceContextId3, "bar");
storage.fetchSourceId(sourceContextId1, "bar");
storage.fetchSourceId(sourceContextId3, "bar");
} }
auto createVerySimpleSynchronizationPackage() auto createVerySimpleSynchronizationPackage()
@@ -1342,92 +1327,53 @@ TEST_F(ProjectStorage, fetch_all_source_contexts)
TEST_F(ProjectStorage, fetch_source_id_first_time) TEST_F(ProjectStorage, fetch_source_id_first_time)
{ {
addSomeDummyData(); addSomeDummyData();
auto sourceContextId = storage.fetchSourceContextId("/path/to");
auto sourceId = storage.fetchSourceId(sourceContextId, "foo"); auto sourceNameId = storage.fetchSourceNameId("foo");
ASSERT_TRUE(sourceId.isValid()); ASSERT_TRUE(sourceNameId.isValid());
} }
TEST_F(ProjectStorage, fetch_existing_source_id) TEST_F(ProjectStorage, fetch_existing_source_id)
{ {
addSomeDummyData(); addSomeDummyData();
auto sourceContextId = storage.fetchSourceContextId("/path/to"); auto createdSourceNameId = storage.fetchSourceNameId("foo");
auto createdSourceId = storage.fetchSourceId(sourceContextId, "foo");
auto sourceId = storage.fetchSourceId(sourceContextId, "foo"); auto sourceNameId = storage.fetchSourceNameId("foo");
ASSERT_THAT(sourceId, createdSourceId); ASSERT_THAT(sourceNameId, createdSourceNameId);
}
TEST_F(ProjectStorage, fetch_source_id_with_different_context_id_are_not_equal)
{
addSomeDummyData();
auto sourceContextId = storage.fetchSourceContextId("/path/to");
auto sourceContextId2 = storage.fetchSourceContextId("/path/to2");
auto sourceId2 = storage.fetchSourceId(sourceContextId2, "foo");
auto sourceId = storage.fetchSourceId(sourceContextId, "foo");
ASSERT_THAT(sourceId, Ne(sourceId2));
} }
TEST_F(ProjectStorage, fetch_source_id_with_different_name_are_not_equal) TEST_F(ProjectStorage, fetch_source_id_with_different_name_are_not_equal)
{ {
addSomeDummyData(); addSomeDummyData();
auto sourceContextId = storage.fetchSourceContextId("/path/to"); auto sourceNameId2 = storage.fetchSourceNameId("foo");
auto sourceId2 = storage.fetchSourceId(sourceContextId, "foo");
auto sourceId = storage.fetchSourceId(sourceContextId, "foo2"); auto sourceNameId = storage.fetchSourceNameId("foo2");
ASSERT_THAT(sourceId, Ne(sourceId2)); ASSERT_THAT(sourceNameId, Ne(sourceNameId2));
}
TEST_F(ProjectStorage, fetch_source_id_with_non_existing_source_context_id_throws)
{
ASSERT_THROW(storage.fetchSourceId(SourceContextId::create(42), "foo"),
Sqlite::ConstraintPreventsModification);
} }
TEST_F(ProjectStorage, fetch_source_name_and_source_context_id_for_non_existing_source_id) TEST_F(ProjectStorage, fetch_source_name_and_source_context_id_for_non_existing_source_id)
{ {
ASSERT_THROW(storage.fetchSourceNameAndSourceContextId(SourceId::create(212)), ASSERT_THROW(storage.fetchSourceName(SourceNameId::create(212)),
QmlDesigner::SourceIdDoesNotExists); QmlDesigner::SourceNameIdDoesNotExists);
} }
TEST_F(ProjectStorage, fetch_source_name_and_source_context_id_for_non_existing_entry) TEST_F(ProjectStorage, fetch_source_name_for_non_existing_entry)
{ {
addSomeDummyData(); addSomeDummyData();
auto sourceContextId = storage.fetchSourceContextId("/path/to"); auto sourceNameId = storage.fetchSourceNameId("foo");
auto sourceId = storage.fetchSourceId(sourceContextId, "foo");
auto sourceNameAndSourceContextId = storage.fetchSourceNameAndSourceContextId(sourceId); auto sourceName = storage.fetchSourceName(sourceNameId);
ASSERT_THAT(sourceNameAndSourceContextId, IsSourceNameAndSourceContextId("foo", sourceContextId)); ASSERT_THAT(sourceName, Eq("foo"));
}
TEST_F(ProjectStorage, fetch_source_context_id_for_non_existing_source_id)
{
ASSERT_THROW(storage.fetchSourceContextId(SourceId::create(212)),
QmlDesigner::SourceIdDoesNotExists);
}
TEST_F(ProjectStorage, fetch_source_context_id_for_existing_source_id)
{
addSomeDummyData();
auto originalSourceContextId = storage.fetchSourceContextId("/path/to3");
auto sourceId = storage.fetchSourceId(originalSourceContextId, "foo");
auto sourceContextId = storage.fetchSourceContextId(sourceId);
ASSERT_THAT(sourceContextId, Eq(originalSourceContextId));
} }
TEST_F(ProjectStorage, fetch_all_sources) TEST_F(ProjectStorage, fetch_all_sources)
{ {
storage.clearSources(); storage.clearSources();
auto sources = storage.fetchAllSources(); auto sources = storage.fetchAllSourceNames();
ASSERT_THAT(toValues(sources), IsEmpty()); ASSERT_THAT(toValues(sources), IsEmpty());
} }
@@ -1435,10 +1381,9 @@ TEST_F(ProjectStorage, fetch_all_sources)
TEST_F(ProjectStorage, fetch_source_id_unguarded_first_time) TEST_F(ProjectStorage, fetch_source_id_unguarded_first_time)
{ {
addSomeDummyData(); addSomeDummyData();
auto sourceContextId = storage.fetchSourceContextId("/path/to");
std::lock_guard lock{database}; std::lock_guard lock{database};
auto sourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo"); auto sourceId = storage.fetchSourceNameIdUnguarded("foo");
ASSERT_TRUE(sourceId.isValid()); ASSERT_TRUE(sourceId.isValid());
} }
@@ -1446,48 +1391,25 @@ TEST_F(ProjectStorage, fetch_source_id_unguarded_first_time)
TEST_F(ProjectStorage, fetch_existing_source_id_unguarded) TEST_F(ProjectStorage, fetch_existing_source_id_unguarded)
{ {
addSomeDummyData(); addSomeDummyData();
auto sourceContextId = storage.fetchSourceContextId("/path/to");
std::lock_guard lock{database}; std::lock_guard lock{database};
auto createdSourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo"); auto createdSourceId = storage.fetchSourceNameIdUnguarded("foo");
auto sourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo"); auto sourceId = storage.fetchSourceNameIdUnguarded("foo");
ASSERT_THAT(sourceId, createdSourceId); ASSERT_THAT(sourceId, createdSourceId);
} }
TEST_F(ProjectStorage, fetch_source_id_unguarded_with_different_context_id_are_not_equal)
{
addSomeDummyData();
auto sourceContextId = storage.fetchSourceContextId("/path/to");
auto sourceContextId2 = storage.fetchSourceContextId("/path/to2");
std::lock_guard lock{database};
auto sourceId2 = storage.fetchSourceIdUnguarded(sourceContextId2, "foo");
auto sourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo");
ASSERT_THAT(sourceId, Ne(sourceId2));
}
TEST_F(ProjectStorage, fetch_source_id_unguarded_with_different_name_are_not_equal) TEST_F(ProjectStorage, fetch_source_id_unguarded_with_different_name_are_not_equal)
{ {
addSomeDummyData(); addSomeDummyData();
auto sourceContextId = storage.fetchSourceContextId("/path/to");
std::lock_guard lock{database}; std::lock_guard lock{database};
auto sourceId2 = storage.fetchSourceIdUnguarded(sourceContextId, "foo"); auto sourceId2 = storage.fetchSourceNameIdUnguarded("foo");
auto sourceId = storage.fetchSourceIdUnguarded(sourceContextId, "foo2"); auto sourceId = storage.fetchSourceNameIdUnguarded("foo2");
ASSERT_THAT(sourceId, Ne(sourceId2)); ASSERT_THAT(sourceId, Ne(sourceId2));
} }
TEST_F(ProjectStorage, fetch_source_id_unguarded_with_non_existing_source_context_id_throws)
{
std::lock_guard lock{database};
ASSERT_THROW(storage.fetchSourceIdUnguarded(SourceContextId::create(42), "foo"),
Sqlite::ConstraintPreventsModification);
}
TEST_F(ProjectStorage, synchronize_types_adds_new_types) TEST_F(ProjectStorage, synchronize_types_adds_new_types)
{ {
auto package{createSimpleSynchronizationPackage()}; auto package{createSimpleSynchronizationPackage()};

View File

@@ -104,9 +104,9 @@ protected:
pathCache.sourceId(path3), pathCache.sourceId(path3),
pathCache.sourceId(path4), pathCache.sourceId(path4),
pathCache.sourceId(path5)}; pathCache.sourceId(path5)};
SourceContextIds sourceContextIds = {pathCache.sourceContextId(sourceIds[0]), SourceContextIds sourceContextIds = {sourceIds[0].contextId(),
pathCache.sourceContextId(sourceIds[2]), sourceIds[2].contextId(),
pathCache.sourceContextId(sourceIds[4])}; sourceIds[4].contextId()};
ProjectChunkIds ids{projectChunkId1, projectChunkId2, projectChunkId3}; ProjectChunkIds ids{projectChunkId1, projectChunkId2, projectChunkId3};
WatcherEntry watcherEntry1{projectChunkId1, sourceContextIds[0], sourceIds[0]}; WatcherEntry watcherEntry1{projectChunkId1, sourceContextIds[0], sourceIds[0]};
WatcherEntry watcherEntry2{projectChunkId2, sourceContextIds[0], sourceIds[0]}; WatcherEntry watcherEntry2{projectChunkId2, sourceContextIds[0], sourceIds[0]};
@@ -366,10 +366,9 @@ TEST_F(ProjectStoragePathWatcher, two_notify_file_changes)
.WillByDefault(Return(FileStatus{sourceIds[3], 1, 2})); .WillByDefault(Return(FileStatus{sourceIds[3], 1, 2}));
EXPECT_CALL(notifier, EXPECT_CALL(notifier,
pathsWithIdsChanged(ElementsAre( pathsWithIdsChanged(
IdPaths{projectChunkId1, {SourceId::create(1), SourceId::create(2)}}, ElementsAre(IdPaths{projectChunkId1, {sourceIds[0], sourceIds[1]}},
IdPaths{projectChunkId2, IdPaths{projectChunkId2, {sourceIds[0], sourceIds[1], sourceIds[3]}})));
{SourceId::create(1), SourceId::create(2), SourceId::create(4)}})));
mockQFileSytemWatcher.directoryChanged(sourceContextPath); mockQFileSytemWatcher.directoryChanged(sourceContextPath);
mockQFileSytemWatcher.directoryChanged(sourceContextPath2); mockQFileSytemWatcher.directoryChanged(sourceContextPath2);

View File

@@ -2413,7 +2413,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_directory_change
setContent(u"/path/qmldir", qmldir); setContent(u"/path/qmldir", qmldir);
setFilesChanged({directoryPathSourceId}); setFilesChanged({directoryPathSourceId});
setFilesDontChanged({qmlDirPathSourceId}); setFilesDontChanged({qmlDirPathSourceId});
auto directorySourceContextId = sourcePathCache.sourceContextId(directoryPathSourceId); auto directorySourceContextId = directoryPathSourceId.contextId();
EXPECT_CALL(patchWatcherMock, EXPECT_CALL(patchWatcherMock,
updateContextIdPaths( updateContextIdPaths(
@@ -2526,7 +2526,7 @@ TEST_F(ProjectStorageUpdater, watcher_watches_directories_after_qmldir_changes)
FirstType 2.2 First2.qml FirstType 2.2 First2.qml
SecondType 2.2 Second.qml)"}; SecondType 2.2 Second.qml)"};
setContent(u"/path/qmldir", qmldir); setContent(u"/path/qmldir", qmldir);
auto directorySourceContextId = sourcePathCache.sourceContextId(qmlDirPathSourceId); auto directorySourceContextId = qmlDirPathSourceId.contextId();
EXPECT_CALL(patchWatcherMock, EXPECT_CALL(patchWatcherMock,
updateContextIdPaths( updateContextIdPaths(

View File

@@ -156,7 +156,7 @@ protected:
QmlDesigner::QmlDocumentParser parser{storage, sourcePathCache}; QmlDesigner::QmlDocumentParser parser{storage, sourcePathCache};
Storage::Imports imports; Storage::Imports imports;
SourceId qmlFileSourceId{sourcePathCache.sourceId("/path/to/qmlfile.qml")}; SourceId qmlFileSourceId{sourcePathCache.sourceId("/path/to/qmlfile.qml")};
SourceContextId qmlFileSourceContextId{sourcePathCache.sourceContextId(qmlFileSourceId)}; SourceContextId qmlFileSourceContextId{qmlFileSourceId.contextId()};
Utils::PathString directoryPath{sourcePathCache.sourceContextPath(qmlFileSourceContextId)}; Utils::PathString directoryPath{sourcePathCache.sourceContextPath(qmlFileSourceContextId)};
ModuleId directoryModuleId{storage.moduleId(directoryPath, ModuleKind::PathLibrary)}; ModuleId directoryModuleId{storage.moduleId(directoryPath, ModuleKind::PathLibrary)};
}; };

View File

@@ -184,7 +184,7 @@ protected:
qmltypesFileSourceId, qmltypesFileSourceId,
qtQmlNativeModuleId, qtQmlNativeModuleId,
Synchronization::FileType::QmlTypes}; Synchronization::FileType::QmlTypes};
SourceContextId qmltypesFileSourceContextId{sourcePathCache.sourceContextId(qmltypesFileSourceId)}; SourceContextId qmltypesFileSourceContextId{qmltypesFileSourceId.contextId()};
}; };
TEST_F(QmlTypesParser, imports) TEST_F(QmlTypesParser, imports)

View File

@@ -13,48 +13,44 @@ namespace {
using QmlDesigner::SourceContextId; using QmlDesigner::SourceContextId;
using QmlDesigner::SourceId; using QmlDesigner::SourceId;
using QmlDesigner::SourceIds; using QmlDesigner::SourceIds;
using QmlDesigner::SourceNameId;
using Cache = QmlDesigner::SourcePathCache<NiceMock<ProjectStorageMock>>; using Cache = QmlDesigner::SourcePathCache<NiceMock<ProjectStorageMock>>;
using NFP = QmlDesigner::SourcePath; using NFP = QmlDesigner::SourcePath;
using QmlDesigner::Cache::SourceName;
using QmlDesigner::SourcePathView; using QmlDesigner::SourcePathView;
using QmlDesigner::SourcePathViews; using QmlDesigner::SourcePathViews;
using QmlDesigner::Cache::SourceNameAndSourceContextId;
class SourcePathCache : public testing::Test class SourcePathCache : public testing::Test
{ {
protected: protected:
SourcePathCache() SourcePathCache()
{ {
ON_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))) ON_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).WillByDefault(Return(sourceContextId5));
.WillByDefault(Return(SourceContextId::create(5))); ON_CALL(storageMock, fetchSourceContextId(Eq("/path2/to"))).WillByDefault(Return(sourceContextId6));
ON_CALL(storageMock, fetchSourceContextId(Eq("/path2/to"))) ON_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))).WillByDefault(Return(sourceNameId42));
.WillByDefault(Return(SourceContextId::create(6))); ON_CALL(storageMock, fetchSourceNameId(Eq("file2.cpp"))).WillByDefault(Return(sourceNameId63));
ON_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))) ON_CALL(storageMock, fetchSourceContextPath(sourceContextId5))
.WillByDefault(Return(SourceId::create(42)));
ON_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file2.cpp")))
.WillByDefault(Return(SourceId::create(63)));
ON_CALL(storageMock, fetchSourceId(SourceContextId::create(6), Eq("file.cpp")))
.WillByDefault(Return(SourceId::create(72)));
ON_CALL(storageMock, fetchSourceContextPath(SourceContextId::create(5)))
.WillByDefault(Return(Utils::PathString("/path/to"))); .WillByDefault(Return(Utils::PathString("/path/to")));
ON_CALL(storageMock, fetchSourceNameAndSourceContextId(SourceId::create(42))) ON_CALL(storageMock, fetchSourceName(sourceNameId42)).WillByDefault(Return("file.cpp"));
.WillByDefault( ON_CALL(storageMockFilled, fetchAllSourceNames())
Return(SourceNameAndSourceContextId("file.cpp", SourceContextId::create(5)))); .WillByDefault(Return(std::vector<QmlDesigner::Cache::SourceName>(
ON_CALL(storageMockFilled, fetchAllSources()) {{"file.cpp", sourceNameId42}, {"file2.cpp", sourceNameId63}})));
.WillByDefault(Return(std::vector<QmlDesigner::Cache::Source>({
{"file.cpp", SourceContextId::create(6), SourceId::create(72)},
{"file2.cpp", SourceContextId::create(5), SourceId::create(63)},
{"file.cpp", SourceContextId::create(5), SourceId::create(42)},
})));
ON_CALL(storageMockFilled, fetchAllSourceContexts()) ON_CALL(storageMockFilled, fetchAllSourceContexts())
.WillByDefault(Return(std::vector<QmlDesigner::Cache::SourceContext>( .WillByDefault(Return(std::vector<QmlDesigner::Cache::SourceContext>(
{{"/path2/to", SourceContextId::create(6)}, {"/path/to", SourceContextId::create(5)}}))); {{"/path2/to", sourceContextId6}, {"/path/to", sourceContextId5}})));
ON_CALL(storageMockFilled, fetchSourceContextId(Eq("/path/to"))) ON_CALL(storageMockFilled, fetchSourceContextId(Eq("/path/to")))
.WillByDefault(Return(SourceContextId::create(5))); .WillByDefault(Return(sourceContextId5));
ON_CALL(storageMockFilled, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))) ON_CALL(storageMockFilled, fetchSourceNameId(Eq("file.cpp"))).WillByDefault(Return(sourceNameId42));
.WillByDefault(Return(SourceId::create(42)));
} }
protected: protected:
SourceNameId sourceNameId42 = SourceNameId::create(42);
SourceNameId sourceNameId63 = SourceNameId::create(63);
SourceContextId sourceContextId5 = SourceContextId::create(5);
SourceContextId sourceContextId6 = SourceContextId::create(6);
SourceId sourceId542 = SourceId::create(sourceNameId42, sourceContextId5);
SourceId sourceId563 = SourceId::create(sourceNameId63, sourceContextId5);
SourceId sourceId642 = SourceId::create(sourceNameId42, sourceContextId6);
NiceMock<ProjectStorageMock> storageMock; NiceMock<ProjectStorageMock> storageMock;
Cache cache{storageMock}; Cache cache{storageMock};
NiceMock<ProjectStorageMock> storageMockFilled; NiceMock<ProjectStorageMock> storageMockFilled;
@@ -70,7 +66,7 @@ TEST_F(SourcePathCache, source_id_with_out_any_entry_call_source_context_id)
TEST_F(SourcePathCache, source_id_with_out_any_entry_calls) TEST_F(SourcePathCache, source_id_with_out_any_entry_calls)
{ {
EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))); EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp")));
cache.sourceId(SourcePathView("/path/to/file.cpp")); cache.sourceId(SourcePathView("/path/to/file.cpp"));
} }
@@ -79,7 +75,7 @@ TEST_F(SourcePathCache, source_id_of_source_id_with_out_any_entry)
{ {
auto sourceId = cache.sourceId(SourcePathView("/path/to/file.cpp")); auto sourceId = cache.sourceId(SourcePathView("/path/to/file.cpp"));
ASSERT_THAT(sourceId, SourceId::create(42)); ASSERT_THAT(sourceId, sourceId542);
} }
TEST_F(SourcePathCache, source_id_with_source_context_id_and_source_name) TEST_F(SourcePathCache, source_id_with_source_context_id_and_source_name)
@@ -88,7 +84,7 @@ TEST_F(SourcePathCache, source_id_with_source_context_id_and_source_name)
auto sourceId = cache.sourceId(sourceContextId, "file.cpp"_sv); auto sourceId = cache.sourceId(sourceContextId, "file.cpp"_sv);
ASSERT_THAT(sourceId, SourceId::create(42)); ASSERT_THAT(sourceId, sourceId542);
} }
TEST_F(SourcePathCache, if_entry_exists_dont_call_in_strorage) TEST_F(SourcePathCache, if_entry_exists_dont_call_in_strorage)
@@ -96,7 +92,7 @@ TEST_F(SourcePathCache, if_entry_exists_dont_call_in_strorage)
cache.sourceId(SourcePathView("/path/to/file.cpp")); cache.sourceId(SourcePathView("/path/to/file.cpp"));
EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0);
EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))).Times(0); EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))).Times(0);
cache.sourceId(SourcePathView("/path/to/file.cpp")); cache.sourceId(SourcePathView("/path/to/file.cpp"));
} }
@@ -106,7 +102,7 @@ TEST_F(SourcePathCache, if_directory_entry_exists_dont_call_fetch_source_context
cache.sourceId(SourcePathView("/path/to/file2.cpp")); cache.sourceId(SourcePathView("/path/to/file2.cpp"));
EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0);
EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))); EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp")));
cache.sourceId(SourcePathView("/path/to/file.cpp")); cache.sourceId(SourcePathView("/path/to/file.cpp"));
} }
@@ -117,7 +113,7 @@ TEST_F(SourcePathCache, get_source_id_with_cached_value)
auto sourceId = cache.sourceId(SourcePathView("/path/to/file.cpp")); auto sourceId = cache.sourceId(SourcePathView("/path/to/file.cpp"));
ASSERT_THAT(sourceId, SourceId::create(42)); ASSERT_THAT(sourceId, sourceId542);
} }
TEST_F(SourcePathCache, get_source_id_with_source_context_id_cached) TEST_F(SourcePathCache, get_source_id_with_source_context_id_cached)
@@ -126,7 +122,7 @@ TEST_F(SourcePathCache, get_source_id_with_source_context_id_cached)
auto sourceId = cache.sourceId(SourcePathView("/path/to/file2.cpp")); auto sourceId = cache.sourceId(SourcePathView("/path/to/file2.cpp"));
ASSERT_THAT(sourceId, SourceId::create(63)); ASSERT_THAT(sourceId, sourceId563);
} }
TEST_F(SourcePathCache, throw_for_getting_a_file_path_with_an_invalid_id) TEST_F(SourcePathCache, throw_for_getting_a_file_path_with_an_invalid_id)
@@ -147,9 +143,7 @@ TEST_F(SourcePathCache, get_a_file_path)
TEST_F(SourcePathCache, get_a_file_path_with_cached_source_id) TEST_F(SourcePathCache, get_a_file_path_with_cached_source_id)
{ {
SourceId sourceId{SourceId::create(42)}; auto sourcePath = cache.sourcePath(sourceId542);
auto sourcePath = cache.sourcePath(sourceId);
ASSERT_THAT(sourcePath, Eq(SourcePathView{"/path/to/file.cpp"})); ASSERT_THAT(sourcePath, Eq(SourcePathView{"/path/to/file.cpp"}));
} }
@@ -199,7 +193,7 @@ TEST_F(SourcePathCache, source_context_id)
{ {
auto id = cache.sourceContextId(Utils::SmallString("/path/to")); auto id = cache.sourceContextId(Utils::SmallString("/path/to"));
ASSERT_THAT(id, Eq(SourceContextId::create(5))); ASSERT_THAT(id, Eq(sourceContextId5));
} }
TEST_F(SourcePathCache, source_context_id_is_already_in_cache) TEST_F(SourcePathCache, source_context_id_is_already_in_cache)
@@ -248,7 +242,7 @@ TEST_F(SourcePathCache, throw_for_getting_a_directory_path_with_an_invalid_id)
TEST_F(SourcePathCache, get_a_directory_path) TEST_F(SourcePathCache, get_a_directory_path)
{ {
SourceContextId sourceContextId{SourceContextId::create(5)}; SourceContextId sourceContextId{sourceContextId5};
auto sourceContextPath = cache.sourceContextPath(sourceContextId); auto sourceContextPath = cache.sourceContextPath(sourceContextId);
@@ -257,7 +251,7 @@ TEST_F(SourcePathCache, get_a_directory_path)
TEST_F(SourcePathCache, get_a_directory_path_with_cached_source_context_id) TEST_F(SourcePathCache, get_a_directory_path_with_cached_source_context_id)
{ {
SourceContextId sourceContextId{SourceContextId::create(5)}; SourceContextId sourceContextId{sourceContextId5};
cache.sourceContextPath(sourceContextId); cache.sourceContextPath(sourceContextId);
auto sourceContextPath = cache.sourceContextPath(sourceContextId); auto sourceContextPath = cache.sourceContextPath(sourceContextId);
@@ -267,65 +261,40 @@ TEST_F(SourcePathCache, get_a_directory_path_with_cached_source_context_id)
TEST_F(SourcePathCache, directory_path_calls_fetch_directory_path) TEST_F(SourcePathCache, directory_path_calls_fetch_directory_path)
{ {
EXPECT_CALL(storageMock, fetchSourceContextPath(Eq(SourceContextId::create(5)))); EXPECT_CALL(storageMock, fetchSourceContextPath(Eq(sourceContextId5)));
cache.sourceContextPath(SourceContextId::create(5)); cache.sourceContextPath(sourceContextId5);
} }
TEST_F(SourcePathCache, second_directory_path_calls_not_fetch_directory_path) TEST_F(SourcePathCache, second_directory_path_calls_not_fetch_directory_path)
{ {
cache.sourceContextPath(SourceContextId::create(5)); cache.sourceContextPath(sourceContextId5);
EXPECT_CALL(storageMock, fetchSourceContextPath(_)).Times(0); EXPECT_CALL(storageMock, fetchSourceContextPath(_)).Times(0);
cache.sourceContextPath(SourceContextId::create(5)); cache.sourceContextPath(sourceContextId5);
} }
TEST_F(SourcePathCache, throw_for_getting_a_source_context_id_with_an_invalid_source_id) TEST_F(SourcePathCache, fetch_source_context_from_source_id)
{ {
SourceId sourceId; auto sourceContextId = sourceId542.contextId();
ASSERT_THROW(cache.sourceContextId(sourceId), QmlDesigner::NoSourcePathForInvalidSourceId); ASSERT_THAT(sourceContextId, Eq(sourceContextId5));
}
TEST_F(SourcePathCache, fetch_source_context_id_by_source_id)
{
auto sourceContextId = cache.sourceContextId(SourceId::create(42));
ASSERT_THAT(sourceContextId, Eq(SourceContextId::create(5)));
}
TEST_F(SourcePathCache, fetch_source_context_id_by_source_id_cached)
{
cache.sourceContextId(SourceId::create(42));
auto sourceContextId = cache.sourceContextId(SourceId::create(42));
ASSERT_THAT(sourceContextId, Eq(SourceContextId::create(5)));
}
TEST_F(SourcePathCache, fetch_file_path_after_fetching_source_context_id_by_source_id)
{
cache.sourceContextId(SourceId::create(42));
auto sourcePath = cache.sourcePath(SourceId::create(42));
ASSERT_THAT(sourcePath, Eq("/path/to/file.cpp"));
} }
TEST_F(SourcePathCache, fetch_source_context_id_after_fetching_file_path_by_source_id) TEST_F(SourcePathCache, fetch_source_context_id_after_fetching_file_path_by_source_id)
{ {
cache.sourcePath(SourceId::create(42)); cache.sourcePath(sourceId542);
auto sourceContextId = cache.sourceContextId(SourceId::create(42)); auto sourceContextId = sourceId542.contextId();
ASSERT_THAT(sourceContextId, Eq(SourceContextId::create(5))); ASSERT_THAT(sourceContextId, Eq(sourceContextId5));
} }
TEST_F(SourcePathCache, fetch_all_source_contexts_and_sources_at_creation) TEST_F(SourcePathCache, fetch_all_source_contexts_and_sources_at_creation)
{ {
EXPECT_CALL(storageMock, fetchAllSourceContexts()); EXPECT_CALL(storageMock, fetchAllSourceContexts());
EXPECT_CALL(storageMock, fetchAllSources()); EXPECT_CALL(storageMock, fetchAllSourceNames());
Cache cache{storageMock}; Cache cache{storageMock};
} }
@@ -336,23 +305,23 @@ TEST_F(SourcePathCache, get_file_id_in_filled_cache)
auto id = cacheFilled.sourceId("/path2/to/file.cpp"); auto id = cacheFilled.sourceId("/path2/to/file.cpp");
ASSERT_THAT(id, Eq(SourceId::create(72))); ASSERT_THAT(id, Eq(sourceId642));
} }
TEST_F(SourcePathCache, get_source_context_id_in_filled_cache) TEST_F(SourcePathCache, get_source_context_id_in_filled_cache)
{ {
Cache cacheFilled{storageMockFilled}; Cache cacheFilled{storageMockFilled};
auto id = cacheFilled.sourceContextId(SourceId::create(42)); auto id = sourceId542.contextId();
ASSERT_THAT(id, Eq(SourceContextId::create(5))); ASSERT_THAT(id, Eq(sourceContextId5));
} }
TEST_F(SourcePathCache, get_directory_path_in_filled_cache) TEST_F(SourcePathCache, get_directory_path_in_filled_cache)
{ {
Cache cacheFilled{storageMockFilled}; Cache cacheFilled{storageMockFilled};
auto path = cacheFilled.sourceContextPath(SourceContextId::create(5)); auto path = cacheFilled.sourceContextPath(sourceContextId5);
ASSERT_THAT(path, Eq("/path/to")); ASSERT_THAT(path, Eq("/path/to"));
} }
@@ -361,7 +330,7 @@ TEST_F(SourcePathCache, get_file_path_in_filled_cache)
{ {
Cache cacheFilled{storageMockFilled}; Cache cacheFilled{storageMockFilled};
auto path = cacheFilled.sourcePath(SourceId::create(42)); auto path = cacheFilled.sourcePath(sourceId542);
ASSERT_THAT(path, Eq("/path/to/file.cpp")); ASSERT_THAT(path, Eq("/path/to/file.cpp"));
} }
@@ -372,7 +341,7 @@ TEST_F(SourcePathCache, get_file_id_in_after_populate_if_empty)
auto id = cacheNotFilled.sourceId("/path2/to/file.cpp"); auto id = cacheNotFilled.sourceId("/path2/to/file.cpp");
ASSERT_THAT(id, Eq(SourceId::create(72))); ASSERT_THAT(id, Eq(sourceId642));
} }
TEST_F(SourcePathCache, dont_populate_if_not_empty) TEST_F(SourcePathCache, dont_populate_if_not_empty)
@@ -380,25 +349,16 @@ TEST_F(SourcePathCache, dont_populate_if_not_empty)
cacheNotFilled.sourceId("/path/to/file.cpp"); cacheNotFilled.sourceId("/path/to/file.cpp");
EXPECT_CALL(storageMockFilled, fetchAllSourceContexts()).Times(0); EXPECT_CALL(storageMockFilled, fetchAllSourceContexts()).Times(0);
EXPECT_CALL(storageMockFilled, fetchAllSources()).Times(0); EXPECT_CALL(storageMockFilled, fetchAllSourceNames()).Times(0);
cacheNotFilled.populateIfEmpty(); cacheNotFilled.populateIfEmpty();
} }
TEST_F(SourcePathCache, get_source_context_id_after_populate_if_empty)
{
cacheNotFilled.populateIfEmpty();
auto id = cacheNotFilled.sourceContextId(SourceId::create(42));
ASSERT_THAT(id, Eq(SourceContextId::create(5)));
}
TEST_F(SourcePathCache, get_directory_path_after_populate_if_empty) TEST_F(SourcePathCache, get_directory_path_after_populate_if_empty)
{ {
cacheNotFilled.populateIfEmpty(); cacheNotFilled.populateIfEmpty();
auto path = cacheNotFilled.sourceContextPath(SourceContextId::create(5)); auto path = cacheNotFilled.sourceContextPath(sourceContextId5);
ASSERT_THAT(path, Eq("/path/to")); ASSERT_THAT(path, Eq("/path/to"));
} }
@@ -407,7 +367,7 @@ TEST_F(SourcePathCache, get_file_path_after_populate_if_empty)
{ {
cacheNotFilled.populateIfEmpty(); cacheNotFilled.populateIfEmpty();
auto path = cacheNotFilled.sourcePath(SourceId::create(42)); auto path = cacheNotFilled.sourcePath(sourceId542);
ASSERT_THAT(path, Eq("/path/to/file.cpp")); ASSERT_THAT(path, Eq("/path/to/file.cpp"));
} }
@@ -421,17 +381,18 @@ TEST_F(SourcePathCache, source_context_and_source_id_with_out_any_entry_call_sou
TEST_F(SourcePathCache, source_context_and_source_id_with_out_any_entry_calls) TEST_F(SourcePathCache, source_context_and_source_id_with_out_any_entry_calls)
{ {
EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))); EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp")));
cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp"));
} }
TEST_F(SourcePathCache, source_context_and_source_id_of_source_id_with_out_any_entry) TEST_F(SourcePathCache, source_context_and_source_id_of_source_id_with_out_any_entry)
{ {
auto sourceContextAndSourceId = cache.sourceContextAndSourceId( SourcePathView path("/path/to/file.cpp");
SourcePathView("/path/to/file.cpp"));
ASSERT_THAT(sourceContextAndSourceId, Pair(SourceContextId::create(5), SourceId::create(42))); auto sourceId = cache.sourceId(path);
ASSERT_THAT(sourceId.contextId(), sourceContextId5);
} }
TEST_F(SourcePathCache, source_context_and_source_id_if_entry_exists_dont_call_in_strorage) TEST_F(SourcePathCache, source_context_and_source_id_if_entry_exists_dont_call_in_strorage)
@@ -439,7 +400,7 @@ TEST_F(SourcePathCache, source_context_and_source_id_if_entry_exists_dont_call_i
cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp"));
EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0);
EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))).Times(0); EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp"))).Times(0);
cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp"));
} }
@@ -450,7 +411,7 @@ TEST_F(SourcePathCache,
cache.sourceContextAndSourceId(SourcePathView("/path/to/file2.cpp")); cache.sourceContextAndSourceId(SourcePathView("/path/to/file2.cpp"));
EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0); EXPECT_CALL(storageMock, fetchSourceContextId(Eq("/path/to"))).Times(0);
EXPECT_CALL(storageMock, fetchSourceId(SourceContextId::create(5), Eq("file.cpp"))); EXPECT_CALL(storageMock, fetchSourceNameId(Eq("file.cpp")));
cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp"));
} }
@@ -461,7 +422,7 @@ TEST_F(SourcePathCache, source_context_and_source_id_get_source_id_with_cached_v
auto sourceId = cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp")); auto sourceId = cache.sourceContextAndSourceId(SourcePathView("/path/to/file.cpp"));
ASSERT_THAT(sourceId, Pair(SourceContextId::create(5), SourceId::create(42))); ASSERT_THAT(sourceId, Pair(sourceContextId5, sourceId542));
} }
TEST_F(SourcePathCache, get_source_context_and_source_id_with_source_context_id_cached) TEST_F(SourcePathCache, get_source_context_and_source_id_with_source_context_id_cached)
@@ -471,7 +432,7 @@ TEST_F(SourcePathCache, get_source_context_and_source_id_with_source_context_id_
auto sourceContextAndSourceId = cache.sourceContextAndSourceId( auto sourceContextAndSourceId = cache.sourceContextAndSourceId(
SourcePathView("/path/to/file2.cpp")); SourcePathView("/path/to/file2.cpp"));
ASSERT_THAT(sourceContextAndSourceId, Pair(SourceContextId::create(5), SourceId::create(63))); ASSERT_THAT(sourceContextAndSourceId, Pair(sourceContextId5, sourceId563));
} }
TEST_F(SourcePathCache, get_source_context_and_source_id_file_names_are_unique_for_every_directory) TEST_F(SourcePathCache, get_source_context_and_source_id_file_names_are_unique_for_every_directory)

View File

@@ -33,10 +33,13 @@ using Sqlite::ReadWriteStatement;
using Sqlite::Value; using Sqlite::Value;
using Sqlite::WriteStatement; using Sqlite::WriteStatement;
enum class BasicIdEnumeration { TestId }; enum class BasicIdEnumeration { TestId, TestId2 };
using TestLongLongId = Sqlite::BasicId<BasicIdEnumeration::TestId, long long>; using TestLongLongId = Sqlite::BasicId<BasicIdEnumeration::TestId, long long>;
using TestIntId = Sqlite::BasicId<BasicIdEnumeration::TestId, int>; using TestIntId = Sqlite::BasicId<BasicIdEnumeration::TestId, int>;
using TestIntId2 = Sqlite::BasicId<BasicIdEnumeration::TestId2, int>;
using CompoundId = Sqlite::CompoundBasicId<BasicIdEnumeration::TestId, BasicIdEnumeration::TestId2>;
template<typename Type> template<typename Type>
bool compareValue(SqliteTestStatement<2, 1> &statement, Type value, int column) bool compareValue(SqliteTestStatement<2, 1> &statement, Type value, int column)
@@ -255,6 +258,19 @@ TEST_F(SqliteStatement, bind_invalid_int_id_to_null)
ASSERT_THAT(readStatement.fetchType(0), Sqlite::Type::Null); ASSERT_THAT(readStatement.fetchType(0), Sqlite::Type::Null);
} }
TEST_F(SqliteStatement, bind_invalid_compound_id_to_null)
{
CompoundId id;
SqliteTestStatement<0, 1> statement("INSERT INTO test VALUES ('id', 323, ?)", database);
statement.bind(1, id);
statement.next();
SqliteTestStatement<1, 1> readStatement("SELECT value FROM test WHERE name='id'", database);
readStatement.next();
ASSERT_THAT(readStatement.fetchType(0), Sqlite::Type::Null);
}
TEST_F(SqliteStatement, bind_int_id) TEST_F(SqliteStatement, bind_int_id)
{ {
TestIntId id{TestIntId::create(42)}; TestIntId id{TestIntId::create(42)};
@@ -269,6 +285,20 @@ TEST_F(SqliteStatement, bind_int_id)
ASSERT_THAT(readStatement.fetchIntValue(0), 42); ASSERT_THAT(readStatement.fetchIntValue(0), 42);
} }
TEST_F(SqliteStatement, bind_compound_id)
{
CompoundId id = CompoundId::create(42);
SqliteTestStatement<0, 1> statement("INSERT INTO test VALUES ('id', 323, ?)", database);
statement.bind(1, id);
statement.next();
SqliteTestStatement<1, 1> readStatement("SELECT value FROM test WHERE name='id'", database);
readStatement.next();
ASSERT_THAT(readStatement.fetchType(0), Sqlite::Type::Integer);
ASSERT_THAT(readStatement.fetchIntValue(0), 42);
}
TEST_F(SqliteStatement, bind_special_state_id) TEST_F(SqliteStatement, bind_special_state_id)
{ {
enum class SpecialIdState { Unresolved = -1 }; enum class SpecialIdState { Unresolved = -1 };
@@ -1271,6 +1301,30 @@ TEST_F(SqliteStatement, get_single_int_id)
ASSERT_THAT(value.internalId(), Eq(42)); ASSERT_THAT(value.internalId(), Eq(42));
} }
TEST_F(SqliteStatement, get_single_invalid_compound_id)
{
CompoundId id;
WriteStatement<1>("INSERT INTO test VALUES ('id', 323, ?)", database).write(id);
ReadStatement<1, 0> statement("SELECT value FROM test WHERE name='id'", database);
auto value = statement.value<CompoundId>();
ASSERT_FALSE(value.isValid());
}
TEST_F(SqliteStatement, get_single_compound_id)
{
TestIntId testId = TestIntId::create(42);
TestIntId2 testId2 = TestIntId2::create(23);
CompoundId id = CompoundId::create(testId, testId2);
WriteStatement<1>("INSERT INTO test VALUES ('id', 323, ?)", database).write(id);
ReadStatement<1, 0> statement("SELECT value FROM test WHERE name='id'", database);
auto value = statement.value<CompoundId>();
ASSERT_THAT(value, Eq(id));
}
TEST_F(SqliteStatement, get_value_calls_reset) TEST_F(SqliteStatement, get_value_calls_reset)
{ {
struct Value struct Value