diff --git a/src/lib/data/storage/PersistentStorage.cpp b/src/lib/data/storage/PersistentStorage.cpp index aa9e692d..1ddb9184 100644 --- a/src/lib/data/storage/PersistentStorage.cpp +++ b/src/lib/data/storage/PersistentStorage.cpp @@ -344,21 +344,19 @@ std::vector PersistentStorage::getFileInfoForAllFiles() const TRACE(); std::vector fileInfos; - for (StorageFile file : m_sqliteIndexStorage.getAll()) - { - boost::posix_time::ptime modificationTime = boost::posix_time::not_a_date_time; - if (file.modificationTime != "not-a-date-time") - { - modificationTime = boost::posix_time::time_from_string(file.modificationTime); - } - fileInfos.push_back( - FileInfo( - FilePath(file.filePath), - modificationTime - ) - ); - } + m_sqliteIndexStorage.forEach( + [&](StorageFile&& file) + { + boost::posix_time::ptime modificationTime = boost::posix_time::not_a_date_time; + if (file.modificationTime != "not-a-date-time") + { + modificationTime = boost::posix_time::time_from_string(file.modificationTime); + } + + fileInfos.emplace_back(FilePath(file.filePath), modificationTime); + } + ); return fileInfos; } @@ -906,18 +904,21 @@ std::shared_ptr PersistentStorage::getGraphForAll() const TRACE(); std::vector tokenIds; - for (const StorageNode& node: m_sqliteIndexStorage.getAll()) - { - auto it = m_symbolDefinitionKinds.find(node.id); - if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT && - ( - NodeType(NodeType::intToType(node.type)).isPackage() || - !m_hierarchyCache.isChildOfVisibleNodeOrInvisible(node.id) - ) - ){ - tokenIds.push_back(node.id); + + m_sqliteIndexStorage.forEach( + [&](StorageNode&& node) + { + auto it = m_symbolDefinitionKinds.find(node.id); + if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT && + ( + NodeType(NodeType::intToType(node.type)).isPackage() || + !m_hierarchyCache.isChildOfVisibleNodeOrInvisible(node.id) + ) + ){ + tokenIds.push_back(node.id); + } } - } + ); for (const auto& p : m_fileNodeIndexed) { @@ -937,20 +938,21 @@ std::shared_ptr PersistentStorage::getGraphForNodeTypes(NodeTypeSet nodeT { TRACE(); - std::shared_ptr graph = std::make_shared(); - std::vector tokenIds; - for (StorageNode& node: m_sqliteIndexStorage.getAll()) - { - if (nodeTypes.contains(NodeType::intToType(node.type))) + + m_sqliteIndexStorage.forEach( + [&](StorageNode&& node) { - auto it = m_symbolDefinitionKinds.find(node.id); - if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT) + if (nodeTypes.contains(NodeType::intToType(node.type))) { - tokenIds.push_back(node.id); + auto it = m_symbolDefinitionKinds.find(node.id); + if (it != m_symbolDefinitionKinds.end() && it->second == DEFINITION_EXPLICIT) + { + tokenIds.push_back(node.id); + } } } - } + ); if (nodeTypes.containsMatching([](const NodeType& type) { return type.isFile(); })) { @@ -960,6 +962,7 @@ std::shared_ptr PersistentStorage::getGraphForNodeTypes(NodeTypeSet nodeT } } + std::shared_ptr graph = std::make_shared(); addNodesWithParentsAndEdgesToGraph(tokenIds, std::vector(), graph.get(), false); return graph; @@ -2267,20 +2270,30 @@ bool PersistentStorage::getFileNodeIndexed(Id fileId) const std::unordered_map> PersistentStorage::getFileIdToIncludingFileIdMap() const { std::unordered_map> fileIdToIncludingFileIdMap; - for (const StorageEdge& includeEdge : m_sqliteIndexStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_INCLUDE))) - { - fileIdToIncludingFileIdMap[includeEdge.targetNodeId].insert(includeEdge.sourceNodeId); - } + + m_sqliteIndexStorage.forEachOfType( + Edge::typeToInt(Edge::EDGE_INCLUDE), + [&fileIdToIncludingFileIdMap](StorageEdge&& edge) + { + fileIdToIncludingFileIdMap[edge.targetNodeId].insert(edge.sourceNodeId); + } + ); + return fileIdToIncludingFileIdMap; } std::unordered_map> PersistentStorage::getFileIdToIncludedFileIdMap() const { std::unordered_map> fileIdToIncludingFileIdMap; - for (const StorageEdge& includeEdge : m_sqliteIndexStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_INCLUDE))) - { - fileIdToIncludingFileIdMap[includeEdge.sourceNodeId].insert(includeEdge.targetNodeId); - } + + m_sqliteIndexStorage.forEachOfType( + Edge::typeToInt(Edge::EDGE_INCLUDE), + [&fileIdToIncludingFileIdMap](StorageEdge&& edge) + { + fileIdToIncludingFileIdMap[edge.sourceNodeId].insert(edge.targetNodeId); + } + ); + return fileIdToIncludingFileIdMap; } @@ -2291,11 +2304,14 @@ std::unordered_map> PersistentStorage::getFileIdToImportingFile std::vector importedElementIds; std::map> elementIdToImportingFileIds; - for (const StorageEdge& importEdge : m_sqliteIndexStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_IMPORT))) - { - importedElementIds.push_back(importEdge.targetNodeId); - elementIdToImportingFileIds[importEdge.targetNodeId].insert(importEdge.sourceNodeId); - } + m_sqliteIndexStorage.forEachOfType( + Edge::typeToInt(Edge::EDGE_IMPORT), + [&importedElementIds, &elementIdToImportingFileIds](StorageEdge&& edge) + { + importedElementIds.push_back(edge.targetNodeId); + elementIdToImportingFileIds[edge.targetNodeId].insert(edge.sourceNodeId); + } + ); std::unordered_map importedElementIdToFileNodeId; { @@ -2828,26 +2844,30 @@ void PersistentStorage::buildFilePathMaps() { TRACE(); - for (const StorageFile& file: m_sqliteIndexStorage.getAll()) - { - const FilePath path(file.filePath); - - m_fileNodeIds.emplace(path, file.id); - m_lowerCasefileNodeIds.emplace(path.getLowerCase(), file.id); - m_fileNodePaths.emplace(file.id, path); - m_fileNodeComplete.emplace(file.id, file.complete); - m_fileNodeIndexed.emplace(file.id, file.indexed); - - if (!m_hasJavaFiles && path.extension() == L".java") + m_sqliteIndexStorage.forEach( + [&](StorageFile&& file) { - m_hasJavaFiles = true; - } - } + const FilePath path(file.filePath); - for (StorageSymbol& symbol : m_sqliteIndexStorage.getAll()) - { - m_symbolDefinitionKinds.emplace(symbol.id, intToDefinitionKind(symbol.definitionKind)); - } + m_fileNodeIds.emplace(path, file.id); + m_lowerCasefileNodeIds.emplace(path.getLowerCase(), file.id); + m_fileNodePaths.emplace(file.id, path); + m_fileNodeComplete.emplace(file.id, file.complete); + m_fileNodeIndexed.emplace(file.id, file.indexed); + + if (!m_hasJavaFiles && path.extension() == L".java") + { + m_hasJavaFiles = true; + } + } + ); + + m_sqliteIndexStorage.forEach( + [&](StorageSymbol&& symbol) + { + m_symbolDefinitionKinds.emplace(symbol.id, intToDefinitionKind(symbol.definitionKind)); + } + ); } void PersistentStorage::buildSearchIndex() @@ -2856,52 +2876,54 @@ void PersistentStorage::buildSearchIndex() const FilePath dbPath = getIndexDbFilePath(); - for (const StorageNode& node : m_sqliteIndexStorage.getAll()) - { - const NodeType type = NodeType::intToType(node.type); - if (type.isFile()) + m_sqliteIndexStorage.forEach( + [&](StorageNode&& node) { - bool indexed = getFileNodeIndexed(node.id); - if (!indexed) + const NodeType type = NodeType::intToType(node.type); + if (type.isFile()) { - continue; - } - - auto it = m_fileNodePaths.find(node.id); - if (it != m_fileNodePaths.end()) - { - FilePath filePath(it->second); - - if (filePath.exists()) + bool indexed = getFileNodeIndexed(node.id); + if (!indexed) { - filePath.makeRelativeTo(dbPath); + return; } - m_fileIndex.addNode(node.id, filePath.wstr(), type); - } - } - else - { - auto it = m_symbolDefinitionKinds.find(node.id); - const DefinitionKind defKind = (it != m_symbolDefinitionKinds.end() ? it->second : DEFINITION_NONE); - if (defKind != DEFINITION_IMPLICIT) - { - const NameHierarchy nameHierarchy = NameHierarchy::deserialize(node.serializedName); - - // we don't use the signature here, so elements with the same signature share the same node. - std::wstring name = nameHierarchy.getQualifiedName(); - - // replace template arguments with .. to avoid clutter in search results and have different - // template specializations share the same node. - if (defKind == DEFINITION_NONE && nameHierarchy.getDelimiter() == NAME_DELIMITER_CXX) + auto it = m_fileNodePaths.find(node.id); + if (it != m_fileNodePaths.end()) { - name = utility::replaceBetween(name, L'<', L'>', L".."); - } + FilePath filePath(it->second); - m_symbolIndex.addNode(node.id, std::move(name), type); + if (filePath.exists()) + { + filePath.makeRelativeTo(dbPath); + } + + m_fileIndex.addNode(node.id, filePath.wstr(), type); + } + } + else + { + auto it = m_symbolDefinitionKinds.find(node.id); + const DefinitionKind defKind = (it != m_symbolDefinitionKinds.end() ? it->second : DEFINITION_NONE); + if (defKind != DEFINITION_IMPLICIT) + { + const NameHierarchy nameHierarchy = NameHierarchy::deserialize(node.serializedName); + + // we don't use the signature here, so elements with the same signature share the same node. + std::wstring name = nameHierarchy.getQualifiedName(); + + // replace template arguments with .. to avoid clutter in search results and have different + // template specializations share the same node. + if (defKind == DEFINITION_NONE && nameHierarchy.getDelimiter() == NAME_DELIMITER_CXX) + { + name = utility::replaceBetween(name, L'<', L'>', L".."); + } + + m_symbolIndex.addNode(node.id, std::move(name), type); + } } } - } + ); m_symbolIndex.finishSetup(); m_fileIndex.finishSetup(); @@ -2963,11 +2985,14 @@ void PersistentStorage::buildMemberEdgeIdOrderMap() std::vector childNodeIds; std::unordered_map childIdToMemberEdgeIdMap; - for (const StorageEdge& edge : m_sqliteIndexStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_MEMBER))) - { - childNodeIds.push_back(edge.targetNodeId); - childIdToMemberEdgeIdMap.emplace(edge.targetNodeId, edge.id); - } + m_sqliteIndexStorage.forEachOfType( + Edge::typeToInt(Edge::EDGE_MEMBER), + [&childNodeIds, &childIdToMemberEdgeIdMap](StorageEdge&& edge) + { + childNodeIds.push_back(edge.targetNodeId); + childIdToMemberEdgeIdMap.emplace(edge.targetNodeId, edge.id); + } + ); std::vector locationIds; std::unordered_map locationIdToElementIdMap; @@ -3028,29 +3053,37 @@ void PersistentStorage::buildHierarchyCache() { TRACE(); - const std::vector memberEdges = m_sqliteIndexStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_MEMBER)); - std::vector sourceNodeIds; - for (const StorageEdge& edge : memberEdges) - { - sourceNodeIds.push_back(edge.sourceNodeId); - } + std::vector memberEdges; - std::map sourceNodeTypeMap; - for (const StorageNode& node : m_sqliteIndexStorage.getAllByIds(sourceNodeIds)) - { - sourceNodeTypeMap.emplace(node.id, NodeType::intToType(node.type)); - } + m_sqliteIndexStorage.forEachOfType( + Edge::typeToInt(Edge::EDGE_MEMBER), + [&sourceNodeIds, &memberEdges](StorageEdge&& edge) + { + sourceNodeIds.push_back(edge.sourceNodeId); + memberEdges.emplace_back(edge); + } + ); + + std::set invisibleParentSourceNodeIds; + + m_sqliteIndexStorage.forEachByIds( + sourceNodeIds, + [&invisibleParentSourceNodeIds](StorageNode&& node) + { + if (!NodeType(NodeType::intToType(node.type)).isVisibleAsParentInGraph()) + { + invisibleParentSourceNodeIds.insert(node.id); + } + } + ); for (const StorageEdge& edge : memberEdges) { bool sourceIsVisible = true; + if (invisibleParentSourceNodeIds.find(edge.sourceNodeId) != invisibleParentSourceNodeIds.end()) { - std::map::const_iterator it = sourceNodeTypeMap.find(edge.sourceNodeId); - if (it != sourceNodeTypeMap.end()) - { - sourceIsVisible = it->second.isVisibleAsParentInGraph(); - } + sourceIsVisible = false; } bool sourceIsImplicit = false; @@ -3071,9 +3104,11 @@ void PersistentStorage::buildHierarchyCache() edge.id, edge.sourceNodeId, edge.targetNodeId, sourceIsVisible, sourceIsImplicit, targetIsImplicit); } - std::vector inheritanceEdges = m_sqliteIndexStorage.getEdgesByType(Edge::typeToInt(Edge::EDGE_INHERITANCE)); - for (const StorageEdge& edge : inheritanceEdges) - { - m_hierarchyCache.createInheritance(edge.id, edge.sourceNodeId, edge.targetNodeId); - } + m_sqliteIndexStorage.forEachOfType( + Edge::typeToInt(Edge::EDGE_INHERITANCE), + [this](StorageEdge&& edge) + { + m_hierarchyCache.createInheritance(edge.id, edge.sourceNodeId, edge.targetNodeId); + } + ); } diff --git a/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp b/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp index 913b5270..77becc7b 100644 --- a/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp +++ b/src/lib/data/storage/sqlite/SqliteIndexStorage.cpp @@ -97,20 +97,22 @@ std::vector SqliteIndexStorage::addNodes(const std::vector& nod { if (m_tempNodeNameIndex.empty() && m_tempWNodeNameIndex.empty()) { - for (const StorageNode& node : getAll()) - { - std::string name = utility::encodeToUtf8(node.serializedName); - if (name.size() != node.serializedName.size()) + forEach( + [this](StorageNode&& node) { - m_tempWNodeNameIndex.add(node.serializedName, node.id); - } - else - { - m_tempNodeNameIndex.add(name, node.id); - } + std::string name = utility::encodeToUtf8(node.serializedName); + if (name.size() != node.serializedName.size()) + { + m_tempWNodeNameIndex.add(node.serializedName, node.id); + } + else + { + m_tempNodeNameIndex.add(name, node.id); + } - m_tempNodeTypes.emplace(node.id, node.type); - } + m_tempNodeTypes.emplace(node.id, node.type); + } + ); } std::vector nodeIds(nodes.size(), 0); @@ -234,10 +236,12 @@ std::vector SqliteIndexStorage::addEdges(const std::vector& edg { if (m_tempEdgeIndex.empty()) { - for (const StorageEdge& edge : getAll()) - { - m_tempEdgeIndex.emplace(StorageEdgeData(edge.type, edge.sourceNodeId, edge.targetNodeId), edge.id); - } + forEach( + [this](StorageEdge&& edge) + { + m_tempEdgeIndex.emplace(StorageEdgeData(edge.type, edge.sourceNodeId, edge.targetNodeId), edge.id); + } + ); } std::vector edgeIds(edges.size(), 0); @@ -278,20 +282,20 @@ Id SqliteIndexStorage::addLocalSymbol(const StorageLocalSymbolData& data) std::vector SqliteIndexStorage::addLocalSymbols(const std::set& symbols) { - std::wstring name; - uint32_t line; - uint32_t col; - if (m_tempLocalSymbolIndex.empty()) { - for (const StorageLocalSymbol& localSymbol : getAll()) - { - std::tie(name, line, col) = splitLocalSymbolName(localSymbol.name); - if (name.size()) + forEach( + [this](StorageLocalSymbol&& localSymbol) { - m_tempLocalSymbolIndex[name].emplace(std::make_pair(line, col), localSymbol.id); + std::wstring name; + uint32_t line, col; + std::tie(name, line, col) = splitLocalSymbolName(localSymbol.name); + if (name.size()) + { + m_tempLocalSymbolIndex[name].emplace(std::make_pair(line, col), localSymbol.id); + } } - } + ); } std::vector symbolIds(symbols.size(), 0); @@ -300,6 +304,8 @@ std::vector SqliteIndexStorage::addLocalSymbols(const std::set SqliteIndexStorage::addSourceLocations(const std::vector()) - { - std::map& index = m_tempSourceLocationIndices[loc.fileNodeId]; - index.emplace( - TempSourceLocation(loc.startLine, loc.endLine - loc.startLine, loc.startCol, loc.endCol, loc.type), - loc.id); - } + forEach( + [this](StorageSourceLocation&& loc) + { + std::map& index = m_tempSourceLocationIndices[loc.fileNodeId]; + index.emplace( + TempSourceLocation(loc.startLine, loc.endLine - loc.startLine, loc.startCol, loc.endCol, loc.type), + loc.id); + } + ); } std::vector locationIds(locations.size(), 0); @@ -1293,13 +1301,12 @@ void SqliteIndexStorage::setupPrecompiledStatements() } template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const { CppSQLite3Query q = executeQuery( "SELECT id, type, source_node_id, target_node_id FROM edge " + query + ";" ); - std::vector edges; while (!q.eof()) { const Id id = q.getIntField(0, 0); @@ -1309,22 +1316,20 @@ std::vector SqliteIndexStorage::doGetAll(const std::st if (id != 0 && type != -1) { - edges.emplace_back(id, type, sourceId, targetId); + func(StorageEdge(id, type, sourceId, targetId)); } q.nextRow(); } - return edges; } template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const { CppSQLite3Query q = executeQuery( "SELECT id, type, serialized_name FROM node " + query + ";" ); - std::vector nodes; while (!q.eof()) { const Id id = q.getIntField(0, 0); @@ -1333,22 +1338,20 @@ std::vector SqliteIndexStorage::doGetAll(const std::st if (id != 0 && type != -1) { - nodes.emplace_back(id, type, utility::decodeFromUtf8(serializedName)); + func(StorageNode(id, type, utility::decodeFromUtf8(serializedName))); } q.nextRow(); } - return nodes; } template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const { CppSQLite3Query q = executeQuery( "SELECT id, definition_kind FROM symbol " + query + ";" ); - std::vector symbols; while (!q.eof()) { const Id id = q.getIntField(0, 0); @@ -1356,22 +1359,20 @@ std::vector SqliteIndexStorage::doGetAll(const std if (id != 0) { - symbols.emplace_back(id, definitionKind); + func(StorageSymbol(id, definitionKind)); } q.nextRow(); } - return symbols; } template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const { CppSQLite3Query q = executeQuery( "SELECT id, path, modification_time, indexed, complete FROM file " + query + ";" ); - std::vector files; while (!q.eof()) { const Id id = q.getIntField(0, 0); @@ -1382,23 +1383,19 @@ std::vector SqliteIndexStorage::doGetAll(const std::st if (id != 0) { - files.emplace_back(id, utility::decodeFromUtf8(filePath), modificationTime, indexed, complete); + func(StorageFile(id, utility::decodeFromUtf8(filePath), modificationTime, indexed, complete)); } q.nextRow(); } - - return files; } template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const { CppSQLite3Query q = executeQuery( "SELECT id, name FROM local_symbol " + query + ";" ); - std::vector localSymbols; - while (!q.eof()) { const Id id = q.getIntField(0, 0); @@ -1406,23 +1403,20 @@ std::vector SqliteIndexStorage::doGetAll if (id != 0) { - localSymbols.emplace_back(id, utility::decodeFromUtf8(name)); + func(StorageLocalSymbol(id, utility::decodeFromUtf8(name))); } q.nextRow(); } - return localSymbols; } template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const { CppSQLite3Query q = executeQuery( "SELECT id, file_node_id, start_line, start_column, end_line, end_column, type FROM source_location " + query + ";" ); - std::vector sourceLocations; - while (!q.eof()) { const Id id = q.getIntField(0, 0); @@ -1436,23 +1430,20 @@ std::vector SqliteIndexStorage::doGetAll -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const { CppSQLite3Query q = executeQuery( "SELECT element_id, source_location_id FROM occurrence " + query + ";" ); - std::vector occurrences; - while (!q.eof()) { const Id elementId = q.getIntField(0, 0); @@ -1460,23 +1451,20 @@ std::vector SqliteIndexStorage::doGetAll(c if (elementId != 0 && sourceLocationId != 0) { - occurrences.emplace_back(elementId, sourceLocationId); + func(StorageOccurrence(elementId, sourceLocationId)); } q.nextRow(); } - return occurrences; } template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const { CppSQLite3Query q = executeQuery( "SELECT node_id, type FROM component_access " + query + ";" ); - std::vector componentAccesses; - while (!q.eof()) { const Id nodeId = q.getIntField(0, 0); @@ -1484,22 +1472,20 @@ std::vector SqliteIndexStorage::doGetAll -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const { CppSQLite3Query q = executeQuery( "SELECT message, fatal, indexed, file_path, line_number, column_number, translation_unit FROM error " + query + ";" ); - std::vector errors; Id id = 1; while (!q.eof()) { @@ -1513,15 +1499,13 @@ std::vector SqliteIndexStorage::doGetAll(const std:: if (lineNumber != -1 && columnNumber != -1) { - errors.emplace_back( + func(StorageError( id, utility::decodeFromUtf8(message), utility::decodeFromUtf8(filePath), lineNumber, columnNumber, utility::decodeFromUtf8(translationUnit), fatal, indexed - ); + )); id++; } q.nextRow(); } - - return errors; } diff --git a/src/lib/data/storage/sqlite/SqliteIndexStorage.h b/src/lib/data/storage/sqlite/SqliteIndexStorage.h index 246c6470..ae732784 100644 --- a/src/lib/data/storage/sqlite/SqliteIndexStorage.h +++ b/src/lib/data/storage/sqlite/SqliteIndexStorage.h @@ -145,6 +145,27 @@ public: return std::vector(); } + template + void forEach(std::function func) const + { + forEach("", func); + } + + template + void forEachOfType(int type, std::function func) const + { + forEach("WHERE type == " + std::to_string(type), func); + } + + template + void forEachByIds(const std::vector ids, std::function func) const + { + if (ids.size()) + { + forEach("WHERE id IN (" + utility::join(utility::toStrings(ids), ',') + ")", func); + } + } + int getNodeCount() const; int getEdgeCount() const; int getFileCount() const; @@ -204,7 +225,18 @@ private: virtual void setupPrecompiledStatements(); template - std::vector doGetAll(const std::string& query) const; + std::vector doGetAll(const std::string& query) const + { + std::vector elements; + forEach( + query, + [&elements](ResultType&& element) + { + elements.emplace_back(element); + } + ); + return elements; + } template ResultType doGetFirst(const std::string& query) const @@ -217,6 +249,9 @@ private: return ResultType(); } + template + void forEach(const std::string& query, std::function func) const; + LowMemoryStringMap m_tempNodeNameIndex; LowMemoryStringMap m_tempWNodeNameIndex; std::map m_tempNodeTypes; @@ -309,22 +344,22 @@ template const size_t SqliteIndexStorage::InsertBatchStatement::BATCH_SIZES[4] = { 100, 27, 8, 1 }; template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const; +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const; template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const; +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const; template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const; +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const; template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const; +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const; template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const; +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const; template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const; +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const; template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const; +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const; template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const; +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const; template <> -std::vector SqliteIndexStorage::doGetAll(const std::string& query) const; +void SqliteIndexStorage::forEach(const std::string& query, std::function func) const; #endif // SQLITE_INDEX_STORAGE_H