diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 18b97501..f88947fa 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -181,7 +181,7 @@ void CodeController::handleMessage(MessageChangeFileView* message) std::shared_ptr textAccess = m_storageAccess->getFileContent(message->filePath); params.code = textAccess->getText(); - params.modificationTime = m_storageAccess->getFileModificationTime(message->filePath); + params.modificationTime = m_storageAccess->getFileInfoForFilePath(message->filePath).lastWriteTime; if (message->showErrors) { @@ -326,7 +326,6 @@ std::vector CodeController::getSnippetsForActiveTokenLocation CodeSnippetParams params; params.locationFile = file; params.refCount = file->getUnscopedStartTokenLocationCount(); - params.modificationTime = m_storageAccess->getFileModificationTime(file->getFilePath()); params.isCollapsed = true; snippets.push_back(params); @@ -341,6 +340,8 @@ std::vector CodeController::getSnippetsForActiveTokenLocation std::sort(snippets.begin(), snippets.end(), CodeSnippetParams::sort); + addModificationTimes(snippets); + return snippets; } @@ -425,7 +426,6 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt } const int snippetExpandRange = ApplicationSettings::getInstance()->getCodeSnippetExpandRange(); - TimePoint fileModificationTime = m_storageAccess->getFileModificationTime(activeTokenLocations->getFilePath()); std::vector snippets; for (const SnippetMerger::Range& range: ranges) { @@ -434,7 +434,6 @@ std::vector CodeController::getSnippetsForFile(std::shared_pt params.refCount = activeTokenLocations->getUnscopedStartTokenLocationCount(); params.startLineNumber = std::max(1, range.start.row - (range.start.strong ? 0 : snippetExpandRange)); params.endLineNumber = std::min(textAccess->getLineCount(), range.end.row + (range.end.strong ? 0 : snippetExpandRange)); - params.modificationTime = fileModificationTime; std::shared_ptr tempFile = m_storageAccess->getTokenLocationsForLinesInFile(activeTokenLocations->getFilePath().str(), params.startLineNumber, params.endLineNumber); @@ -585,7 +584,6 @@ std::vector CodeController::getSnippetsForErrorLocations( CodeSnippetParams params; params.locationFile = file; params.refCount = file->getUnscopedStartTokenLocationCount(); - params.modificationTime = m_storageAccess->getFileModificationTime(file->getFilePath()); params.isCollapsed = true; snippets.push_back(params); @@ -593,6 +591,8 @@ std::vector CodeController::getSnippetsForErrorLocations( } ); + addModificationTimes(snippets); + return snippets; } @@ -651,3 +651,24 @@ std::vector CodeController::getProjectDescription(TokenLocationFile return lines; } + +void CodeController::addModificationTimes(std::vector& snippets) const +{ + std::vector filePaths; + for (const CodeSnippetParams& snippet : snippets) + { + filePaths.push_back(snippet.locationFile->getFilePath()); + } + std::vector fileInfos = m_storageAccess->getFileInfosForFilePaths(filePaths); + + std::map fileInfoMap; + for (FileInfo& fileInfo : fileInfos) + { + fileInfoMap.emplace(fileInfo.path, fileInfo); + } + + for (CodeSnippetParams& snippet : snippets) + { + snippet.modificationTime = fileInfoMap[snippet.locationFile->getFilePath()].lastWriteTime; + } +} diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index d43ed736..a77d4b62 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -74,6 +74,8 @@ private: std::vector getProjectDescription(TokenLocationFile* locationFile) const; + void addModificationTimes(std::vector& snippets) const; + StorageAccess* m_storageAccess; }; diff --git a/src/lib/data/SqliteStorage.cpp b/src/lib/data/SqliteStorage.cpp index 7d704fdd..e5686f88 100644 --- a/src/lib/data/SqliteStorage.cpp +++ b/src/lib/data/SqliteStorage.cpp @@ -270,7 +270,7 @@ StorageNode SqliteStorage::getFirstNode() const return nodes[0]; } - return StorageNode(0, 0, "", definitionTypeToInt(DEFINITION_NONE)); + return StorageNode(); } std::vector SqliteStorage::getAllNodes() const @@ -422,7 +422,7 @@ StorageNode SqliteStorage::getNodeById(Id id) const { return getFirstNode("WHERE id == " + std::to_string(id)); } - return StorageNode(0, 0, "", definitionTypeToInt(DEFINITION_NONE)); + return StorageNode(); } StorageNode SqliteStorage::getNodeBySerializedName(const std::string& serializedName) const @@ -455,19 +455,24 @@ StorageFile SqliteStorage::getFileById(const Id id) const ); } -StorageFile SqliteStorage::getFileByPath(const std::string& filePath) const +StorageFile SqliteStorage::getFileByPath(const FilePath& filePath) const { StorageFile storageFile = getFirstFile( "SELECT node.id, node.serialized_name, file.path, file.modification_time FROM node INNER JOIN file ON node.id = file.id " - "WHERE file.path == '" + filePath + "';" + "WHERE file.path == '" + filePath.str() + "';" ); return storageFile; } +std::vector SqliteStorage::getFilesByPaths(const std::vector& filePaths) const +{ + return getAllFiles("WHERE file.path IN ('" + utility::join(utility::toStrings(filePaths), "', '") + "')"); +} + std::vector SqliteStorage::getAllFiles() const { - return getAllFiles("SELECT file.id, node.serialized_name, file.path, file.modification_time FROM file INNER JOIN node ON file.id = node.id;"); + return getAllFiles(""); } std::shared_ptr SqliteStorage::getFileContentByPath(const std::string& filePath) const @@ -909,10 +914,12 @@ StorageFile SqliteStorage::getFirstFile(const std::string& query) const std::vector SqliteStorage::getAllFiles(const std::string& query) const { + CppSQLite3Query q = m_database.execQuery(( + "SELECT file.id, node.serialized_name, file.path, file.modification_time FROM file " + "INNER JOIN node ON file.id = node.id " + query + ";" + ).c_str()); + std::vector files; - - CppSQLite3Query q = m_database.execQuery(query.c_str()); - while (!q.eof()) { const Id id = q.getIntField(0, 0); @@ -1011,5 +1018,5 @@ StorageNode SqliteStorage::getFirstNode(const std::string& query) const { return nodes[0]; } - return StorageNode(0, 0, "", definitionTypeToInt(DEFINITION_NONE)); + return StorageNode(); } diff --git a/src/lib/data/SqliteStorage.h b/src/lib/data/SqliteStorage.h index cad4d96f..7b02a4d1 100644 --- a/src/lib/data/SqliteStorage.h +++ b/src/lib/data/SqliteStorage.h @@ -79,7 +79,9 @@ public: StorageLocalSymbol getLocalSymbolByName(const std::string& name) const; StorageFile getFileById(const Id id) const; - StorageFile getFileByPath(const std::string& filePath) const; + StorageFile getFileByPath(const FilePath& filePath) const; + + std::vector getFilesByPaths(const std::vector& filePaths) const; std::vector getAllFiles() const; std::shared_ptr getFileContentByPath(const std::string& filePath) const; diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 2a2882be..954b9659 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -260,50 +260,69 @@ std::vector Storage::getAutocompletionMatches(const std::string& qu } ); - std::vector matches; - for (size_t i = 0; i < results.size(); i++) + std::map storageNodesMap; { + std::vector elementIds; + + for (const SearchResult& result : results) + { + elementIds.insert(elementIds.end(), result.elementIds.begin(), result.elementIds.end()); + } + + std::vector storageNodes = m_sqliteStorage.getNodesByIds(elementIds); + + for (StorageNode& node : storageNodes) + { + if (node.id > 0) + { + storageNodesMap.emplace(node.id, node); + } + } + } + + std::vector matches; + for (const SearchResult& result : results) + { + if (result.elementIds.size() == 0) + { + continue; + } + SearchMatch match; - if (results[i].elementIds.size() > 0) + const StorageNode* firstNode = nullptr; + for (const Id& elementId : result.elementIds) { - StorageNode firstNode(0, 0, "", 0); - for (std::set::const_iterator itElementIds = results[i].elementIds.begin(); - itElementIds != results[i].elementIds.end(); - itElementIds++) + if (elementId != 0) { - Id elementId = *itElementIds; - if (elementId != 0) - { - StorageNode node = m_sqliteStorage.getNodeById(elementId); - match.nameHierarchies.push_back(NameHierarchy::deserialize(node.serializedName)); + const StorageNode& node = storageNodesMap[elementId]; + match.nameHierarchies.push_back(NameHierarchy::deserialize(node.serializedName)); - if (firstNode.id == 0) - { - firstNode = node; - } + if (!firstNode) + { + firstNode = &node; } } + } - match.text = results[i].text; - match.indices = results[i].indices; + match.text = result.text; + match.indices = result.indices; - if (firstNode.id != 0) + if (firstNode) + { + match.nodeType = Node::intToType(firstNode->type); + match.typeName = Node::getTypeString(match.nodeType); + + if (intToDefinitionType(firstNode->definitionType) == DEFINITION_NONE && match.nodeType != Node::NODE_UNDEFINED) { - match.nodeType = Node::intToType(firstNode.type); - match.typeName = Node::getTypeString(match.nodeType); - - if (intToDefinitionType(firstNode.definitionType) == DEFINITION_NONE && match.nodeType != Node::NODE_UNDEFINED) - { - match.typeName = "undefined " + match.typeName; - } - match.searchType = SearchMatch::SEARCH_TOKEN; - } - else - { - match.searchType = SearchMatch::SEARCH_COMMAND; - match.typeName = "command"; + match.typeName = "undefined " + match.typeName; } + match.searchType = SearchMatch::SEARCH_TOKEN; + } + else + { + match.searchType = SearchMatch::SEARCH_COMMAND; + match.typeName = "command"; } matches.push_back(match); @@ -742,9 +761,22 @@ std::shared_ptr Storage::getFileContent(const FilePath& filePath) co return m_sqliteStorage.getFileContentByPath(filePath.str()); } -TimePoint Storage::getFileModificationTime(const FilePath& filePath) const +FileInfo Storage::getFileInfoForFilePath(const FilePath& filePath) const { - return TimePoint(m_sqliteStorage.getFileByPath(filePath.str()).modificationTime); + return FileInfo(filePath, m_sqliteStorage.getFileByPath(filePath).modificationTime); +} + +std::vector Storage::getFileInfosForFilePaths(const std::vector& filePaths) const +{ + std::vector fileInfos; + + std::vector storageFiles = m_sqliteStorage.getFilesByPaths(filePaths); + for (const StorageFile& file : storageFiles) + { + fileInfos.push_back(FileInfo(FilePath(file.filePath), file.modificationTime)); + } + + return fileInfos; } ErrorCountInfo Storage::getErrorCount() const diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index 2ca29b67..1d62e683 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -79,7 +79,9 @@ public: virtual std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const; virtual std::shared_ptr getFileContent(const FilePath& filePath) const; - virtual TimePoint getFileModificationTime(const FilePath& filePath) const; + + virtual FileInfo getFileInfoForFilePath(const FilePath& filePath) const; + virtual std::vector getFileInfosForFilePaths(const std::vector& filePaths) const; virtual ErrorCountInfo getErrorCount() const; virtual StorageStats getStorageStats() const; diff --git a/src/lib/data/StorageTypes.h b/src/lib/data/StorageTypes.h index 73a8e2e5..d74426c8 100644 --- a/src/lib/data/StorageTypes.h +++ b/src/lib/data/StorageTypes.h @@ -5,6 +5,8 @@ #include "utility/types.h" +#include "data/DefinitionType.h" + struct StorageEdge { StorageEdge(Id id, int type, Id sourceNodeId, Id targetNodeId) @@ -22,6 +24,12 @@ struct StorageEdge struct StorageNode { + StorageNode() + : id(0) + , type(0) + , definitionType(definitionTypeToInt(DEFINITION_NONE)) + {} + StorageNode(Id id, int type, const std::string& serializedName, int definitionType) : id(id) , type(type) diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index dcc4d4ce..663895dd 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -6,6 +6,7 @@ #include #include "utility/types.h" +#include "utility/file/FileInfo.h" #include "utility/file/FilePath.h" #include "data/graph/Node.h" @@ -14,7 +15,6 @@ #include "data/ErrorInfo.h" #include "data/StorageStats.h" -struct FileInfo; class Graph; class TextAccess; class TokenLocation; @@ -61,7 +61,9 @@ public: virtual std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const = 0; virtual std::shared_ptr getFileContent(const FilePath& filePath) const = 0; - virtual TimePoint getFileModificationTime(const FilePath& filePath) const = 0; + + virtual FileInfo getFileInfoForFilePath(const FilePath& filePath) const = 0; + virtual std::vector getFileInfosForFilePaths(const std::vector& filePaths) const = 0; virtual ErrorCountInfo getErrorCount() const = 0; virtual StorageStats getStorageStats() const = 0; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index 10449780..96ac41ae 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -255,14 +255,24 @@ std::shared_ptr StorageAccessProxy::getFileContent(const FilePath& f return nullptr; } -TimePoint StorageAccessProxy::getFileModificationTime(const FilePath& filePath) const +FileInfo StorageAccessProxy::getFileInfoForFilePath(const FilePath& filePath) const { if (hasSubject()) { - return m_subject->getFileModificationTime(filePath); + return m_subject->getFileInfoForFilePath(filePath); } - return TimePoint(boost::posix_time::not_a_date_time); + return FileInfo(); +} + +std::vector StorageAccessProxy::getFileInfosForFilePaths(const std::vector& filePaths) const +{ + if (hasSubject()) + { + return m_subject->getFileInfosForFilePaths(filePaths); + } + + return std::vector(); } ErrorCountInfo StorageAccessProxy::getErrorCount() const diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index b80687b8..cdb13044 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -48,7 +48,9 @@ public: virtual std::shared_ptr getCommentLocationsInFile(const FilePath& filePath) const; virtual std::shared_ptr getFileContent(const FilePath& filePath) const; - virtual TimePoint getFileModificationTime(const FilePath& filePath) const; + + virtual FileInfo getFileInfoForFilePath(const FilePath& filePath) const; + virtual std::vector getFileInfosForFilePaths(const std::vector& filePaths) const; virtual ErrorCountInfo getErrorCount() const; virtual StorageStats getStorageStats() const; diff --git a/src/lib/data/parser/ParserClientImpl.cpp b/src/lib/data/parser/ParserClientImpl.cpp index cf3e71f6..0a7979ae 100644 --- a/src/lib/data/parser/ParserClientImpl.cpp +++ b/src/lib/data/parser/ParserClientImpl.cpp @@ -358,7 +358,7 @@ Id ParserClientImpl::onFileParsed(const FileInfo& fileInfo) // TODO: move up to { log("file", fileInfo.path.str(), ParseLocation()); - addFile(fileInfo.path.fileName(), fileInfo.path.str(), utility::timeToString(fileInfo.lastWriteTime)); + addFile(fileInfo.path.fileName(), fileInfo.path.str(), fileInfo.lastWriteTime.toString()); return 0; } @@ -367,8 +367,8 @@ Id ParserClientImpl::onFileIncludeParsed(const ParseLocation& location, const Fi { log("include", includedFileInfo.path.str(), location); - Id fileNodeId = addFile(fileInfo.path.fileName(), fileInfo.path.str(), utility::timeToString(fileInfo.lastWriteTime)); - Id includedFileNodeId = addFile(includedFileInfo.path.fileName(), includedFileInfo.path.str(), utility::timeToString(includedFileInfo.lastWriteTime)); + Id fileNodeId = addFile(fileInfo.path.fileName(), fileInfo.path.str(), fileInfo.lastWriteTime.toString()); + Id includedFileNodeId = addFile(includedFileInfo.path.fileName(), includedFileInfo.path.str(), includedFileInfo.lastWriteTime.toString()); Id edgeId = addEdge(Edge::EDGE_INCLUDE, fileNodeId, includedFileNodeId); addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN)); diff --git a/src/lib/utility/file/FileInfo.cpp b/src/lib/utility/file/FileInfo.cpp index be092a75..4fc27421 100644 --- a/src/lib/utility/file/FileInfo.cpp +++ b/src/lib/utility/file/FileInfo.cpp @@ -2,17 +2,15 @@ FileInfo::FileInfo() : path(FilePath("")) - , lastWriteTime(boost::posix_time::not_a_date_time) { } FileInfo::FileInfo(const FilePath& path) : path(path) - , lastWriteTime(boost::posix_time::not_a_date_time) { } -FileInfo::FileInfo(const FilePath& path, boost::posix_time::ptime lastWriteTime) +FileInfo::FileInfo(const FilePath& path, const TimePoint& lastWriteTime) : path(path) , lastWriteTime(lastWriteTime) { diff --git a/src/lib/utility/file/FileInfo.h b/src/lib/utility/file/FileInfo.h index dcc40ddb..3ace0e0b 100644 --- a/src/lib/utility/file/FileInfo.h +++ b/src/lib/utility/file/FileInfo.h @@ -6,15 +6,16 @@ #include "boost/date_time.hpp" #include "utility/file/FilePath.h" +#include "utility/TimePoint.h" struct FileInfo { FileInfo(); FileInfo(const FilePath& path); - FileInfo(const FilePath& path, boost::posix_time::ptime lastWriteTime); + FileInfo(const FilePath& path, const TimePoint& lastWriteTime); FilePath path; - boost::posix_time::ptime lastWriteTime; + TimePoint lastWriteTime; }; #endif // FILE_INFO_H