forked from qt-creator/qt-creator
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:
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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!";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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>)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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()};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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)};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user