forked from qt-creator/qt-creator
Clang: Add fetchTimeStamps to PrecompiledHeaderStorage
Change-Id: I75552a971fbc39a81e14e3b9ec0c5125d3858025 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -59,6 +59,19 @@ public:
|
||||
int64 value = -1;
|
||||
};
|
||||
|
||||
class PrecompiledHeaderTimeStamps
|
||||
{
|
||||
public:
|
||||
PrecompiledHeaderTimeStamps() = default;
|
||||
PrecompiledHeaderTimeStamps(long long projectTimeStamp, long long systemTimeStamp)
|
||||
: project(projectTimeStamp)
|
||||
, system(systemTimeStamp)
|
||||
{}
|
||||
|
||||
TimeStamp project;
|
||||
TimeStamp system;
|
||||
};
|
||||
|
||||
class SourceTimeStamp
|
||||
{
|
||||
using int64 = long long;
|
||||
|
@@ -182,6 +182,26 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
PrecompiledHeaderTimeStamps fetchTimeStamps(ProjectPartId projectPartId) const override
|
||||
{
|
||||
try {
|
||||
Sqlite::DeferredTransaction transaction{database};
|
||||
|
||||
auto value = fetchTimeStampsStatement.template value<PrecompiledHeaderTimeStamps, 2>(
|
||||
projectPartId.projectPathId);
|
||||
|
||||
transaction.commit();
|
||||
|
||||
if (value)
|
||||
return *value;
|
||||
|
||||
} catch (const Sqlite::StatementIsBusy) {
|
||||
return fetchTimeStamps(projectPartId);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
|
||||
Database &database;
|
||||
@@ -216,6 +236,10 @@ public:
|
||||
mutable ReadStatement fetchPrecompiledHeadersStatement{
|
||||
"SELECT projectPchPath, systemPchPath FROM precompiledHeaders WHERE projectPartId = ?",
|
||||
database};
|
||||
mutable ReadStatement fetchTimeStampsStatement{
|
||||
"SELECT projectPchBuildTime, systemPchBuildTime FROM precompiledHeaders WHERE "
|
||||
"projectPartId = ?",
|
||||
database};
|
||||
};
|
||||
|
||||
}
|
||||
|
@@ -58,6 +58,7 @@ public:
|
||||
virtual FilePath fetchSystemPrecompiledHeaderPath(ProjectPartId projectPartId) = 0;
|
||||
virtual FilePath fetchPrecompiledHeader(ProjectPartId projectPartId) const = 0;
|
||||
virtual PchPaths fetchPrecompiledHeaders(ProjectPartId projectPartId) const = 0;
|
||||
virtual PrecompiledHeaderTimeStamps fetchTimeStamps(ProjectPartId projectPartId) const = 0;
|
||||
|
||||
protected:
|
||||
~PrecompiledHeaderStorageInterface() = default;
|
||||
|
@@ -52,4 +52,7 @@ public:
|
||||
ClangBackEnd::FilePath(ClangBackEnd::ProjectPartId projectPartId));
|
||||
MOCK_CONST_METHOD1(fetchPrecompiledHeaders,
|
||||
ClangBackEnd::PchPaths(ClangBackEnd::ProjectPartId projectPartId));
|
||||
MOCK_CONST_METHOD1(
|
||||
fetchTimeStamps,
|
||||
ClangBackEnd::PrecompiledHeaderTimeStamps(ClangBackEnd::ProjectPartId projectPartId));
|
||||
};
|
||||
|
@@ -253,3 +253,10 @@ MockSqliteReadStatement::value<Sources::SourceNameAndDirectoryId, 2>(const int &
|
||||
{
|
||||
return valueReturnSourceNameAndDirectoryId(id);
|
||||
}
|
||||
|
||||
template<>
|
||||
Utils::optional<ClangBackEnd::PrecompiledHeaderTimeStamps>
|
||||
MockSqliteReadStatement::value<ClangBackEnd::PrecompiledHeaderTimeStamps, 2>(const int &projectPartId)
|
||||
{
|
||||
return valuesReturnPrecompiledHeaderTimeStamps(projectPartId);
|
||||
}
|
||||
|
@@ -57,9 +57,10 @@ using ClangRefactoring::SourceLocation;
|
||||
using ClangRefactoring::SourceLocations;
|
||||
using std::int64_t;
|
||||
namespace Sources = ClangBackEnd::Sources;
|
||||
using ClangBackEnd::PrecompiledHeaderTimeStamps;
|
||||
using ClangBackEnd::UsedMacros;
|
||||
using ClangRefactoring::Symbol;
|
||||
using ClangRefactoring::Symbols;
|
||||
using ClangBackEnd::UsedMacros;
|
||||
|
||||
class MockSqliteDatabase;
|
||||
|
||||
@@ -142,9 +143,10 @@ public:
|
||||
MOCK_METHOD1(valuesReturnSourceTimeStamps, SourceTimeStamps(std::size_t));
|
||||
MOCK_METHOD2(valuesReturnSourceTimeStamps, SourceTimeStamps(std::size_t, int sourcePathId));
|
||||
|
||||
template <typename ResultType,
|
||||
int ResultTypeCount = 1,
|
||||
typename... QueryType>
|
||||
MOCK_METHOD1(valuesReturnPrecompiledHeaderTimeStamps,
|
||||
PrecompiledHeaderTimeStamps(int projectPartId));
|
||||
|
||||
template<typename ResultType, int ResultTypeCount = 1, typename... QueryType>
|
||||
std::vector<ResultType> values(std::size_t reserveSize, const QueryType &... queryValues);
|
||||
|
||||
template <typename ResultType,
|
||||
@@ -306,3 +308,7 @@ SourceTimeStamps MockSqliteReadStatement::values<SourceTimeStamp, 2>(std::size_t
|
||||
template <>
|
||||
Utils::optional<Sources::SourceNameAndDirectoryId>
|
||||
MockSqliteReadStatement::value<Sources::SourceNameAndDirectoryId, 2>(const int&);
|
||||
|
||||
template<>
|
||||
Utils::optional<ClangBackEnd::PrecompiledHeaderTimeStamps>
|
||||
MockSqliteReadStatement::value<ClangBackEnd::PrecompiledHeaderTimeStamps, 2>(const int &);
|
||||
|
@@ -51,6 +51,7 @@ protected:
|
||||
MockSqliteReadStatement &fetchSystemPrecompiledHeaderPathStatement = storage.fetchSystemPrecompiledHeaderPathStatement;
|
||||
MockSqliteReadStatement &fetchPrecompiledHeaderStatement = storage.fetchPrecompiledHeaderStatement;
|
||||
MockSqliteReadStatement &fetchPrecompiledHeadersStatement = storage.fetchPrecompiledHeadersStatement;
|
||||
MockSqliteReadStatement &fetchTimeStampsStatement = storage.fetchTimeStampsStatement;
|
||||
};
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, UseTransaction)
|
||||
@@ -339,4 +340,72 @@ TEST_F(PrecompiledHeaderStorage, FetchEmptyPrecompiledHeaders)
|
||||
Field(&ClangBackEnd::PchPaths::systemPchPath, IsEmpty())));
|
||||
}
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, FetchTimeStamps)
|
||||
{
|
||||
ClangBackEnd::PrecompiledHeaderTimeStamps precompiledHeaderTimeStamps{22, 33};
|
||||
ON_CALL(fetchTimeStampsStatement, valuesReturnPrecompiledHeaderTimeStamps(Eq(23)))
|
||||
.WillByDefault(Return(precompiledHeaderTimeStamps));
|
||||
|
||||
auto timeStamps = storage.fetchTimeStamps(23);
|
||||
|
||||
ASSERT_THAT(timeStamps,
|
||||
AllOf(Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::project, Eq(22)),
|
||||
Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::system, Eq(33))));
|
||||
}
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, NoFetchTimeStamps)
|
||||
{
|
||||
auto timeStamps = storage.fetchTimeStamps(23);
|
||||
|
||||
ASSERT_THAT(timeStamps,
|
||||
AllOf(Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::project, Eq(-1)),
|
||||
Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::system, Eq(-1))));
|
||||
}
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, FetchTimeStampsCalls)
|
||||
{
|
||||
InSequence s;
|
||||
|
||||
EXPECT_CALL(database, deferredBegin());
|
||||
EXPECT_CALL(fetchTimeStampsStatement, valuesReturnPrecompiledHeaderTimeStamps(Eq(23)));
|
||||
EXPECT_CALL(database, commit());
|
||||
|
||||
storage.fetchTimeStamps(23);
|
||||
}
|
||||
|
||||
TEST_F(PrecompiledHeaderStorage, FetchTimeStampsBusy)
|
||||
{
|
||||
InSequence s;
|
||||
|
||||
EXPECT_CALL(database, deferredBegin());
|
||||
EXPECT_CALL(fetchTimeStampsStatement, valuesReturnPrecompiledHeaderTimeStamps(Eq(23)))
|
||||
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
||||
EXPECT_CALL(database, rollback());
|
||||
EXPECT_CALL(database, deferredBegin());
|
||||
EXPECT_CALL(fetchTimeStampsStatement, valuesReturnPrecompiledHeaderTimeStamps(Eq(23)));
|
||||
EXPECT_CALL(database, commit());
|
||||
|
||||
storage.fetchTimeStamps(23);
|
||||
}
|
||||
|
||||
class PrecompiledHeaderStorageSlowTest : public testing::Test
|
||||
{
|
||||
protected:
|
||||
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
||||
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
|
||||
ClangBackEnd::PrecompiledHeaderStorage<> storage{database};
|
||||
};
|
||||
|
||||
TEST_F(PrecompiledHeaderStorageSlowTest, NoFetchTimeStamps)
|
||||
{
|
||||
storage.insertProjectPrecompiledHeader(23, {}, 22);
|
||||
storage.insertSystemPrecompiledHeaders({23}, {}, 33);
|
||||
|
||||
auto timeStamps = storage.fetchTimeStamps(23);
|
||||
|
||||
ASSERT_THAT(timeStamps,
|
||||
AllOf(Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::project, Eq(22)),
|
||||
Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::system, Eq(33))));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
Reference in New Issue
Block a user