forked from qt-creator/qt-creator
ClangRefactoring: Make the indexer more robust
We check now if the database is busy. This should not be happen but better be careful. Change-Id: I8b667ff183368977991974ea1fe7fcde837e968a Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -91,12 +91,31 @@ void SymbolIndexer::updateProjectParts(ProjectPartContainers &&projectParts)
|
|||||||
updateProjectPart(std::move(projectPart));
|
updateProjectPart(std::move(projectPart));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void store(SymbolStorageInterface &symbolStorage,
|
||||||
|
BuildDependenciesStorageInterface &buildDependencyStorage,
|
||||||
|
Sqlite::TransactionInterface &transactionInterface,
|
||||||
|
SymbolsCollectorInterface &symbolsCollector)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Sqlite::ImmediateTransaction transaction{transactionInterface};
|
||||||
|
buildDependencyStorage.insertOrUpdateIndexingTimeStamps(symbolsCollector.fileStatuses());
|
||||||
|
symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
||||||
|
symbolsCollector.sourceLocations());
|
||||||
|
transaction.commit();
|
||||||
|
} catch (const Sqlite::StatementIsBusy &) {
|
||||||
|
store(symbolStorage, buildDependencyStorage, transactionInterface, symbolsCollector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
||||||
{
|
{
|
||||||
ProjectPartId projectPartId = projectPart.projectPartId;
|
ProjectPartId projectPartId = projectPart.projectPartId;
|
||||||
|
|
||||||
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
std::vector<SymbolIndexerTask> symbolIndexerTask;
|
||||||
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
|
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
|
||||||
|
|
||||||
for (FilePathId sourcePathId : projectPart.sourcePathIds) {
|
for (FilePathId sourcePathId : projectPart.sourcePathIds) {
|
||||||
SourceTimeStamps dependentTimeStamps = m_buildDependencyStorage.fetchIncludedIndexingTimeStamps(
|
SourceTimeStamps dependentTimeStamps = m_buildDependencyStorage.fetchIncludedIndexingTimeStamps(
|
||||||
sourcePathId);
|
sourcePathId);
|
||||||
@@ -117,27 +136,28 @@ void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
|
|||||||
preIncludeSearchPath};
|
preIncludeSearchPath};
|
||||||
symbolsCollector.setFile(sourcePathId, commandLineBuilder.commandLine);
|
symbolsCollector.setFile(sourcePathId, commandLineBuilder.commandLine);
|
||||||
|
|
||||||
return symbolsCollector.collectSymbols();
|
|
||||||
};
|
|
||||||
|
|
||||||
auto store = [&] {
|
return symbolsCollector.collectSymbols();
|
||||||
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
|
||||||
m_buildDependencyStorage.insertOrUpdateIndexingTimeStamps(
|
|
||||||
symbolsCollector.fileStatuses());
|
|
||||||
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
|
||||||
symbolsCollector.sourceLocations());
|
|
||||||
transaction.commit();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const PchPaths pchPaths = m_precompiledHeaderStorage.fetchPrecompiledHeaders(
|
const PchPaths pchPaths = m_precompiledHeaderStorage.fetchPrecompiledHeaders(
|
||||||
projectPart.projectPartId);
|
projectPart.projectPartId);
|
||||||
|
|
||||||
if (pchPaths.projectPchPath.size() && collect(pchPaths.projectPchPath)) {
|
if (pchPaths.projectPchPath.size() && collect(pchPaths.projectPchPath)) {
|
||||||
store();
|
store(m_symbolStorage,
|
||||||
|
m_buildDependencyStorage,
|
||||||
|
m_transactionInterface,
|
||||||
|
symbolsCollector);
|
||||||
} else if (pchPaths.systemPchPath.size() && collect(pchPaths.systemPchPath)) {
|
} else if (pchPaths.systemPchPath.size() && collect(pchPaths.systemPchPath)) {
|
||||||
store();
|
store(m_symbolStorage,
|
||||||
|
m_buildDependencyStorage,
|
||||||
|
m_transactionInterface,
|
||||||
|
symbolsCollector);
|
||||||
} else if (collect({})) {
|
} else if (collect({})) {
|
||||||
store();
|
store(m_symbolStorage,
|
||||||
|
m_buildDependencyStorage,
|
||||||
|
m_transactionInterface,
|
||||||
|
symbolsCollector);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -196,23 +216,15 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
|
|||||||
return symbolsCollector.collectSymbols();
|
return symbolsCollector.collectSymbols();
|
||||||
};
|
};
|
||||||
|
|
||||||
auto store = [&] {
|
|
||||||
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
|
|
||||||
m_buildDependencyStorage.insertOrUpdateIndexingTimeStamps(symbolsCollector.fileStatuses());
|
|
||||||
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
|
|
||||||
symbolsCollector.sourceLocations());
|
|
||||||
transaction.commit();
|
|
||||||
};
|
|
||||||
|
|
||||||
const PchPaths pchPaths = m_precompiledHeaderStorage.fetchPrecompiledHeaders(
|
const PchPaths pchPaths = m_precompiledHeaderStorage.fetchPrecompiledHeaders(
|
||||||
optionalArtefact->projectPartId);
|
optionalArtefact->projectPartId);
|
||||||
|
|
||||||
if (pchPaths.projectPchPath.size() && collect(pchPaths.projectPchPath)) {
|
if (pchPaths.projectPchPath.size() && collect(pchPaths.projectPchPath)) {
|
||||||
store();
|
store(m_symbolStorage, m_buildDependencyStorage, m_transactionInterface, symbolsCollector);
|
||||||
} else if (pchPaths.systemPchPath.size() && collect(pchPaths.systemPchPath)) {
|
} else if (pchPaths.systemPchPath.size() && collect(pchPaths.systemPchPath)) {
|
||||||
store();
|
store(m_symbolStorage, m_buildDependencyStorage, m_transactionInterface, symbolsCollector);
|
||||||
} else if (collect({})) {
|
} else if (collect({})) {
|
||||||
store();
|
store(m_symbolStorage, m_buildDependencyStorage, m_transactionInterface, symbolsCollector);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,10 @@
|
|||||||
|
|
||||||
#include <filepathcaching.h>
|
#include <filepathcaching.h>
|
||||||
#include <filestatuscache.h>
|
#include <filestatuscache.h>
|
||||||
|
#include <processormanager.h>
|
||||||
#include <projectpartcontainer.h>
|
#include <projectpartcontainer.h>
|
||||||
#include <refactoringdatabaseinitializer.h>
|
#include <refactoringdatabaseinitializer.h>
|
||||||
#include <processormanager.h>
|
#include <sqliteexception.h>
|
||||||
#include <symbolindexer.h>
|
#include <symbolindexer.h>
|
||||||
#include <symbolindexertaskqueue.h>
|
#include <symbolindexertaskqueue.h>
|
||||||
#include <taskscheduler.h>
|
#include <taskscheduler.h>
|
||||||
@@ -868,29 +869,29 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsGetsNoPchPathsAndHasErrors)
|
|||||||
TEST_F(SymbolIndexer, UpdateProjectPartsFetchIncludedIndexingTimeStamps)
|
TEST_F(SymbolIndexer, UpdateProjectPartsFetchIncludedIndexingTimeStamps)
|
||||||
{
|
{
|
||||||
InSequence s;
|
InSequence s;
|
||||||
ProjectPartContainer projectPart{1,
|
|
||||||
{"-Wno-pragma-once-outside-header"},
|
|
||||||
{{"BAR", "1", 1}, {"FOO", "1", 2}},
|
|
||||||
Utils::clone(systemIncludeSearchPaths),
|
|
||||||
Utils::clone(projectIncludeSearchPaths),
|
|
||||||
{header1PathId},
|
|
||||||
{main1PathId, main2PathId},
|
|
||||||
Utils::Language::Cxx,
|
|
||||||
Utils::LanguageVersion::CXX14,
|
|
||||||
Utils::LanguageExtension::None};
|
|
||||||
|
|
||||||
EXPECT_CALL(mockBuildDependenciesStorage, fetchIncludedIndexingTimeStamps(Eq(main1PathId)))
|
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
|
||||||
.WillOnce(Return(dependentSourceTimeStamps1));
|
|
||||||
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps1));
|
|
||||||
EXPECT_CALL(mockBuildDependenciesStorage, fetchIncludedIndexingTimeStamps(Eq(main2PathId)))
|
|
||||||
.WillOnce(Return(dependentSourceTimeStamps2));
|
|
||||||
EXPECT_CALL(mockModifiedTimeChecker, isUpToDate(dependentSourceTimeStamps2));
|
|
||||||
EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses1));
|
EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses1));
|
||||||
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(fileStatuses1));
|
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(_));
|
||||||
EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses2));
|
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(_, _));
|
||||||
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(fileStatuses2));
|
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||||
|
|
||||||
indexer.updateProjectParts({projectPart});
|
indexer.updateProjectParts({projectPart1});
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SymbolIndexer, UpdateProjectPartsIsBusyInStoringData)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin())
|
||||||
|
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
||||||
|
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
|
||||||
|
EXPECT_CALL(mockCollector, fileStatuses()).WillRepeatedly(ReturnRef(fileStatuses1));
|
||||||
|
EXPECT_CALL(mockBuildDependenciesStorage, insertOrUpdateIndexingTimeStamps(_));
|
||||||
|
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(_, _));
|
||||||
|
EXPECT_CALL(mockSqliteTransactionBackend, commit());
|
||||||
|
|
||||||
|
indexer.updateProjectParts({projectPart1});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(SymbolIndexer, DependentSourceAreNotUpToDate)
|
TEST_F(SymbolIndexer, DependentSourceAreNotUpToDate)
|
||||||
|
|||||||
Reference in New Issue
Block a user