diff --git a/Config.cmake b/Config.cmake index 1032ce379..b5394225d 100644 --- a/Config.cmake +++ b/Config.cmake @@ -87,7 +87,7 @@ set(ODBFLAGS --default-pointer "std::shared_ptr") # Set CXX standard -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h b/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h index 6e0d56e35..2f3d26d64 100644 --- a/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h +++ b/plugins/cpp_metrics/model/include/model/cppastnodemetrics.h @@ -117,6 +117,17 @@ struct CppAstNodeMetricsAndDataForPathView double value; }; +#pragma db view \ + object(CppAstNodeMetrics) \ + object(CppAstNode : CppAstNodeMetrics::astNodeId == CppAstNode::id) \ + object(File : CppAstNode::location.file) \ + query(distinct) +struct CppAstNodeMetricsDistinctView +{ + #pragma db column(CppAstNodeMetrics::astNodeId) + CppAstNodeId astNodeId; +}; + } //model } //cc diff --git a/plugins/cpp_metrics/model/include/model/cppfilemetrics.h b/plugins/cpp_metrics/model/include/model/cppfilemetrics.h index eebedbc46..248c2a710 100644 --- a/plugins/cpp_metrics/model/include/model/cppfilemetrics.h +++ b/plugins/cpp_metrics/model/include/model/cppfilemetrics.h @@ -47,6 +47,16 @@ struct CppModuleMetricsForPathView unsigned value; }; +#pragma db view \ + object(CppFileMetrics) \ + object(File : CppFileMetrics::file == File::id) \ + query(distinct) +struct CppModuleMetricsDistinctView +{ + #pragma db column(CppFileMetrics::file) + FileId fileId; +}; + } //model } //cc diff --git a/plugins/cpp_metrics/service/CMakeLists.txt b/plugins/cpp_metrics/service/CMakeLists.txt index 96b5a1fdf..dbdd2fe0b 100644 --- a/plugins/cpp_metrics/service/CMakeLists.txt +++ b/plugins/cpp_metrics/service/CMakeLists.txt @@ -19,8 +19,9 @@ add_custom_command( ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp/CppMetricsService.cpp ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp/CppMetricsService.h ${CMAKE_CURRENT_BINARY_DIR}/gen-cpp + ${CMAKE_CURRENT_BINARY_DIR}/gen-js COMMAND - ${THRIFT_EXECUTABLE} --gen cpp + ${THRIFT_EXECUTABLE} --gen cpp --gen js -o ${CMAKE_CURRENT_BINARY_DIR} -I ${PROJECT_SOURCE_DIR}/service ${CMAKE_CURRENT_SOURCE_DIR}/cxxmetrics.thrift diff --git a/plugins/cpp_metrics/service/cxxmetrics.thrift b/plugins/cpp_metrics/service/cxxmetrics.thrift index 68defdc0b..08975f80e 100644 --- a/plugins/cpp_metrics/service/cxxmetrics.thrift +++ b/plugins/cpp_metrics/service/cxxmetrics.thrift @@ -98,6 +98,17 @@ service CppMetricsService map> getCppAstNodeMetricsForPath( 1:string path) + /** + * This is a paged function which returns all available C++ metrics + * (AST node-level) for a particular path. + * + * The given path is a handled as a prefix. + */ + map> getPagedCppAstNodeMetricsForPath( + 1:string path + 2:i32 pageSize, + 3:i32 pageNumber) + /** * This function returns all available C++ metrics * (AST node-level) and miscellaneous data for a particular path. @@ -107,6 +118,17 @@ service CppMetricsService map getCppAstNodeMetricsDetailedForPath( 1:string path) + /** + * This is a paged function which returns all available C++ metrics + * (AST node-level) and miscellaneous data for a particular path. + * + * The given path is a handled as a prefix. + */ + map getPagedCppAstNodeMetricsDetailedForPath( + 1:string path, + 2:i32 pageSize, + 3:i32 pageNumber) + /** * This function returns all available C++ metrics * (file-level) for a particular path. @@ -116,6 +138,17 @@ service CppMetricsService map> getCppFileMetricsForPath( 1:string path) + /** + * This is a paged function which returns all available C++ metrics + * (file-level) for a particular path. + * + * The given path is a handled as a prefix. + */ + map> getPagedCppFileMetricsForPath( + 1:string path, + 2:i32 pageSize, + 3:i32 pageNumber) + /** * This function returns the names of the AST node-level C++ metrics. */ diff --git a/plugins/cpp_metrics/service/include/service/cppmetricsservice.h b/plugins/cpp_metrics/service/include/service/cppmetricsservice.h index 4374b29ce..be7b901dc 100644 --- a/plugins/cpp_metrics/service/include/service/cppmetricsservice.h +++ b/plugins/cpp_metrics/service/include/service/cppmetricsservice.h @@ -53,14 +53,32 @@ class CppMetricsServiceHandler : virtual public CppMetricsServiceIf std::map>& _return, const std::string& path_) override; + void getPagedCppAstNodeMetricsForPath( + std::map>& _return, + const std::string& path_, + const std::int32_t pageSize_, + const std::int32_t pageNumber_) override; + void getCppAstNodeMetricsDetailedForPath( std::map& _return, const std::string& path_) override; + void getPagedCppAstNodeMetricsDetailedForPath( + std::map& _return, + const std::string& path_, + const std::int32_t pageSize_, + const std::int32_t pageNumber_) override; + void getCppFileMetricsForPath( std::map>& _return, const std::string& path_) override; + void getPagedCppFileMetricsForPath( + std::map>& _return, + const std::string& path_, + const std::int32_t pageSize_, + const std::int32_t pageNumber_) override; + void getCppAstNodeMetricsTypeNames( std::vector& _return) override; @@ -72,6 +90,46 @@ class CppMetricsServiceHandler : virtual public CppMetricsServiceIf util::OdbTransaction _transaction; const boost::program_options::variables_map& _config; + + std::string getPagingQuery( + const std::int32_t pageSize_, + const std::int32_t pageNumber_); + + template + std::vector pageMetrics( + const std::string& path_, + const std::int32_t pageSize_, + const std::int32_t pageNumber_) + { + return _transaction([&, this](){ + odb::result paged_nodes = _db->query( + odb::query::File::path.like(path_ + '%') + getPagingQuery(pageSize_, pageNumber_)); + + std::vector paged_ids(paged_nodes.size()); + std::transform(paged_nodes.begin(), paged_nodes.end(), paged_ids.begin(), + [](const TView& e){ + if constexpr (std::is_same::value) { + return e.astNodeId; + } else if constexpr (std::is_same::value) { + return e.fileId; + } + }); + + return paged_ids; + }); + } + + void queryCppAstNodeMetricsForPath( + std::map>& _return, + const odb::query& query_); + + void queryCppAstNodeMetricsDetailedForPath( + std::map& _return, + const odb::query& query_); + + void queryCppFileMetricsForPath( + std::map>& _return, + const odb::query& query_); }; } // cppmetrics diff --git a/plugins/cpp_metrics/service/src/cppmetricsservice.cpp b/plugins/cpp_metrics/service/src/cppmetricsservice.cpp index 14b6ddc35..12785856e 100644 --- a/plugins/cpp_metrics/service/src/cppmetricsservice.cpp +++ b/plugins/cpp_metrics/service/src/cppmetricsservice.cpp @@ -14,8 +14,10 @@ namespace service namespace cppmetrics { -typedef odb::query AstQuery; -typedef odb::result AstResult; +typedef odb::query CppNodeMetricsQuery; +typedef odb::result CppNodeMetricsResult; +typedef odb::query CppModuleMetricsQuery; +typedef odb::result CppModuleMetricsResult; CppMetricsServiceHandler::CppMetricsServiceHandler( std::shared_ptr db_, @@ -137,18 +139,12 @@ void CppMetricsServiceHandler::getCppMetricsForModule( }); } -void CppMetricsServiceHandler::getCppAstNodeMetricsForPath( +void CppMetricsServiceHandler::queryCppAstNodeMetricsForPath( std::map>& _return, - const std::string& path_) + const odb::query& query_) { _transaction([&, this](){ - typedef odb::query CppAstNodeFilePathQuery; - typedef odb::result CppAstNodeFilePathResult; - typedef odb::query CppAstNodeMetricsForPathViewQuery; - typedef odb::result CppAstNodeMetricsForPathViewResult; - - auto nodes = _db->query( - CppAstNodeFilePathQuery::LocFile::path.like(path_ + '%')); + auto nodes = _db->query(query_); for (const auto& node : nodes) { @@ -171,18 +167,33 @@ void CppMetricsServiceHandler::getCppAstNodeMetricsForPath( }); } -void CppMetricsServiceHandler::getCppAstNodeMetricsDetailedForPath( - std::map& _return, +void CppMetricsServiceHandler::getCppAstNodeMetricsForPath( + std::map>& _return, const std::string& path_) { - _transaction([&, this](){ - typedef odb::query CppAstNodeFilePathQuery; - typedef odb::result CppAstNodeFilePathResult; - typedef odb::query CppAstNodeMetricsAndDataForPathViewQuery; - typedef odb::result CppAstNodeMetricsAndDataForPathViewResult; + queryCppAstNodeMetricsForPath(_return, + CppNodeMetricsQuery::LocFile::path.like(path_ + '%')); +} + +void CppMetricsServiceHandler::getPagedCppAstNodeMetricsForPath( + std::map>& _return, + const std::string& path_, + const std::int32_t pageSize_, + const std::int32_t pageNumber_) +{ + std::vector paged_nodes = pageMetrics( + path_, pageSize_, pageNumber_); + + queryCppAstNodeMetricsForPath(_return, + CppNodeMetricsQuery::CppAstNodeMetrics::astNodeId.in_range(paged_nodes.begin(), paged_nodes.end())); +} - auto nodes = _db->query( - CppAstNodeFilePathQuery::LocFile::path.like(path_ + '%')); +void CppMetricsServiceHandler::queryCppAstNodeMetricsDetailedForPath( + std::map& _return, + const odb::query& query_) +{ + _transaction([&, this](){ + auto nodes = _db->query(query_); for (const auto& node : nodes) { @@ -210,16 +221,33 @@ void CppMetricsServiceHandler::getCppAstNodeMetricsDetailedForPath( }); } -void CppMetricsServiceHandler::getCppFileMetricsForPath( - std::map>& _return, +void CppMetricsServiceHandler::getCppAstNodeMetricsDetailedForPath( + std::map& _return, const std::string& path_) { - _transaction([&, this](){ - typedef odb::query CppModuleMetricsQuery; - typedef odb::result CppModuleMetricsResult; + queryCppAstNodeMetricsDetailedForPath(_return, + CppNodeMetricsQuery::LocFile::path.like(path_ + '%')); +} + +void CppMetricsServiceHandler::getPagedCppAstNodeMetricsDetailedForPath( + std::map& _return, + const std::string& path_, + const std::int32_t pageSize_, + const std::int32_t pageNumber_) +{ + std::vector paged_nodes = pageMetrics( + path_, pageSize_, pageNumber_); - auto files = _db->query( - CppModuleMetricsQuery::File::path.like(path_ + '%')); + queryCppAstNodeMetricsDetailedForPath(_return, + CppNodeMetricsQuery::CppAstNodeMetrics::astNodeId.in_range(paged_nodes.begin(), paged_nodes.end())); +} + +void CppMetricsServiceHandler::queryCppFileMetricsForPath( + std::map>& _return, + const odb::query& query_) +{ + _transaction([&, this](){ + auto files = _db->query(query_); for (const auto& file : files) { @@ -242,6 +270,47 @@ void CppMetricsServiceHandler::getCppFileMetricsForPath( }); } +void CppMetricsServiceHandler::getCppFileMetricsForPath( + std::map>& _return, + const std::string& path_) +{ + queryCppFileMetricsForPath(_return, + CppModuleMetricsQuery::File::path.like(path_ + '%')); +} + +void CppMetricsServiceHandler::getPagedCppFileMetricsForPath( + std::map>& _return, + const std::string& path_, + const std::int32_t pageSize_, + const std::int32_t pageNumber_) +{ + std::vector paged_files = pageMetrics(path_, pageSize_, pageNumber_); + queryCppFileMetricsForPath(_return, + CppModuleMetricsQuery::CppFileMetrics::file.in_range(paged_files.begin(), paged_files.end())); +} + +std::string CppMetricsServiceHandler::getPagingQuery( + const std::int32_t pageSize_, + const std::int32_t pageNumber_) +{ + if (pageSize_ <= 0) + { + core::InvalidInput ex; + ex.__set_msg("Invalid page size: " + std::to_string(pageSize_)); + throw ex; + } + + if (pageNumber_ <= 0) + { + core::InvalidInput ex; + ex.__set_msg("Invalid page number: " + std::to_string(pageNumber_)); + throw ex; + } + + const std::int32_t offset = (pageNumber_ - 1) * pageSize_; + return " LIMIT " + std::to_string(pageSize_) + " OFFSET " + std::to_string(offset); +} + } // cppmetrics } // service } // cc