From c45a2dcc935935cb3101a32bfb120466786534f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=BCkki=20D=C3=A1niel?= Date: Fri, 26 Apr 2024 10:15:04 +0200 Subject: [PATCH 1/3] Fix segmentation fault due to access of file ID on non-loaded file. --- .../model/include/model/cppastnodemetrics.h | 13 +++++++++++++ plugins/cpp_metrics/parser/src/cppmetricsparser.cpp | 8 +++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h b/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h index eb17cdf3d..75ae307d1 100644 --- a/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h +++ b/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h @@ -44,6 +44,19 @@ struct CppRecordMetricsView double value; }; +#pragma db view \ + object(CppAstNodeMetrics) \ + object(CppAstNode : CppAstNodeMetrics::astNodeId == CppAstNode::id) \ + object(File : CppAstNode::location.file) +struct CppAstNodeMetricsFileView +{ + #pragma db column(CppAstNode::id) + CppAstNodeId astNodeId; + + #pragma db column(File::id) + FileId fileId; +}; + } //model } //cc diff --git a/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp b/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp index 7e8269a4d..bff586806 100644 --- a/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp +++ b/plugins/cpp_metrics/parser/src/cppmetricsparser.cpp @@ -39,12 +39,10 @@ CppMetricsParser::CppMetricsParser(ParserContext& ctx_): AbstractParser(ctx_) _fileIdCache.insert(fm.file); } - for (const model::CppAstNodeMetrics& anm - : _ctx.db->query()) + for (const model::CppAstNodeMetricsFileView& anm + : _ctx.db->query()) { - auto node = _ctx.db->query_one( - odb::query::id == anm.astNodeId); - _astNodeIdCache.insert({anm.astNodeId, node->location.file->id}); + _astNodeIdCache.emplace(anm.astNodeId, anm.fileId); } }); } From 6544d70fc19599429f81d4a831ee3630b41e70e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=BCkki=20D=C3=A1niel?= Date: Fri, 26 Apr 2024 11:15:48 +0200 Subject: [PATCH 2/3] Eliminated use of size() on ODB query result in SourceManager. Added isSingletonResult instead to dbutil. --- parser/src/sourcemanager.cpp | 5 +++-- util/include/util/dbutil.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/parser/src/sourcemanager.cpp b/parser/src/sourcemanager.cpp index 114db9661..af507ec12 100644 --- a/parser/src/sourcemanager.cpp +++ b/parser/src/sourcemanager.cpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -238,9 +239,9 @@ void SourceManager::removeFile(const model::File& file_) _transaction([&]() { if(file_.content) { - auto relFiles = _db->query( + odb::result relFiles = _db->query( odb::query::content == file_.content.object_id()); - if (relFiles.size() == 1) + if (util::isSingletonResult(relFiles)) { removeContent = true; _db->erase(file_.content.object_id()); diff --git a/util/include/util/dbutil.h b/util/include/util/dbutil.h index 4a3d27514..314ce0676 100644 --- a/util/include/util/dbutil.h +++ b/util/include/util/dbutil.h @@ -97,6 +97,40 @@ inline std::string getDbDriver() #endif } +/// @brief Determines if the specified ODB query result only contains +/// a single entity. That single entity is then stored in 'singleton_'. +/// @tparam TEntity The type of entities in the query result. +/// @param result_ The ODB query result in question. +/// @param singleton_ The variable that receives the first entity (if any). +/// @return Returns true if 'result_' only contained 'singleton_'; +/// otherwise false. +template +bool isSingletonResult(odb::result& result_, TEntity& singleton_) +{ + auto it_b = result_.begin(); + const auto it_e = result_.end(); + if (it_b != it_e) + { + singleton_ = *it_b; + return ++it_b == it_e; + } + else return false; +} + +/// @brief Determines if the specified ODB query result only contains +/// a single entity. +/// @tparam TEntity The type of entities in the query result. +/// @param result_ The ODB query result in question. +/// @return Returns true if 'result_' only contained a single entity; +/// otherwise false. +template +bool isSingletonResult(odb::result& result_) +{ + auto it_b = result_.begin(); + const auto it_e = result_.end(); + return (it_b != it_e) && (++it_b == it_e); +} + } // util } // cc From 72c6a6b441d4092364f480c32fe43cb69a23e18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=BCkki=20D=C3=A1niel?= Date: Wed, 1 May 2024 20:06:22 +0200 Subject: [PATCH 3/3] isSingletonResult is renamed to isSingleResult. --- parser/src/sourcemanager.cpp | 2 +- util/include/util/dbutil.h | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/parser/src/sourcemanager.cpp b/parser/src/sourcemanager.cpp index af507ec12..73868e859 100644 --- a/parser/src/sourcemanager.cpp +++ b/parser/src/sourcemanager.cpp @@ -241,7 +241,7 @@ void SourceManager::removeFile(const model::File& file_) { odb::result relFiles = _db->query( odb::query::content == file_.content.object_id()); - if (util::isSingletonResult(relFiles)) + if (util::isSingleResult(relFiles)) { removeContent = true; _db->erase(file_.content.object_id()); diff --git a/util/include/util/dbutil.h b/util/include/util/dbutil.h index 314ce0676..5d1c331d5 100644 --- a/util/include/util/dbutil.h +++ b/util/include/util/dbutil.h @@ -98,20 +98,20 @@ inline std::string getDbDriver() } /// @brief Determines if the specified ODB query result only contains -/// a single entity. That single entity is then stored in 'singleton_'. +/// a single entity. That single entity is then stored in 'single_'. /// @tparam TEntity The type of entities in the query result. /// @param result_ The ODB query result in question. -/// @param singleton_ The variable that receives the first entity (if any). -/// @return Returns true if 'result_' only contained 'singleton_'; +/// @param single_ The variable that receives the first entity (if any). +/// @return Returns true if 'result_' only contained 'single_'; /// otherwise false. template -bool isSingletonResult(odb::result& result_, TEntity& singleton_) +bool isSingleResult(odb::result& result_, TEntity& single_) { auto it_b = result_.begin(); const auto it_e = result_.end(); if (it_b != it_e) { - singleton_ = *it_b; + single_ = *it_b; return ++it_b == it_e; } else return false; @@ -124,7 +124,7 @@ bool isSingletonResult(odb::result& result_, TEntity& singleton_) /// @return Returns true if 'result_' only contained a single entity; /// otherwise false. template -bool isSingletonResult(odb::result& result_) +bool isSingleResult(odb::result& result_) { auto it_b = result_.begin(); const auto it_e = result_.end();