diff --git a/.docker/Dockerfile b/.docker/Dockerfile index 870c810c33b9182d9e2566f928f10ead44ea4d0c..df8ef0a9f18f5754eae33686e832bd88f37da9de 100644 --- a/.docker/Dockerfile +++ b/.docker/Dockerfile @@ -1,7 +1,7 @@ -FROM debian:buster-backports +FROM debian:bullseye RUN apt-get update -RUN apt-get install -y cmake/buster-backports +RUN apt-get install -y cmake RUN apt-get install -y lcov RUN apt-get install -y doxygen graphviz RUN apt-get install -y clang-format-11 clang-tidy-11 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 334ff10baab25ac2ea08bec30592858282f6c3d2..5c35e94e03ba5a5aa6b8187c3370fdc04ca126fe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -85,9 +85,6 @@ test: - mkdir build - cd build - conan install .. -s "compiler.libcxx=libstdc++11" - - FILE_TO_BE_PATCHED="$(grep "std::unique_ptr<ContextAllocator> context_allocator) {}" -l -r $(conan config home))" - - echo "FILE_TO_BE_PATCHED=$FILE_TO_BE_PATCHED" - - sed -e "s|std::unique_ptr<ContextAllocator> context_allocator) {}|std::unique_ptr<ContextAllocator> /*context_allocator*/) {}|" -i $FILE_TO_BE_PATCHED - cmake -DCMAKE_BUILD_TYPE=Debug .. - cmake --build . -j - cmake --build . -j --target unit_test_coverage @@ -143,12 +140,8 @@ trigger_inttest: tags: [ cached-dind ] stage: deploy script: - - mkdir -p build - - cd build - - conan install .. -s "compiler.libcxx=libstdc++11" - - cmake .. - - cmake --build . --target doc-sphinx - - cp -r doc/sphinx_out ../public + - make doc + - cp -r build/doc/sphinx_out ../public test_pages: <<: *pages_prepare diff --git a/CMakeLists.txt b/CMakeLists.txt index 04a8e750d568ac331d0e0b30cd180109c7bad109..7f869346a6bb03539736b961ef4555f86117d5f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,9 +22,9 @@ cmake_minimum_required(VERSION 3.13) set(libcaosdb_VERSION 0.1.0) set(libcaosdb_COMPATIBLE_SERVER_VERSION_MAJOR 0) -set(libcaosdb_COMPATIBLE_SERVER_VERSION_MINOR 5) +set(libcaosdb_COMPATIBLE_SERVER_VERSION_MINOR 6) set(libcaosdb_COMPATIBLE_SERVER_VERSION_PATCH 0) -set(libcaosdb_COMPATIBLE_SERVER_VERSION_PRE_RELEASE "GRPC${libcaosdb_VERSION}") +set(libcaosdb_COMPATIBLE_SERVER_VERSION_PRE_RELEASE "") project(libcaosdb VERSION ${libcaosdb_VERSION} @@ -157,6 +157,8 @@ if("${CMAKE_BUILD_TYPE}" MATCHES "Debug") $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> + ) + target_include_directories(caosdb_grpc SYSTEM PUBLIC ${CONAN_INCLUDE_DIRS} ) else() @@ -171,25 +173,40 @@ target_include_directories(caosdb PUBLIC $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> +) +target_include_directories(caosdb SYSTEM PUBLIC ${CONAN_INCLUDE_DIRS} ) add_library(ccaosdb SHARED src/ccaosdb.cpp) target_link_libraries(ccaosdb - ${LIBCAOSDB} ${CONAN_LIBS} + ${LIBCAOSDB} ) +target_include_directories(ccaosdb PUBLIC + $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> + $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> + $<INSTALL_INTERFACE:include> +) +target_include_directories(ccaosdb SYSTEM PUBLIC + ${CONAN_INCLUDE_DIRS} +) + add_executable(ccaosdbcli EXCLUDE_FROM_ALL src/ccaosdbcli.c) target_include_directories(ccaosdbcli PUBLIC $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> +) +target_include_directories(ccaosdbcli SYSTEM PUBLIC ${CONAN_INCLUDE_DIRS} ) + target_link_libraries(ccaosdbcli - ccaosdb ${CONAN_LIBS} + ${LIBCAOSDB} + ccaosdb ) add_executable(cxxcaosdbcli EXCLUDE_FROM_ALL src/cxxcaosdbcli.cpp) @@ -197,6 +214,8 @@ target_include_directories(cxxcaosdbcli PUBLIC $<BUILD_INTERFACE:${libcaosdb_SOURCE_DIR}/include> $<BUILD_INTERFACE:${libcaosdb_BINARY_DIR}/include> $<INSTALL_INTERFACE:include> +) +target_include_directories(cxxcaosdbcli SYSTEM PUBLIC ${CONAN_INCLUDE_DIRS} ) target_link_libraries(cxxcaosdbcli diff --git a/Makefile b/Makefile index 819b9ca2910ce5571f1a80412f655f41afa023e5..544c8039b4f27ccef8b379d1009bfe9173666bc3 100644 --- a/Makefile +++ b/Makefile @@ -58,9 +58,28 @@ conan-install: conan install . -s $(CONAN_SETTINGS) --build=missing) .PHONY: conan-install +conan-install-debug: + conan install . -s $(CONAN_SETTINGS) -s build_type=Debug || \ + (echo "'conan install' failed, trying to build from sources..."; \ + conan install . -s $(CONAN_SETTINGS) -s build_type=Debug --build=missing) +.PHONY: conan-install-debug + conan-create: conan create . -s $(CONAN_SETTINGS) .PHONY: conan-create +conan-create-debug: + conan create . -s $(CONAN_SETTINGS) -s build_type=Debug +.PHONY: conan-create-debug + conan: conan-install conan-create .PHONY: conan + +doc: + mkdir -p build && cd build && conan install .. -s $(CONAN_SETTINGS) \ + && cmake .. && cmake --build . --target doc-sphinx \ + && echo "The documentation starts at build/doc/sphinx_out/index.html ." +.PHONY: doc + +conan-debug: conan-install-debug conan-create-debug +.PHONY: conan-debug diff --git a/cmake/CodeCoverage.cmake b/cmake/CodeCoverage.cmake index 27c6028d70eb608de54f879d4d6e4b59d070f2aa..8a26b4117b567dea4b5c3bb095964c2125ced813 100644 --- a/cmake/CodeCoverage.cmake +++ b/cmake/CodeCoverage.cmake @@ -136,6 +136,18 @@ include(CMakeParseArguments) option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE) +option(SKIP_CODE_COVERAGE "Skip code coverage" OFF) + +if (SKIP_CODE_COVERAGE) + return() +endif() + +find_library(covlib NAMES gcov lcov) +message(STATUS "covlib: >${covlib}<") +if (${covlib} STREQUAL "covlib-NOTFOUND") + message(STATUS "lcov or gcov libraries not found, skipping code coverage.") + return() +endif() # Check prereqs find_program( GCOV_PATH gcov ) diff --git a/conanfile.py b/conanfile.py index 09d5fe40f97736ac4174b455b819dcb01c0586e0..6fc869fb02b3e5577a5af06c647df1dcf3048958 100644 --- a/conanfile.py +++ b/conanfile.py @@ -14,14 +14,16 @@ class CaosdbConan(ConanFile): default_options = {"shared": False, "fPIC": True} generators = "cmake" requires = [ - ("boost/1.76.0"), + ("boost/1.77.0"), + ("grpc/1.39.1"), + ] + build_requires = [ ("gtest/1.11.0"), - ("grpc/1.38.0"), ] exports = ("*.cmake", "*CMakeLists.txt", "*.in", "*.h", "*.proto", "*.c", "*.cpp", "*.rst", "*.md", - ) + ) exports_sources = "src", "doc", "include", "test", "cmake", "proto" def config_options(self): diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 6c123d26653fcbabb57a0b4547b5230ef04a4936..6219cc6643b071d5993905b5027823d4a88ba5c2 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -18,6 +18,7 @@ # along with this program. If not, see <https://www.gnu.org/licenses/>. # +cmake_minimum_required(VERSION 3.13) find_package(Doxygen) if (DOXYGEN_FOUND) diff --git a/doc/README_SETUP.md b/doc/README_SETUP.md index 241ed18e84938a6402434bb8b5cc093b25352a10..ceb857617f4c4a890a15afa65a7a58e7db857e76 100644 --- a/doc/README_SETUP.md +++ b/doc/README_SETUP.md @@ -6,8 +6,8 @@ ## Build -We use [cmake](https://cmake.org) as build tool, with Conan as package manager. The compiler must support the C++17 -standard. +We use [cmake](https://cmake.org) as build tool, with Conan as package manager. +The compiler must support the C++17 standard. 0. clone/update the subrepo `git submodule update --init proto` 1. `mkdir build && cd build` @@ -30,7 +30,7 @@ of installation. ### How to build on MacOS -Instead of the above conan command (2.) use +If you use apple-clang as the compiler: Instead of the above conan command (2.) use 2. `conan install .. -s "compiler.cppstd=17"` @@ -102,7 +102,7 @@ The client will load the configuration file from the first existing file in the following locations (precedence from highest to lowest): 1. A file specified by the environment variable - `$CAOSDB_CLIENT_CONFIGURATION`. +`$CAOSDB_CLIENT_CONFIGURATION`. 2. `$PWD/caosdb_client.json` 3. `$PWD/caosdb-client.json` 4. `$PWD/.caosdb_client.json` @@ -121,12 +121,13 @@ file in the following locations (precedence from highest to lowest): For the tests there is a slightly different setup required (with option `-D CMAKE_BUILD_TYPE=Debug`) 1. `mkdir build && cd build/` -2. `conan install .. -s "compiler.libcxx=libstdc++11"` +2. `conan install .. ` (with gcc, append ` -s "compiler.libcxx=libstdc++11"`, with apple-clang, + append ` -s compiler.cppstd=17`) 3. `cmake -B . -D CMAKE_BUILD_TYPE=Debug ..` - * If your clang-format version is too old, formatting, linting etc. can be skipped: - `cmake -B . -D CMAKE_BUILD_TYPE=Debug -D SKIP_LINTING=ON ..` - * Depending on the clang version it might be necessary to also add - `-DCMAKE_CXX_FLAGS="-Wno-unused-parameter"` +* If your clang-format version is too old, formatting, linting etc. can be skipped: + `cmake -B . -D CMAKE_BUILD_TYPE=Debug -D SKIP_LINTING=ON ..` +* Depending on the clang version it might be necessary to also add + `-DCMAKE_CXX_FLAGS="-Wno-unused-parameter"` 5. `cmake --build .` #### Run #### diff --git a/include/caosdb/authentication.h b/include/caosdb/authentication.h index 070346c9366d89e7476f125b74feaea4ceb40a32..8e98a17e6d94fe118cf2fc478efbbf77733be4a6 100644 --- a/include/caosdb/authentication.h +++ b/include/caosdb/authentication.h @@ -28,10 +28,10 @@ * @brief Configuration and setup of the client authentication. */ #include "caosdb/utility.h" // for base64_encode -#include "grpcpp/impl/codegen/interceptor.h" // for Status -#include "grpcpp/impl/codegen/security/auth_context.h" // for AuthContext -#include "grpcpp/impl/codegen/status.h" // for Status -#include "grpcpp/impl/codegen/string_ref.h" // for string_ref +#include <grpcpp/impl/codegen/interceptor.h> // for Status +#include <grpcpp/impl/codegen/security/auth_context.h> // for AuthContext +#include <grpcpp/impl/codegen/status.h> // for Status +#include <grpcpp/impl/codegen/string_ref.h> // for string_ref #include <grpcpp/security/credentials.h> // for CallCredentials #include <map> // for multimap #include <memory> // for shared_ptr diff --git a/include/caosdb/certificate_provider.h b/include/caosdb/certificate_provider.h index e7d7a156efeaf05435fd3ccb8029549a82e38442..1fd4a80b630e53b8b704b29f7803837a3cff6ced 100644 --- a/include/caosdb/certificate_provider.h +++ b/include/caosdb/certificate_provider.h @@ -22,9 +22,9 @@ #ifndef CAOSDB_CERTIFICATE_PROVIDER_H #define CAOSDB_CERTIFICATE_PROVIDER_H -#include "boost/filesystem/path.hpp" // for path +#include <filesystem> // for path namespace caosdb::configuration { -using boost::filesystem::path; +using std::filesystem::path; class CertificateProvider { public: diff --git a/include/caosdb/configuration.h b/include/caosdb/configuration.h index 2c521e7b0f36c351dabd6f7341ea3bb393fd402c..649495f9a3722c9009edcb6b383f5c02941ade28 100644 --- a/include/caosdb/configuration.h +++ b/include/caosdb/configuration.h @@ -21,25 +21,25 @@ #ifndef CAOSDB_CONFIGURATION_H #define CAOSDB_CONFIGURATION_H -#include "boost/filesystem/operations.hpp" // for exists -#include "boost/filesystem/path.hpp" // for path -#include "boost/json/object.hpp" // for object -#include "boost/json/value.hpp" // for value -#include "boost/json/value_ref.hpp" // IWYU pragma: keep + +#include "caosdb/authentication.h" // for Authenticator, PlainPassw... +#include "caosdb/certificate_provider.h" // for CertificateProvider, path +#include "caosdb/exceptions.h" // for ConfigurationError +#include "caosdb/logging.h" // for SinkConfiguration, Loggin... +#include "caosdb/utility.h" // for load_json_file +#include <google/protobuf/arena.h> // for Arena +#include <google/protobuf/extension_set.h> // for Arena +#include <grpcpp/security/credentials.h> // for ChannelCredentials +#include <boost/json/object.hpp> // for object +#include <boost/json/value.hpp> // for value +#include <boost/json/value_ref.hpp> // for array, object // IWYU pragma: no_include "boost/json/fwd.hpp" -#include "caosdb/authentication.h" // for Authenticator, PlainPassw... -#include "caosdb/certificate_provider.h" // for CertificateProvider, path -#include "caosdb/exceptions.h" // for ConfigurationError -#include "caosdb/logging.h" -#include "caosdb/utility.h" // for load_json_file -#include "grpcpp/security/credentials.h" // for ChannelCredentials -#include <iosfwd> // for ostream -#include <memory> // for unique_ptr, shared_ptr -#include <string> // for string +#include <filesystem> // for path, exists +#include <iosfwd> // for ostream +#include <memory> // for shared_ptr, unique_ptr +#include <string> // for string namespace caosdb::configuration { -using boost::filesystem::exists; -using boost::filesystem::path; using boost::json::array; using boost::json::object; using boost::json::value; @@ -47,7 +47,10 @@ using caosdb::authentication::Authenticator; using caosdb::authentication::PlainPasswordAuthenticator; using caosdb::exceptions::ConfigurationError; using caosdb::utility::load_json_file; +using google::protobuf::Arena; using grpc::ChannelCredentials; +using std::filesystem::exists; +using std::filesystem::path; const std::string logger_name = "caosdb::configuration"; @@ -218,7 +221,10 @@ public: ConfigurationManager(ConfigurationManager const &) = delete; void operator=(ConfigurationManager const &) = delete; + inline static auto GetArena() -> Arena * { return &GetInstance().arena; } + private: + Arena arena; value json_configuration; ConnectionConfigurationHelper connection_configuration_helper; LoggingConfigurationHelper logging_configuration_helper; diff --git a/include/caosdb/connection.h b/include/caosdb/connection.h index 55a92fa1a7aca5e71911032f2d97fbcb88ca08db..ac1d05a419816ac21bd0a70ceafaf97428bd08da 100644 --- a/include/caosdb/connection.h +++ b/include/caosdb/connection.h @@ -27,10 +27,6 @@ * @date 2021-05-18 * @brief Configuration and setup of the connection. */ -#include <map> // for map -#include <memory> // for shared_ptr, unique_ptr -#include <string> // for string, basic_string -#include "boost/filesystem/path.hpp" // for path #include "caosdb/authentication.h" // for Authenticator #include "caosdb/configuration.h" // for ConnectionConfigura... #include "caosdb/entity/v1/main.grpc.pb.h" // for EntityTransactionSe... @@ -38,10 +34,13 @@ #include "caosdb/info/v1/main.grpc.pb.h" // for GeneralInfoService:... #include "caosdb/transaction.h" // for Transaction #include "caosdb/transaction_status.h" // for TransactionStatus -#include "grpcpp/channel.h" // for Channel +#include <filesystem> // for path +#include <grpcpp/channel.h> // for Channel +#include <map> // for map +#include <memory> // for shared_ptr, unique_ptr +#include <string> // for string, basic_string namespace caosdb::connection { -using boost::filesystem::path; using caosdb::authentication::Authenticator; using caosdb::configuration::ConnectionConfiguration; using caosdb::entity::v1::EntityTransactionService; @@ -50,6 +49,7 @@ using caosdb::info::VersionInfo; using caosdb::info::v1::GeneralInfoService; using caosdb::transaction::Transaction; using caosdb::transaction::TransactionStatus; +using std::filesystem::path; /** * @brief A reusable connection to a CaosDBServer. diff --git a/include/caosdb/constants.h.in b/include/caosdb/constants.h.in index bfec36bfbebf91fcd3e9eed38dd9ff305afc7a74..2661806d63a23b419da44de664f087b3c95c9a87 100644 --- a/include/caosdb/constants.h.in +++ b/include/caosdb/constants.h.in @@ -22,22 +22,25 @@ #ifndef CAOSDB_CONSTANTS_H #define CAOSDB_CONSTANTS_H +#ifndef __GNUC__ +#define __attribute__(x) +#endif #ifdef __cplusplus namespace caosdb { #endif // clang-format off -const int LIBCAOSDB_VERSION_MAJOR = @libcaosdb_VERSION_MAJOR@; -const int LIBCAOSDB_VERSION_MINOR = @libcaosdb_VERSION_MINOR@; -const int LIBCAOSDB_VERSION_PATCH = @libcaosdb_VERSION_PATCH@; -const int COMPATIBLE_SERVER_VERSION_MAJOR = @libcaosdb_COMPATIBLE_SERVER_VERSION_MAJOR@; -const int COMPATIBLE_SERVER_VERSION_MINOR = @libcaosdb_COMPATIBLE_SERVER_VERSION_MINOR@; -const int COMPATIBLE_SERVER_VERSION_PATCH = @libcaosdb_COMPATIBLE_SERVER_VERSION_PATCH@; -const char* COMPATIBLE_SERVER_VERSION_PRE_RELEASE = "@libcaosdb_COMPATIBLE_SERVER_VERSION_PRE_RELEASE@"; +static const int LIBCAOSDB_VERSION_MAJOR = @libcaosdb_VERSION_MAJOR@; +static const int LIBCAOSDB_VERSION_MINOR = @libcaosdb_VERSION_MINOR@; +static const int LIBCAOSDB_VERSION_PATCH = @libcaosdb_VERSION_PATCH@; +static const int COMPATIBLE_SERVER_VERSION_MAJOR = @libcaosdb_COMPATIBLE_SERVER_VERSION_MAJOR@; +static const int COMPATIBLE_SERVER_VERSION_MINOR = @libcaosdb_COMPATIBLE_SERVER_VERSION_MINOR@; +static const int COMPATIBLE_SERVER_VERSION_PATCH = @libcaosdb_COMPATIBLE_SERVER_VERSION_PATCH@; +__attribute__((unused)) static const char* COMPATIBLE_SERVER_VERSION_PRE_RELEASE = "@libcaosdb_COMPATIBLE_SERVER_VERSION_PRE_RELEASE@"; /** * Precedence of configuration files from highest to lowest. */ -const char* LIBCAOSDB_CONFIGURATION_FILES_PRECEDENCE[] = { +__attribute__((unused)) static const char* LIBCAOSDB_CONFIGURATION_FILES_PRECEDENCE[] = { "$CAOSDB_CLIENT_CONFIGURATION", "caosdb_client.json", "caosdb-client.json", diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h index f109734fc741d4688a1b6b2772378c1d6c8b772b..2ff36d7242c5bcb8739bbca839e749825e4f6825 100644 --- a/include/caosdb/entity.h +++ b/include/caosdb/entity.h @@ -36,28 +36,27 @@ #include "caosdb/protobuf_helper.h" // for get_arena #include "caosdb/status_code.h" // for StatusCode #include "caosdb/value.h" // for Value -#include <boost/filesystem/operations.hpp> // for exists, is_di... -#include <boost/filesystem/path.hpp> // for path #include <boost/log/core/record.hpp> // for record #include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring... #include <boost/log/sources/record_ostream.hpp> // for basic_record_... #include <boost/preprocessor/seq/limits/enum_256.hpp> // for BOOST_PP_SEQ_... #include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_... #include <cstdint> // for int64_t +#include <filesystem> // for path +#include <google/protobuf/arena.h> // for Arena #include <google/protobuf/message.h> // for RepeatedPtrField #include <iosfwd> // for streamsize #include <iterator> // for iterator, output_iterato... #include <map> // for map -#include <random> // for mt19937, rand... #include <stdexcept> // for out_of_range #include <string> // for string, basic... #include <utility> // for move #include <vector> // for vector namespace caosdb::entity { -using boost::filesystem::exists; -using boost::filesystem::is_directory; using caosdb::entity::v1::IdResponse; +using std::filesystem::exists; +using std::filesystem::is_directory; using ProtoParent = caosdb::entity::v1::Parent; using ProtoProperty = caosdb::entity::v1::Property; using ProtoEntity = caosdb::entity::v1::Entity; @@ -113,7 +112,7 @@ const std::map<Role, std::string> role_names = {{Role::UNSPECIFIED, "UNSPECIFIED struct FileDescriptor { FileTransmissionId *file_transmission_id; ProtoFileDescriptor *wrapped; - boost::filesystem::path local_path; + std::filesystem::path local_path; }; /** @@ -372,6 +371,9 @@ private: inline Messages() : RepeatedPtrFieldWrapper<Message, ProtoMessage>(){}; }; +/////////////////////////////////////////////////////////////////////////////// +// class Parent /////////////////////////////////////////////////////////////// + /** * Parent of an Entity. * @@ -489,6 +491,9 @@ private: : RepeatedPtrFieldWrapper<Parent, ProtoParent>(wrapped){}; }; +/////////////////////////////////////////////////////////////////////////////// +// class Property ///////////////////////////////////////////////////////////// + /** * Property of an Entity. * @@ -671,6 +676,9 @@ private: : RepeatedPtrFieldWrapper<Property, ProtoProperty>(wrapped){}; }; +/////////////////////////////////////////////////////////////////////////////// +// class Entity /////////////////////////////////////////////////////////////// + /** * Entity is the central and basic data object of CaosDB. * @@ -712,7 +720,7 @@ public: properties.wrapped = this->wrapped->mutable_properties(); parents.wrapped = this->wrapped->mutable_parents(); }; - explicit inline Entity(EntityResponse *response) : Entity(response->release_entity()) { + explicit inline Entity(EntityResponse *response) : Entity(response->mutable_entity()) { this->errors.wrapped->Swap(response->mutable_errors()); this->warnings.wrapped->Swap(response->mutable_warnings()); this->infos.wrapped->Swap(response->mutable_infos()); @@ -775,7 +783,7 @@ public: this->value = other.value; this->properties = other.properties; this->parents = other.parents; - this->file_descriptor.local_path = boost::filesystem::path(other.file_descriptor.local_path); + this->file_descriptor.local_path = std::filesystem::path(other.file_descriptor.local_path); this->file_descriptor.file_transmission_id->CopyFrom( *other.file_descriptor.file_transmission_id); this->file_descriptor.wrapped->CopyFrom(*other.file_descriptor.wrapped); @@ -862,19 +870,17 @@ public: auto SetFilePath(const std::string &path) -> void; inline auto HasFile() const -> bool { return !this->file_descriptor.local_path.empty(); } - auto SetFileTransmissionRegistrationId(const std::string ®istration_id) -> void; inline auto SetFileTransmissionId(FileTransmissionId *file_transmission_id) -> void { - file_transmission_id->set_file_id(GetNextFileId()); file_descriptor.file_transmission_id = file_transmission_id; } inline auto GetFileDescriptor() -> FileDescriptor & { return this->file_descriptor; } - inline auto GetLocalPath() const noexcept -> const boost::filesystem::path & { + inline auto GetLocalPath() const noexcept -> const std::filesystem::path & { return this->file_descriptor.local_path; } - inline auto SetLocalPath(const boost::filesystem::path &local_path) noexcept -> StatusCode { + inline auto SetLocalPath(const std::filesystem::path &local_path) noexcept -> StatusCode { if (GetRole() != Role::FILE) { CAOSDB_LOG_WARN(logger_name) << "Entity::SetLocalPath failed. This is not a file entity."; return StatusCode::NOT_A_FILE_ENTITY; @@ -911,20 +917,10 @@ public: } private: - inline auto GetNextFileId() -> std::string { - std::string str = "0123456789abcdef"; - std::mt19937 generator(std::random_device{}()); - std::uniform_int_distribution<int> distribution(0, str.size() - 1); - std::string result(10, '\0'); - - for (auto &dis : result) { - dis = str[distribution(generator)]; - } - return result; - } static auto CreateMessagesField() -> RepeatedPtrField<ProtoMessage> *; auto SetId(const std::string &id) -> void; auto SetVersionId(const std::string &id) -> void; + auto inline GetArena() const -> Arena * { return get_arena(); } private: FileDescriptor file_descriptor; diff --git a/include/caosdb/file_transmission/file_reader.h b/include/caosdb/file_transmission/file_reader.h index 5820c1e9294c76f0f777a6e7cfae9cde7ebf490f..14f8614896de79b15e9bb793a04ac17f40f27fec 100644 --- a/include/caosdb/file_transmission/file_reader.h +++ b/include/caosdb/file_transmission/file_reader.h @@ -49,21 +49,19 @@ #ifndef CAOSDB_FILE_TRANSMISSION_FILE_READER_H #define CAOSDB_FILE_TRANSMISSION_FILE_READER_H -#include <boost/filesystem/fstream.hpp> // for ifstream -#include <boost/filesystem/operations.hpp> // for exists -#include <boost/filesystem/path.hpp> // for path -#include <cstddef> // for size_t -#include <fstream> // for ifstream, size_t -#include <string> // for string +#include <cstddef> // for size_t +#include <filesystem> // for ifstream +#include <fstream> // for ifstream, size_t +#include <string> // for string namespace caosdb::transaction { -using boost::filesystem::exists; -using boost::filesystem::ifstream; -using boost::filesystem::path; +using std::ifstream; +using std::filesystem::exists; +using std::filesystem::path; class FileReader final { public: - FileReader(boost::filesystem::path filename); + FileReader(std::filesystem::path filename); ~FileReader() = default; @@ -81,7 +79,7 @@ private: void openFile(); std::ifstream stream_; - boost::filesystem::path filename_; + std::filesystem::path filename_; unsigned long long size_; }; diff --git a/include/caosdb/file_transmission/file_writer.h b/include/caosdb/file_transmission/file_writer.h index 801d74b9547951d2a3b86ed4b333bfb4b7035aa9..165178b1e3b44f9d3208220d1422af1bb61d0833 100644 --- a/include/caosdb/file_transmission/file_writer.h +++ b/include/caosdb/file_transmission/file_writer.h @@ -49,15 +49,15 @@ #ifndef CAOSDB_FILE_TRANSMISSION_FILE_WRITER_H #define CAOSDB_FILE_TRANSMISSION_FILE_WRITER_H -#include <boost/filesystem/path.hpp> // for path -#include <fstream> // for ofstream -#include <string> // for string +#include <filesystem> // for path +#include <fstream> // for ofstream +#include <string> // for string namespace caosdb::transaction { class FileWriter final { public: - FileWriter(boost::filesystem::path filename); + FileWriter(std::filesystem::path filename); ~FileWriter() = default; @@ -73,7 +73,7 @@ private: void openFile(); std::ofstream stream_; - boost::filesystem::path filename_; + std::filesystem::path filename_; }; } // namespace caosdb::transaction diff --git a/include/caosdb/logging.h b/include/caosdb/logging.h index 35c5fdfa1a72ba5f55933f3bd99aa93f313c3e33..eb99f9a51b3630ce48849acf935b316044aa82b2 100644 --- a/include/caosdb/logging.h +++ b/include/caosdb/logging.h @@ -24,12 +24,11 @@ #define CAOSDB_LOGGING_H #include "caosdb/log_level.h" // for CAOSDB_LOG_... -#include "boost/log/sources/global_logger_storage.hpp" // for BOOST_LOG_I... -#include "boost/log/sources/record_ostream.hpp" // IWYU pragma: keep -#include "boost/log/sources/severity_channel_logger.hpp" // for BOOST_LOG_C... -#include "boost/log/utility/setup/settings.hpp" // for settings -#include "boost/smart_ptr/intrusive_ptr.hpp" // for intrusive_ptr -#include "boost/smart_ptr/intrusive_ref_counter.hpp" // for intrusive_p... +#include <boost/log/sources/record_ostream.hpp> // IWYU pragma: keep +#include <boost/log/sources/severity_channel_logger.hpp> // for BOOST_LOG_C... +#include <boost/log/utility/setup/settings.hpp> // for settings +#include <boost/smart_ptr/intrusive_ptr.hpp> // for intrusive_ptr +#include <boost/smart_ptr/intrusive_ref_counter.hpp> // for intrusive_p... #include <memory> // for shared_ptr #include <string> // for string #include <vector> // for vector @@ -40,7 +39,17 @@ const std::string logger_name = "caosdb::logging"; typedef boost::log::sources::severity_channel_logger_mt<int, std::string> boost_logger_class; -BOOST_LOG_GLOBAL_LOGGER(logger, boost_logger_class) +class logger { +public: + static auto get() -> boost_logger_class & { return logger::GetInstance()._logger_instance; } + +private: + static logger &GetInstance() { + static logger instance; + return instance; + } + boost_logger_class _logger_instance; +}; /** * This class stores the integer log level. diff --git a/include/caosdb/protobuf_helper.h b/include/caosdb/protobuf_helper.h index 63b2c54cdfaae5eef33705ac7074e11c1caf3653..ef4cb8383eb384cd058a3f210c9d27f99b199658 100644 --- a/include/caosdb/protobuf_helper.h +++ b/include/caosdb/protobuf_helper.h @@ -22,9 +22,8 @@ #ifndef CAOSDB_PROTOBUF_HELPER_H #define CAOSDB_PROTOBUF_HELPER_H -#include <google/protobuf/arena.h> // for Arena -// IWYU pragma: no_include "google/protobuf/extension_set.h" -// IWYU pragma: no_include "google/protobuf/generated_message_util.h" +// IWYU pragma: no_include <google/protobuf/extension_set.h> +#include <google/protobuf/arena.h> // for Arena #include <google/protobuf/util/json_util.h> // for JsonOptions, MessageToJs... #include <string> // for string @@ -41,6 +40,7 @@ namespace caosdb::utility { using google::protobuf::Arena; auto get_arena() -> Arena *; +auto reset_arena() -> void; /** * Abstract wrapper class for Protobuf messages. diff --git a/include/caosdb/status_code.h b/include/caosdb/status_code.h index e1a382191b5bd4559c554e2fc3e084103c27c3cc..41dad5bddd918ac5cc42e577798676bcf8b6bea4 100644 --- a/include/caosdb/status_code.h +++ b/include/caosdb/status_code.h @@ -67,7 +67,7 @@ enum StatusCode { TRANSACTION_TYPE_ERROR = 26, UNSUPPORTED_FEATURE = 27, ORIGINAL_ENTITY_MISSING_ID = 28, - EXTERN_C_ASSIGNMENT_ERROR = 29, + // EXTERN_C_ASSIGNMENT_ERROR = 29, ENTITY_CANNOT_HAVE_A_DATA_TYPE = 30, ENTITY_CANNOT_HAVE_A_VALUE = 31, NOT_A_FILE_ENTITY = 32, diff --git a/include/caosdb/transaction.h b/include/caosdb/transaction.h index b93be12f37e2e43a395de6c376b13d61f4195cff..0e11d3f1a5d9145795b2bdcd4e1c82c31e360aa2 100644 --- a/include/caosdb/transaction.h +++ b/include/caosdb/transaction.h @@ -55,12 +55,12 @@ return StatusCode::TRANSACTION_STATUS_ERROR; \ } \ switch (this->transaction_type) { \ - case NONE: \ + case TransactionType::NONE: \ this->transaction_type = TransactionType::READ_ONLY; \ break; \ - case READ_ONLY: \ + case TransactionType::READ_ONLY: \ break; \ - case MIXED_READ_AND_WRITE: \ + case TransactionType::MIXED_READ_AND_WRITE: \ break; \ default: \ CAOSDB_LOG_ERROR_AND_RETURN_STATUS( \ @@ -91,11 +91,11 @@ return StatusCode::TRANSACTION_STATUS_ERROR; \ } \ switch (this->transaction_type) { \ - case NONE: \ + case TransactionType::NONE: \ this->transaction_type = TransactionType::MIXED_WRITE; \ - case DELETE: \ - case MIXED_WRITE: \ - case MIXED_READ_AND_WRITE: \ + case TransactionType::DELETE_ONLY: \ + case TransactionType::MIXED_WRITE: \ + case TransactionType::MIXED_READ_AND_WRITE: \ break; \ default: \ CAOSDB_LOG_ERROR_AND_RETURN_STATUS( \ @@ -113,11 +113,11 @@ return StatusCode::TRANSACTION_STATUS_ERROR; \ } \ switch (this->transaction_type) { \ - case NONE: \ + case TransactionType::NONE: \ this->transaction_type = TransactionType::MIXED_WRITE; \ - case INSERT: \ - case MIXED_WRITE: \ - case MIXED_READ_AND_WRITE: \ + case TransactionType::INSERT_ONLY: \ + case TransactionType::MIXED_WRITE: \ + case TransactionType::MIXED_READ_AND_WRITE: \ break; \ default: \ CAOSDB_LOG_ERROR_AND_RETURN_STATUS( \ @@ -135,11 +135,11 @@ return StatusCode::TRANSACTION_STATUS_ERROR; \ } \ switch (this->transaction_type) { \ - case NONE: \ + case TransactionType::NONE: \ this->transaction_type = TransactionType::MIXED_WRITE; \ - case UPDATE: \ - case MIXED_WRITE: \ - case MIXED_READ_AND_WRITE: \ + case TransactionType::UPDATE_ONLY: \ + case TransactionType::MIXED_WRITE: \ + case TransactionType::MIXED_READ_AND_WRITE: \ break; \ default: \ CAOSDB_LOG_ERROR_AND_RETURN_STATUS( \ @@ -287,9 +287,9 @@ public: enum TransactionType { NONE, //!< Unspecified or not specified yet. READ_ONLY, //!< Only retrievals (by id, by query) - INSERT, //!< Only insertions - UPDATE, //!< Only updates - DELETE, //!< Only deletions + INSERT_ONLY, //!< Only insertions + UPDATE_ONLY, //!< Only updates + DELETE_ONLY, //!< Only deletions MIXED_WRITE, //!< Only insertions, deletions, updates MIXED_READ_AND_WRITE //!< all kind of transaction. }; @@ -406,7 +406,7 @@ public: * Instead, do Execute() or WaitForIt() and only call this method afterwards. */ [[nodiscard]] inline auto GetResultSet() const noexcept -> const ResultSet & { - if (!this->result_set) { + if (this->result_set == nullptr) { CAOSDB_LOG_ERROR(logger_name) << "GetResultSet was called before the transaction has terminated. This is a programming " "error of the code which uses the transaction."; @@ -517,11 +517,6 @@ private: std::vector<FileDescriptor> upload_files; std::map<std::string, FileDescriptor> download_files; - // auto RegisterUploadFile(RegisterFileUploadResponse *response) -> void; - auto UploadFile(FileUploadResponse *response, const FileDescriptor &file_descriptor, - const std::string ®istration_id) -> void; - auto DownloadFile(FileDownloadResponse *response, const FileTransmissionId &file_transmission_id) - -> void; bool has_query = false; TransactionType transaction_type = TransactionType::NONE; mutable std::unique_ptr<ResultSet> result_set; diff --git a/include/caosdb/utility.h b/include/caosdb/utility.h index 5af1b491c0b5b9d48606ba6b46130b3ef3de1d9c..0a4d65e883ccfb6cc8f41d1c412bef5433b89417 100644 --- a/include/caosdb/utility.h +++ b/include/caosdb/utility.h @@ -25,15 +25,13 @@ #include "caosdb/entity.h" // for Importance, Role #include <boost/beast/core/detail/base64.hpp> // for encoded_size #include <boost/beast/core/detail/base64.ipp> // for encode -#include <boost/filesystem/operations.hpp> // for exists -#include <boost/filesystem/path.hpp> // for path -#include <boost/filesystem/fstream.hpp> // for basic_ifstream, ifstream #include <boost/filesystem/string_file.hpp> // for load_string_file #include <boost/json/stream_parser.hpp> // for stream_parser #include <boost/json/value.hpp> // for value #include <boost/lexical_cast.hpp> // for lexical_cast #include <cassert> // for assert #include <cstdlib> // for getenv +#include <filesystem> // for path #include <fstream> // for basic_istream<>::__ist... #include <memory> // for allocator, unique_ptr #include <stdexcept> // for logic_error @@ -42,11 +40,11 @@ #include <typeinfo> // for type_info namespace caosdb::utility { -using boost::filesystem::exists; -using boost::filesystem::ifstream; -using boost::filesystem::path; using boost::json::stream_parser; using boost::json::value; +using std::ifstream; +using std::filesystem::exists; +using std::filesystem::path; /** * @brief Get the name of the enum value. May be useful for higher-order CaosDB clients. @@ -86,9 +84,9 @@ auto getEnumValueFromName<caosdb::entity::Role>(const std::string &name) -> caos /** * @brief Read a text file into a string and return the file's content. */ -inline auto load_string_file(const path &path) -> std::string { +inline auto load_string_file(const path &file_path) -> std::string { std::string result; - boost::filesystem::load_string_file(path, result); + boost::filesystem::load_string_file(file_path.string(), result); return result; } diff --git a/include/ccaosdb.h b/include/ccaosdb.h index 4d1b99dd151fbf09a53d9b80c0963ee3d3368c67..48d0da757351508ed194e52635670d0c24e53164 100644 --- a/include/ccaosdb.h +++ b/include/ccaosdb.h @@ -20,10 +20,14 @@ * */ -#include <cstdint> // for int64_t - +#ifndef CCAOSDB_H +#define CCAOSDB_H #ifdef __cplusplus +#include <cstdint> // for int64_t extern "C" { +#else +#include <stdint.h> // for int64_t +#include <stdbool.h> // for bool #endif /** @@ -70,7 +74,7 @@ int caosdb_status_code_OTHER_CLIENT_ERROR(); */ typedef struct caosdb_connection_connection { void *wrapped_connection; - bool _deletable = false; + bool _deletable; } caosdb_connection_connection; /** @@ -82,7 +86,7 @@ typedef struct caosdb_connection_connection { */ typedef struct caosdb_connection_connection_configuration { void *wrapped_connection_configuration; - bool _deletable = false; + bool _deletable; } caosdb_connection_connection_configuration; /** @@ -102,12 +106,12 @@ typedef struct caosdb_info_version_info { typedef struct caosdb_connection_certificate_provider { void *wrapped_certificate_provider; - bool _deletable = false; + bool _deletable; } caosdb_connection_certificate_provider; typedef struct caosdb_authentication_authenticator { void *wrapped_authenticator; - bool _deletable = false; + bool _deletable; } caosdb_authentication_authenticator; /** @@ -266,7 +270,7 @@ int caosdb_connection_connection_manager_get_connection(caosdb_connection_connec typedef struct caosdb_transaction_transaction { void *wrapped_transaction; - bool _deletable = false; + bool _deletable; } caosdb_transaction_transaction; /** @@ -292,12 +296,12 @@ int caosdb_transaction_transaction_execute(caosdb_transaction_transaction *trans typedef struct caosdb_transaction_result_set { void *wrapped_result_set; - bool _deletable = false; + bool _deletable; } caosdb_transaction_result_set; typedef struct caosdb_entity_entity { void *wrapped_entity; - bool _deletable = false; + bool _deletable; } caosdb_entity_entity; int caosdb_transaction_transaction_get_result_set(caosdb_transaction_transaction *transaction, @@ -348,27 +352,27 @@ int caosdb_transaction_transaction_delete_by_id(caosdb_transaction_transaction * typedef struct caosdb_entity_property { void *wrapped_property; - bool _deletable = false; + bool _deletable; } caosdb_entity_property; typedef struct caosdb_entity_parent { void *wrapped_parent; - bool _deletable = false; + bool _deletable; } caosdb_entity_parent; typedef struct caosdb_entity_message { void *wrapped_message; - bool _deletable = false; + bool _deletable; } caosdb_entity_message; typedef struct caosdb_entity_value { void *wrapped_value; - bool _deletable = false; + bool _deletable; } caosdb_entity_value; typedef struct caosdb_entity_datatype { void *wrapped_datatype; - bool _deletable = false; + bool _deletable; } caosdb_entity_datatype; // GETTERS FOR EVERYTHING @@ -494,3 +498,4 @@ int caosdb_entity_parent_set_name(caosdb_entity_parent *parent, const char *name #ifdef __cplusplus } #endif +#endif diff --git a/proto b/proto index 9fa41dce325d370eb8da60a77e921d4a0618f513..533c8e7341d0659e3cc43d834793a7a965703f55 160000 --- a/proto +++ b/proto @@ -1 +1 @@ -Subproject commit 9fa41dce325d370eb8da60a77e921d4a0618f513 +Subproject commit 533c8e7341d0659e3cc43d834793a7a965703f55 diff --git a/src/caosdb/authentication.cpp b/src/caosdb/authentication.cpp index 50ff24455ac87227f475775974abae1228fc50d3..ecfbe35344f557671d8529770f73a3987c389ab0 100644 --- a/src/caosdb/authentication.cpp +++ b/src/caosdb/authentication.cpp @@ -19,13 +19,15 @@ * */ #include "caosdb/authentication.h" -#include "grpcpp/security/credentials.h" // for MetadataCredentialsPlugin -#include <grpcpp/impl/codegen/status.h> // for Status, Status::OK -#include <grpcpp/impl/codegen/string_ref.h> // for string_ref -#include <map> // for multimap -#include <memory> // for allocator, shared_ptr -#include <string> // for basic_string, operator+ -#include <utility> // for pair, move, make_pair +#include <grpcpp/impl/codegen/interceptor.h> // for Status +#include <grpcpp/impl/codegen/security/auth_context.h> // for AuthContext +#include <grpcpp/impl/codegen/status.h> // for Status, Status::OK +#include <grpcpp/impl/codegen/string_ref.h> // for string_ref +#include <grpcpp/security/credentials.h> // for MetadataCredentialsPlugin +#include <map> // for multimap +#include <memory> // for allocator, shared_ptr +#include <string> // for basic_string, operator+ +#include <utility> // for pair, move, make_pair namespace caosdb::authentication { using caosdb::utility::base64_encode; diff --git a/src/caosdb/configuration.cpp b/src/caosdb/configuration.cpp index edce302e00bcb5645d734e2ff577be23d0a8bd67..90cc97b3cebc1b39a1b376805ae73cc068173ef7 100644 --- a/src/caosdb/configuration.cpp +++ b/src/caosdb/configuration.cpp @@ -19,15 +19,6 @@ * */ #include "caosdb/configuration.h" -#include "boost/iterator/iterator_facade.hpp" // for iterator_facad... -#include "boost/json/impl/object.hpp" // for object::at -#include "boost/json/string.hpp" // for string -#include "boost/json/string_view.hpp" // for string_view -#include "boost/log/core/record.hpp" // for record -#include "boost/log/detail/attachable_sstream_buf.hpp" // for basic_ostring... -#include "boost/log/sources/record_ostream.hpp" // for basic_record_o... -#include "boost/preprocessor/seq/limits/enum_256.hpp" // for BOOST_PP_SEQ_E... -#include "boost/preprocessor/seq/limits/size_256.hpp" // for BOOST_PP_SEQ_S... #include "caosdb/authentication.h" // for Authenticator #include "caosdb/connection.h" // for ConnectionManager #include "caosdb/constants.h" // for LIBCAOSDB_CONF... @@ -35,6 +26,17 @@ #include "caosdb/log_level.h" // for CAOSDB_DEFAULT... #include "caosdb/status_code.h" // for StatusCode #include "caosdb/utility.h" // for get_home_direc... +#include <boost/json/impl/object.hpp> // for object::at +#include <boost/json/object.hpp> // for object, objec... +#include <boost/json/string.hpp> // for string +#include <boost/json/string_view.hpp> // for string_view +#include <boost/json/value.hpp> // for value, key_va... +#include <boost/json/value_ref.hpp> // for object +#include <boost/log/core/record.hpp> // for record +#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring... +#include <boost/log/sources/record_ostream.hpp> // for basic_record_o... +#include <boost/preprocessor/seq/limits/enum_256.hpp> // for BOOST_PP_SEQ_E... +#include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_S... #include <cassert> // for assert #include <cstdlib> // for getenv #include <cstring> // for strcmp @@ -43,12 +45,11 @@ #include <grpcpp/security/credentials.h> // for SslCredentials #include <iterator> // for next #include <map> // for map +#include <sstream> // for basic_stringb... #include <stdexcept> // for out_of_range #include <string> // for string, operator+ namespace caosdb::configuration { -using boost::filesystem::exists; -using boost::filesystem::path; using boost::json::object; using boost::json::value; using caosdb::authentication::Authenticator; @@ -66,6 +67,8 @@ using caosdb::utility::load_string_file; using grpc::InsecureChannelCredentials; using grpc::SslCredentials; using grpc::SslCredentialsOptions; +using std::filesystem::exists; +using std::filesystem::path; PemFileCertificateProvider::PemFileCertificateProvider(const path &path) { this->certificate_provider = load_string_file(path); @@ -471,12 +474,12 @@ auto ConfigurationManager::InitializeDefaults() -> int { // NOLINT configuration_file_path = std::make_unique<path>(); const path raw(configuration_file); // resolve home directory - for (auto segment = raw.begin(); segment != raw.end(); ++segment) { - if (segment->string() == "$HOME") { + for (const auto &segment : raw) { + if (segment.string() == "$HOME") { path expanded_home(get_home_directory()); *configuration_file_path /= expanded_home; } else { - *configuration_file_path /= *segment; + *configuration_file_path /= segment; } } if (exists(*configuration_file_path)) { diff --git a/src/caosdb/file_transmission/download_request_handler.cpp b/src/caosdb/file_transmission/download_request_handler.cpp index cbe79e93eb89261d1d85484cf39f4ad5deecba18..23520e0d78c5c8c8606ad5acf7611ba7c4806fc4 100644 --- a/src/caosdb/file_transmission/download_request_handler.cpp +++ b/src/caosdb/file_transmission/download_request_handler.cpp @@ -51,7 +51,6 @@ #include "caosdb/protobuf_helper.h" // for get_arena #include "caosdb/status_code.h" // for GENERIC_RPC_E... #include "caosdb/transaction_status.h" // for TransactionStatus -#include <boost/filesystem/path.hpp> // for operator<<, path #include <boost/log/core/record.hpp> // for record #include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring... #include <boost/log/sources/record_ostream.hpp> // for basic_record_... @@ -59,13 +58,14 @@ #include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_... #include <exception> // IWYU pragma: keep // IWYU pragma: no_include <bits/exception.h> +#include <filesystem> // for operator<<, path #include <google/protobuf/arena.h> // for Arena #include <grpcpp/impl/codegen/async_stream.h> // for ClientAsyncRe... #include <grpcpp/impl/codegen/client_context.h> // for ClientContext #include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue #include <grpcpp/impl/codegen/status.h> // for Status #include <grpcpp/impl/codegen/status_code_enum.h> // for OK, UNAUTHENT... -#include <iostream> // for char_traits +#include <sstream> // for streamsize #include <stdexcept> // for runtime_error #include <string> // for string, opera... #include <utility> // for move @@ -130,7 +130,8 @@ void DownloadRequestHandler::handleNewCallState() { << ", download_id = " << file_descriptor_.file_transmission_id; fileWriter_ = std::make_unique<FileWriter>(file_descriptor_.local_path); - request_->mutable_file_transmission_id()->CopyFrom(*(file_descriptor_.file_transmission_id)); + auto *tid = request_->mutable_file_transmission_id(); + tid->CopyFrom(*(file_descriptor_.file_transmission_id)); rpc_ = stub_->PrepareAsyncFileDownload(&ctx_, *request_, cq_); diff --git a/src/caosdb/file_transmission/file_reader.cpp b/src/caosdb/file_transmission/file_reader.cpp index 1a78e5a76513ae0aaf94b2ae4967af5d7b66e0c0..3f82b8c8c775d38f2a75e2a995ce7cfa8bb7cceb 100644 --- a/src/caosdb/file_transmission/file_reader.cpp +++ b/src/caosdb/file_transmission/file_reader.cpp @@ -48,13 +48,12 @@ */ #include "caosdb/file_transmission/file_reader.h" #include "caosdb/file_transmission/file_error.h" // for FileIOError -#include <boost/filesystem/path.hpp> // for path +#include <filesystem> // for path #include <utility> // for move namespace caosdb::transaction { -FileReader::FileReader(boost::filesystem::path filename) - : filename_(std::move(filename)), size_(0) { +FileReader::FileReader(std::filesystem::path filename) : filename_(std::move(filename)), size_(0) { this->openFile(); } @@ -79,7 +78,7 @@ std::size_t FileReader::read(std::string &buffer) { if (bufferSize > 0) { // TODO(henrik): fix nolint if (!stream_.read(&buffer[0], bufferSize)) { // NOLINT - throw FileIOError("Can't read file: " + filename_.string()); + throw FileIOError("Can't read data from file: " + filename_.string()); } bytesRead = static_cast<std::size_t>(stream_.gcount()); diff --git a/src/caosdb/file_transmission/file_writer.cpp b/src/caosdb/file_transmission/file_writer.cpp index 2c7f2a6000718366f846a4be61dd5c2144370a65..0f0161fbcafe1df7f6ffa271dcce8af9cc10fe82 100644 --- a/src/caosdb/file_transmission/file_writer.cpp +++ b/src/caosdb/file_transmission/file_writer.cpp @@ -48,12 +48,12 @@ */ #include "caosdb/file_transmission/file_writer.h" #include "caosdb/file_transmission/file_error.h" // for FileIOError -#include <boost/filesystem/path.hpp> // for path +#include <filesystem> // for path #include <utility> // for move namespace caosdb::transaction { -FileWriter::FileWriter(boost::filesystem::path filename) : filename_(std::move(filename)) { +FileWriter::FileWriter(std::filesystem::path filename) : filename_(std::move(filename)) { this->openFile(); } diff --git a/src/caosdb/file_transmission/upload_request_handler.cpp b/src/caosdb/file_transmission/upload_request_handler.cpp index bc74391753a0c7c3dce01f80d8fa67acc9e782cd..71f1106b78397a435638a0a1695bb86cb02a3edc 100644 --- a/src/caosdb/file_transmission/upload_request_handler.cpp +++ b/src/caosdb/file_transmission/upload_request_handler.cpp @@ -52,7 +52,6 @@ #include "caosdb/status_code.h" // for GENERIC_RPC_E... #include "caosdb/transaction_status.h" // for TransactionStatus #include <algorithm> // for min -#include <boost/filesystem/path.hpp> // for operator<<, path #include <boost/log/core/record.hpp> // for record #include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring... #include <boost/log/sources/record_ostream.hpp> // for basic_record_... @@ -61,6 +60,7 @@ #include <cstdint> // for uint64_t #include <exception> // IWYU pragma: keep // IWYU pragma: no_include <bits/exception.h> +#include <filesystem> // for operator<<, path #include <google/protobuf/arena.h> // for Arena #include <grpcpp/impl/codegen/async_stream.h> // for ClientAsyncWr... #include <grpcpp/impl/codegen/call_op_set.h> // for WriteOptions @@ -68,7 +68,7 @@ #include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue #include <grpcpp/impl/codegen/status.h> // for Status #include <grpcpp/impl/codegen/status_code_enum.h> // for OK, UNAUTHENT... -#include <iostream> // for endl, streamsize +#include <sstream> // for streamsize #include <string> // for basic_string #include <utility> // for move diff --git a/src/caosdb/logging.cpp b/src/caosdb/logging.cpp index 4070786b2bb4073da5800f4a57b9c0dfcff5d6ac..22cda0b65f5428fe485f62972fde3aac70f84080 100644 --- a/src/caosdb/logging.cpp +++ b/src/caosdb/logging.cpp @@ -19,23 +19,24 @@ * */ #include "caosdb/logging.h" -#include "boost/core/swap.hpp" // for swap -#include "boost/iterator/iterator_facade.hpp" -#include "boost/log/attributes/clock.hpp" -#include "boost/log/core/core.hpp" // for core -#include "boost/log/core/record.hpp" -#include "boost/log/sources/record_ostream.hpp" -#include "boost/log/utility/setup/from_settings.hpp" -#include "boost/log/utility/setup/settings.hpp" -#include "boost/move/utility_core.hpp" // for move -#include "boost/multi_index/detail/bidir_node_iterator.hpp" -#include "boost/operators.hpp" -#include "boost/preprocessor/seq/limits/enum_256.hpp" -#include "boost/preprocessor/seq/limits/size_256.hpp" -#include "boost/property_tree/detail/exception_implementation.hpp" -#include "boost/smart_ptr/shared_ptr.hpp" -#include "boost/tuple/detail/tuple_basic.hpp" // for get #include "caosdb/log_level.h" +#include <boost/core/swap.hpp> // for swap +#include <boost/iterator/iterator_facade.hpp> +#include <boost/log/attributes/clock.hpp> +#include <boost/log/core/core.hpp> // for core +#include <boost/log/core/record.hpp> +#include <boost/log/sources/record_ostream.hpp> +#include <boost/log/sources/severity_channel_logger.hpp> +#include <boost/log/utility/setup/from_settings.hpp> +#include <boost/log/utility/setup/settings.hpp> +#include <boost/move/utility_core.hpp> // for move +#include <boost/multi_index/detail/bidir_node_iterator.hpp> +#include <boost/operators.hpp> +#include <boost/preprocessor/seq/limits/enum_256.hpp> +#include <boost/preprocessor/seq/limits/size_256.hpp> +#include <boost/property_tree/detail/exception_implementation.hpp> +#include <boost/smart_ptr/shared_ptr.hpp> +#include <boost/tuple/detail/tuple_basic.hpp> // for get #include <memory> #include <sstream> #include <string> @@ -44,10 +45,6 @@ namespace caosdb::logging { -BOOST_LOG_GLOBAL_LOGGER_INIT(logger, boost_logger_class) { - boost_logger_class lg; - return lg; -} LoggingConfiguration::LoggingConfiguration(int level) : LevelConfiguration(level) {} auto LoggingConfiguration::AddSink(const std::shared_ptr<SinkConfiguration> &sink) -> void { @@ -114,9 +111,12 @@ SyslogSinkConfiguration::SyslogSinkConfiguration(const std::string &name, int le // Called if no custom logging settings are specified. auto initialize_logging_defaults() -> int { // first: turn everything off - boost::log::settings off_settings; - off_settings["Core.DisableLogging"] = true; - boost::log::init_from_settings(off_settings); + auto core = boost::log::core::get(); + if (core->get_logging_enabled()) { + core->flush(); + core->remove_all_sinks(); + core->set_logging_enabled(false); + } // now set everything up const static std::vector<std::shared_ptr<SinkConfiguration>> default_sinks = { @@ -131,7 +131,6 @@ auto initialize_logging_defaults() -> int { } boost::log::init_from_settings(default_settings); - auto core = boost::log::core::get(); core->add_global_attribute("TimeStamp", boost::log::attributes::local_clock()); CAOSDB_LOG_DEBUG(logger_name) << "Initialized default settings."; @@ -142,20 +141,22 @@ auto initialize_logging_defaults() -> int { // Called if custom logging settings are specified. auto initialize_logging(const LoggingConfiguration &configuration) -> void { // first: turn everything off - boost::log::settings off_settings; - off_settings["Core.DisableLogging"] = true; - boost::log::init_from_settings(off_settings); - - // now set everything up - boost::log::settings new_settings; + auto core = boost::log::core::get(); + if (core->get_logging_enabled()) { + core->flush(); + core->remove_all_sinks(); + core->set_logging_enabled(false); + } if (configuration.GetLevel() == CAOSDB_LOG_LEVEL_OFF) { - new_settings["Core.DisableLogging"] = true; + // it is off return; - } else { - new_settings["Core.DisableLogging"] = false; } + // now set everything up + boost::log::settings new_settings; + new_settings["Core.DisableLogging"] = false; + for (const auto &sink : configuration.GetSinks()) { sink->Configure(new_settings); } diff --git a/src/caosdb/protobuf_helper.cpp b/src/caosdb/protobuf_helper.cpp index 418d14b9c847bc204582f6165fae81bf6adcc156..2b5847687d4926324cbbd5d4f49caca4131dc951 100644 --- a/src/caosdb/protobuf_helper.cpp +++ b/src/caosdb/protobuf_helper.cpp @@ -19,15 +19,15 @@ * */ #include "caosdb/protobuf_helper.h" +#include "caosdb/configuration.h" #include <google/protobuf/arena.h> // for Arena namespace caosdb::utility { using google::protobuf::Arena; -auto get_arena() -> Arena * { - static Arena arena; - return &arena; -} +auto get_arena() -> Arena * { return caosdb::configuration::ConfigurationManager::GetArena(); } + +auto reset_arena() -> void { get_arena()->Reset(); } } // namespace caosdb::utility diff --git a/src/caosdb/status_code_description.cpp b/src/caosdb/status_code_description.cpp index 5823943cfd7f79416cabb61662f778bac5de9bf8..d1f651257bc1a682870ffb52650a42c4d16ec642 100644 --- a/src/caosdb/status_code_description.cpp +++ b/src/caosdb/status_code_description.cpp @@ -132,7 +132,7 @@ auto get_status_description(int code) -> const std::string & { {StatusCode::CONFIGURATION_ERROR, "An error occurred during the configuration of the ConfigurationManager."}, {StatusCode::CONNECTION_CONFIGURATION_ERROR, - "Wither there is no connection of the given name or the given connection has a faulty " + "Either there is no connection of the given name or the given connection has a faulty " "configuration"}, {StatusCode::TRANSACTION_STATUS_ERROR, "The Transaction is in a wrong state for the attempted action."}, @@ -152,9 +152,9 @@ auto get_status_description(int code) -> const std::string & { {StatusCode::FILE_UPLOAD_ERROR, "The transaction failed during the upload of the files"}, {StatusCode::UNSUPPORTED_FEATURE, "This feature is not available in the this client implementation."}, - {StatusCode::EXTERN_C_ASSIGNMENT_ERROR, - "You tried to assign a new object to the wrapped void pointer. You have " - "to delete the old pointee first."}, + //{StatusCode::EXTERN_C_ASSIGNMENT_ERROR, + //"You tried to assign a new object to the wrapped void pointer. You have " + //"to delete the old pointee first."}, {StatusCode::ENUM_MAPPING_ERROR, "The role, importance, or datatype you specified does not exist."}, {StatusCode::SPOILED, diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp index 2bd0fda8cac0bce74051addbecf462ed105bf4f5..4c4bbda601d358c60fffa0537532d28a3699bb86 100644 --- a/src/caosdb/transaction.cpp +++ b/src/caosdb/transaction.cpp @@ -28,7 +28,6 @@ #include "caosdb/status_code.h" // for StatusCode #include "caosdb/transaction_handler.h" // for EntityTransactionHandler #include <algorithm> // for max -#include <boost/filesystem/path.hpp> // for operator<<, path #include <boost/log/core/record.hpp> // for record #include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring... #include <boost/log/sources/record_ostream.hpp> // for basic_record_... @@ -36,13 +35,15 @@ #include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_... // IWYU pragma: no_include <bits/exception.h> #include <exception> // IWYU pragma: keep +#include <filesystem> // for operator<<, path #include <google/protobuf/arena.h> // for Arena #include <grpc/impl/codegen/gpr_types.h> // for gpr_timespec #include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue -#include <iosfwd> // for streamsize #include <map> // for map, operator!= #include <memory> // for unique_ptr -#include <utility> // for move, pair +#include <random> // for mt19937, rand... +#include <sstream> +#include <utility> // for move, pair namespace caosdb::transaction { using caosdb::entity::v1::EntityTransactionService; @@ -52,6 +53,7 @@ using caosdb::entity::v1::MultiTransactionResponse; using TransactionResponseCase = caosdb::entity::v1::TransactionResponse::TransactionResponseCase; using RetrieveResponseCase = caosdb::entity::v1::RetrieveResponse::RetrieveResponseCase; using ProtoEntity = caosdb::entity::v1::Entity; +using caosdb::entity::v1::EntityRequest; using google::protobuf::Arena; using NextStatus = grpc::CompletionQueue::NextStatus; using RegistrationStatus = caosdb::entity::v1::RegistrationStatus; @@ -142,20 +144,39 @@ auto Transaction::DeleteById(const std::string &id) noexcept -> StatusCode { return this->status.GetCode(); } -auto Transaction::InsertEntity(Entity *entity) noexcept -> StatusCode { - ASSERT_CAN_ADD_INSERTION +auto get_next_file_id() -> std::string { + const std::string str = "0123456789abcdef"; + std::mt19937 generator(std::random_device{}()); + std::uniform_int_distribution<int> distribution(0, 15); // NOLINT + std::string result(10, '\0'); // NOLINT - auto *entity_request = - this->request->add_requests()->mutable_insert_request()->mutable_entity_request(); - auto *proto_entity = entity_request->mutable_entity(); + for (auto &dis : result) { + dis = str[distribution(generator)]; + } + return result; +} - // copy the original entity for the transaction +// only used in the next two functions. +auto add_entity_to_request(Entity *entity, EntityRequest *entity_request, + std::vector<FileDescriptor> *upload_files) -> void { + auto *proto_entity = entity_request->mutable_entity(); entity->CopyTo(proto_entity); if (entity->HasFile()) { auto *file_transmission_id = entity_request->mutable_upload_id(); + file_transmission_id->set_file_id(get_next_file_id()); entity->SetFileTransmissionId(file_transmission_id); - upload_files.push_back(entity->GetFileDescriptor()); + upload_files->push_back(entity->GetFileDescriptor()); } +} + +auto Transaction::InsertEntity(Entity *entity) noexcept -> StatusCode { + ASSERT_CAN_ADD_INSERTION + + auto *entity_request = + this->request->add_requests()->mutable_insert_request()->mutable_entity_request(); + + add_entity_to_request(entity, entity_request, &upload_files); + this->status = TransactionStatus::GO_ON(); return this->status.GetCode(); } @@ -165,14 +186,9 @@ auto Transaction::UpdateEntity(Entity *entity) noexcept -> StatusCode { auto *entity_request = this->request->add_requests()->mutable_update_request()->mutable_entity_request(); - auto *proto_entity = entity_request->mutable_entity(); - entity->CopyTo(proto_entity); - if (entity->HasFile()) { - auto *file_transmission_id = entity_request->mutable_upload_id(); - entity->SetFileTransmissionId(file_transmission_id); - upload_files.push_back(entity->GetFileDescriptor()); - } + add_entity_to_request(entity, entity_request, &upload_files); + this->status = TransactionStatus::GO_ON(); return this->status.GetCode(); } @@ -195,7 +211,7 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { // NOLINT case MIXED_READ_AND_WRITE: CAOSDB_LOG_ERROR_AND_RETURN_STATUS( logger_name, StatusCode::UNSUPPORTED_FEATURE, - "MIXED_WRITE UNSUPPORTED: The current implementation does not support " + "MIXED_READ_AND_WRITE UNSUPPORTED: The current implementation does not support " "mixed read and write transactions (containing retrievals, insertions, " "deletions, and updates in one transaction).") default: @@ -250,8 +266,9 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode { // NOLINT auto *entity_response = sub_response.mutable_retrieve_response()->mutable_entity_response(); auto entity_id = entity_response->entity().id(); - download_files[entity_id].file_transmission_id = entity_response->release_download_id(); - // TODO(tf) handle error + download_files[entity_id].file_transmission_id = + Arena::CreateMessage<FileTransmissionId>(GetArena()); + download_files[entity_id].file_transmission_id->CopyFrom(entity_response->download_id()); } } } @@ -289,7 +306,7 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus { // NOLINT switch (retrieve_response->retrieve_response_case()) { case RetrieveResponseCase::kEntityResponse: { - auto *retrieve_entity_response = retrieve_response->release_entity_response(); + auto *retrieve_entity_response = retrieve_response->mutable_entity_response(); result = std::make_unique<Entity>(retrieve_entity_response); } break; case RetrieveResponseCase::kSelectResult: { @@ -320,24 +337,24 @@ auto Transaction::WaitForIt() const noexcept -> TransactionStatus { // NOLINT } case TransactionResponseCase::kInsertResponse: { - auto *inserted_id_response = sub_response.mutable_insert_response()->release_id_response(); + auto *inserted_id_response = sub_response.mutable_insert_response()->mutable_id_response(); result = std::make_unique<Entity>(inserted_id_response); break; } case TransactionResponseCase::kDeleteResponse: { - auto *deleted_id_response = sub_response.mutable_delete_response()->release_id_response(); + auto *deleted_id_response = sub_response.mutable_delete_response()->mutable_id_response(); result = std::make_unique<Entity>(deleted_id_response); break; } case TransactionResponseCase::kUpdateResponse: { - auto *updated_id_response = sub_response.mutable_update_response()->release_id_response(); + auto *updated_id_response = sub_response.mutable_update_response()->mutable_id_response(); result = std::make_unique<Entity>(updated_id_response); break; } default: CAOSDB_LOG_FATAL(logger_name) << "Received invalid TransactionResponseCase."; break; - } + } // default to sub_response.transaction_response_case() if (result != nullptr) { if (result->HasErrors()) { set_error = true; diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp index 77759fce1d216f215dfccd343aa8202b2ec911fa..ae1a728f62b7cdfb293eb347d1a1966b86bfd3b2 100644 --- a/src/ccaosdb.cpp +++ b/src/ccaosdb.cpp @@ -58,11 +58,6 @@ extern "C" { #define ENUM_VALUE_FROM_NAME(arg, etype) \ caosdb::utility::getEnumValueFromName<caosdb::entity::etype>(arg) -#define RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(name) \ - if (name->_deletable) { \ - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; \ - } - /* * Macro for wrapping every function into a try-catch clause. If an exception * occurs, the given StatusCode is being returned. @@ -163,7 +158,6 @@ extern "C" { #define CREATE_VALUE(fname, arg) \ ERROR_RETURN_CODE(GENERIC_ERROR, \ int caosdb_entity_create_##fname(caosdb_entity_value *out, arg), { \ - RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) \ out->wrapped_value = new caosdb::entity::Value(value); \ out->_deletable = true; \ return 0; \ @@ -175,9 +169,6 @@ extern "C" { ERROR_RETURN_CODE( \ GENERIC_ERROR, \ int caosdb_entity_create_##fname(caosdb_entity_value *out, arg, const int length), { \ - if (out->_deletable) { \ - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; \ - } \ std::vector<type> value_vec; \ for (int i = 0; i < length; i++) { \ value_vec.push_back(assign); \ @@ -245,9 +236,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_connection_create_pem_file_certificate_provider( caosdb_connection_certificate_provider *out, const char *path), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } out->wrapped_certificate_provider = new caosdb::configuration::PemFileCertificateProvider(std::string(path)); out->_deletable = true; @@ -258,10 +246,11 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_connection_delete_certificate_provider( caosdb_connection_certificate_provider *provider), { - if (provider->_deletable) { + if (provider->_deletable && provider->wrapped_certificate_provider) { delete static_cast<caosdb::configuration::CertificateProvider *>( provider->wrapped_certificate_provider); } + provider->wrapped_certificate_provider = nullptr; provider->_deletable = false; return 0; }) @@ -271,9 +260,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, caosdb_authentication_authenticator *out, const char *username, const char *password), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } out->wrapped_authenticator = new caosdb::authentication::PlainPasswordAuthenticator(std::string(username), std::string(password)); @@ -285,10 +271,11 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_authentication_delete_authenticator( caosdb_authentication_authenticator *authenticator), { - if (authenticator->_deletable) { + if (authenticator->_deletable && authenticator->wrapped_authenticator) { delete static_cast<caosdb::authentication::Authenticator *>( authenticator->wrapped_authenticator); } + authenticator->wrapped_authenticator = nullptr; authenticator->_deletable = false; return 0; }) @@ -300,9 +287,6 @@ ERROR_RETURN_CODE( caosdb_authentication_authenticator *authenticator, caosdb_connection_certificate_provider *provider), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto host_str = std::string(host); if (authenticator != nullptr && provider != nullptr) { auto wrapped_provider = static_cast<caosdb::configuration::CertificateProvider *>( @@ -334,9 +318,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, caosdb_connection_connection_configuration *out, const char *host, const int port), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } out->wrapped_connection_configuration = new caosdb::configuration::InsecureConnectionConfiguration(host, port); out->_deletable = true; @@ -347,10 +328,12 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_connection_delete_connection_configuration( caosdb_connection_connection_configuration *configuration), { - if (configuration->_deletable) { + if (configuration->_deletable && + configuration->wrapped_connection_configuration) { delete static_cast<caosdb::configuration::ConnectionConfiguration *>( configuration->wrapped_connection_configuration); } + configuration->wrapped_connection_configuration = nullptr; configuration->_deletable = false; return 0; }) @@ -360,9 +343,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, caosdb_connection_connection *out, const caosdb_connection_connection_configuration *configuration), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } caosdb::configuration::ConnectionConfiguration *config = static_cast<caosdb::configuration::ConnectionConfiguration *>( configuration->wrapped_connection_configuration); @@ -374,10 +354,11 @@ ERROR_RETURN_CODE(GENERIC_ERROR, ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_connection_delete_connection(caosdb_connection_connection *connection), { - if (connection->_deletable) { + if (connection->_deletable && connection->wrapped_connection) { delete static_cast<caosdb::connection::Connection *>( connection->wrapped_connection); } + connection->wrapped_connection = nullptr; connection->_deletable = false; return 0; }) @@ -417,9 +398,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_connection_connection_manager_get_default_connection( caosdb_connection_connection *out), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } out->wrapped_connection = caosdb::connection::ConnectionManager::GetDefaultConnection().get(); out->_deletable = false; @@ -430,9 +408,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_connection_connection_manager_get_connection( caosdb_connection_connection *out, const char *name), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } out->wrapped_connection = caosdb::connection::ConnectionManager::GetConnection(std::string(name)).get(); // managed by the connection manager now, so not @@ -448,9 +423,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_connection_connection_create_transaction( caosdb_connection_connection *connection, caosdb_transaction_transaction *out), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_connection = static_cast<caosdb::connection::Connection *>(connection->wrapped_connection); out->wrapped_transaction = wrapped_connection->CreateTransaction().release(); @@ -461,9 +433,11 @@ ERROR_RETURN_CODE(GENERIC_ERROR, ERROR_RETURN_CODE( GENERIC_ERROR, int caosdb_transaction_delete_transaction(caosdb_transaction_transaction *transaction), { - if (transaction->_deletable) { + if (transaction->_deletable && transaction->wrapped_transaction) { delete static_cast<caosdb::transaction::Transaction *>(transaction->wrapped_transaction); } + transaction->wrapped_transaction = nullptr; + transaction->_deletable = false; return 0; }) @@ -553,9 +527,6 @@ ERROR_RETURN_CODE( int caosdb_transaction_transaction_get_result_set(caosdb_transaction_transaction *transaction, caosdb_transaction_result_set *out), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_transaction = static_cast<caosdb::transaction::Transaction *>(transaction->wrapped_transaction); out->wrapped_result_set = (void *)(&(wrapped_transaction->GetResultSet())); @@ -568,9 +539,6 @@ ERROR_RETURN_CODE( int caosdb_transaction_transaction_release_result_set(caosdb_transaction_transaction *transaction, caosdb_transaction_result_set *out), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_transaction = static_cast<caosdb::transaction::Transaction *>(transaction->wrapped_transaction); out->wrapped_result_set = (void *)(wrapped_transaction->ReleaseResultSet()); @@ -582,9 +550,10 @@ ERROR_RETURN_CODE( ERROR_RETURN_CODE( GENERIC_ERROR, int caosdb_transaction_delete_result_set(caosdb_transaction_result_set *result_set), { - if (result_set->_deletable) { + if (result_set->_deletable && result_set->wrapped_result_set) { delete static_cast<caosdb::entity::Entity *>(result_set->wrapped_result_set); } + result_set->wrapped_result_set = nullptr; result_set->_deletable = false; return 0; }) @@ -615,9 +584,6 @@ ERROR_RETURN_CODE( int caosdb_transaction_result_set_release_at(caosdb_transaction_result_set *result_set, caosdb_entity_entity *entity, int index), { - if (entity->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_result_set = static_cast<caosdb::transaction::MultiResultSet *>(result_set->wrapped_result_set); entity->wrapped_entity = wrapped_result_set->release_at(index); @@ -638,52 +604,46 @@ ERROR_RETURN_CODE(GENERIC_ERROR, }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_create_entity(caosdb_entity_entity *out), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } out->wrapped_entity = new caosdb::entity::Entity(); out->_deletable = true; return 0; }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_entity(caosdb_entity_entity *out), { - if (out->_deletable) { + if (out->_deletable && out->wrapped_entity) { delete static_cast<caosdb::entity::Entity *>(out->wrapped_entity); } + out->wrapped_entity = nullptr; out->_deletable = false; return 0; }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_create_property(caosdb_entity_property *out), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } out->wrapped_property = new caosdb::entity::Property(); out->_deletable = true; return 0; }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_property(caosdb_entity_property *out), { - if (out->_deletable) { + if (out->_deletable && out->wrapped_property) { delete static_cast<caosdb::entity::Property *>(out->wrapped_property); } + out->wrapped_property = nullptr; out->_deletable = false; return 0; }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_create_parent(caosdb_entity_parent *out), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } out->wrapped_parent = new caosdb::entity::Parent(); out->_deletable = true; return 0; }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_parent(caosdb_entity_parent *out), { - if (out->_deletable) { + if (out->_deletable && out->wrapped_parent) { delete static_cast<caosdb::entity::Parent *>(out->wrapped_parent); } + out->wrapped_parent = nullptr; out->_deletable = false; return 0; }) @@ -692,7 +652,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_create_atomic_datatype(caosdb_entity_datatype *out, const char *name), { - RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) try { auto enum_value = ENUM_VALUE_FROM_NAME(std::string(name), AtomicDataType); out->wrapped_datatype = new caosdb::entity::DataType(enum_value); @@ -707,7 +666,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_create_reference_datatype(caosdb_entity_datatype *out, const char *name), { - RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) out->wrapped_datatype = new caosdb::entity::DataType(std::string(name)); out->_deletable = true; return 0; @@ -716,7 +674,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_create_atomic_list_datatype(caosdb_entity_datatype *out, const char *name), { - RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) try { auto enum_value = ENUM_VALUE_FROM_NAME(std::string(name), AtomicDataType); out->wrapped_datatype = @@ -732,7 +689,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_create_reference_list_datatype(caosdb_entity_datatype *out, const char *name), { - RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) out->wrapped_datatype = new caosdb::entity::DataType( caosdb::entity::DataType::ListOf(std::string(name))); out->_deletable = true; @@ -740,9 +696,10 @@ ERROR_RETURN_CODE(GENERIC_ERROR, }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_datatype(caosdb_entity_datatype *out), { - if (out->_deletable) { + if (out->_deletable && out->wrapped_datatype) { delete WRAPPED_DATATYPE_CAST(out); } + out->wrapped_datatype = nullptr; out->_deletable = false; return 0; }) @@ -757,9 +714,10 @@ CREATE_VECTOR_VALUE(double_vector_value, double, const double *value, value[i]) CREATE_VECTOR_VALUE(bool_vector_value, bool, const bool *value, value[i]) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_value(caosdb_entity_value *out), { - if (out->_deletable) { + if (out->_deletable && out->wrapped_value) { delete WRAPPED_VALUE_CAST(out); } + out->wrapped_value = nullptr; out->_deletable = false; return 0; }) @@ -793,7 +751,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, caosdb_entity_datatype *out), { - RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); out->wrapped_datatype = (void *)(&(wrapped_entity->GetDataType())); out->_deletable = false; @@ -803,7 +760,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_get_value(caosdb_entity_entity *entity, caosdb_entity_value *out), { - RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); out->wrapped_value = (void *)(&(wrapped_entity->GetValue())); out->_deletable = false; @@ -826,9 +782,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_get_error(caosdb_entity_entity *entity, caosdb_entity_message *out, int index), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_message = wrapped_entity->GetErrors().mutable_at(index); @@ -850,9 +803,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_get_warning(caosdb_entity_entity *entity, caosdb_entity_message *out, int index), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_message = wrapped_entity->GetWarnings().mutable_at(index); @@ -872,9 +822,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_get_info(caosdb_entity_entity *entity, caosdb_entity_message *out, int index), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_message = wrapped_entity->GetInfos().mutable_at(index); @@ -896,9 +843,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_get_property(caosdb_entity_entity *entity, caosdb_entity_property *out, int index), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_property = wrapped_entity->GetProperties().mutable_at(index); @@ -919,9 +863,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_get_parent(caosdb_entity_entity *entity, caosdb_entity_parent *out, int index), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); out->wrapped_parent = wrapped_entity->GetParents().mutable_at(index); @@ -954,7 +895,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_property_get_datatype(caosdb_entity_property *property, caosdb_entity_datatype *out), { - RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); out->wrapped_datatype = (void *)(&(wrapped_property->GetDataType())); out->_deletable = false; @@ -964,7 +904,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_property_get_value(caosdb_entity_property *property, caosdb_entity_value *out), { - RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); out->wrapped_value = (void *)(&(wrapped_property->GetValue())); out->_deletable = false; @@ -1092,9 +1031,6 @@ ERROR_RETURN_CODE(GENERIC_ERROR, caosdb_entity_value *out, const int index), { - if (out->_deletable) { - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; - } auto *wrapped_value = WRAPPED_VALUE_CAST(value); out->wrapped_value = (void *)(&(wrapped_value->GetAsVector().at(index))); out->_deletable = false; @@ -1115,7 +1051,7 @@ ERROR_RETURN_CODE(GENERIC_ERROR, }) CAOSDB_ENTITY_SET(name, name, wrapped_entity->SetName(std::string(name));) CAOSDB_ENTITY_SET(local_path, local_path, - return wrapped_entity->SetLocalPath(boost::filesystem::path(local_path));) + return wrapped_entity->SetLocalPath(std::filesystem::path(local_path));) CAOSDB_ENTITY_SET(file_path, file_path, wrapped_entity->SetFilePath(std::string(file_path));) CAOSDB_ENTITY_SET(description, description, wrapped_entity->SetDescription(std::string(description));) diff --git a/src/cxxcaosdbcli.cpp b/src/cxxcaosdbcli.cpp index bb60696e8a0f3b10d2b29e54cac034b89907f9c3..e6e5cee66e6c90ab7719434d7667cd6ad20ccbb8 100644 --- a/src/cxxcaosdbcli.cpp +++ b/src/cxxcaosdbcli.cpp @@ -21,16 +21,23 @@ */ // A simple caosdb client -#include "caosdb/connection.h" // for Connection, ConnectionManager -#include "caosdb/constants.h" // for LIBCAOSDB_VERSION_MINOR, LIBCAOSDB_V... -#include "caosdb/entity.h" // for Entity -#include "caosdb/exceptions.h" // for ConfigurationError -#include "caosdb/info.h" // for VersionInfo -#include "caosdb/logging.h" // for CAOSDB_LOG_TRACE -#include "caosdb/transaction.h" // for Transaction, ResultSet -#include <iostream> // for operator<<, basic_ostream, basic_ost... -#include <memory> // for unique_ptr, allocator, __shared_ptr_... -#include <string> // for operator<<, char_traits +#include "caosdb/connection.h" // for Connection, ConnectionManager +#include "caosdb/constants.h" // for LIBCAOSDB_VERSION_MINOR, LIBCAOSDB_V... +#include "caosdb/entity.h" // for Entity +#include "caosdb/exceptions.h" // for ConfigurationError +#include "caosdb/info.h" // for VersionInfo +#include "caosdb/logging.h" // for CAOSDB_LOG_TRACE +#include "caosdb/transaction.h" // for Transaction, ResultSet +#include "caosdb/transaction_status.h" // for TransactionSt... +#include <boost/log/core/record.hpp> // for record +#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring... +#include <boost/log/sources/record_ostream.hpp> // for operator<< +#include <boost/preprocessor/seq/limits/enum_256.hpp> // for BOOST_PP_SEQ_... +#include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_... +#include <exception> // for exception +#include <iostream> // for operator<<, basic_ostream, basic_ost... +#include <memory> // for unique_ptr, allocator, __shared_ptr_... +#include <string> // for operator<<, char_traits const auto logger_name = "libcaosdb"; @@ -53,24 +60,14 @@ auto main() -> int { // retrieve an entity auto transaction(connection->CreateTransaction()); - transaction->RetrieveById("120"); + transaction->RetrieveById("21"); transaction->ExecuteAsynchronously(); auto t_stat = transaction->WaitForIt(); CAOSDB_LOG_INFO(logger_name) << "status: " << t_stat.GetCode() << " // " << t_stat.GetDescription(); const auto &result_set = transaction->GetResultSet(); - if (result_set.size() > 0) { - // print information - const auto &ent = result_set.at(0); - const auto &props = ent.GetProperties(); - std::cout << "Entity Name: " << ent.GetName() << std::endl; - std::cout << "Entity Description: " << ent.GetDescription() << std::endl; - std::cout << "Entity Properties: " << std::endl; - for (const auto &prop : props) { - std::cout << "----------\n" << prop.ToString() << std::endl; - } - } else { - std::cout << "No entity \"120\" retrieved, maybe it does not exist?\n" << std::endl; + for (const auto &entity : result_set) { + std::cout << entity.ToString() << std::endl; } // execute a query @@ -82,6 +79,11 @@ auto main() -> int { t_stat = q_transaction->WaitForIt(); CAOSDB_LOG_INFO(logger_name) << "status: " << t_stat.GetCode() << " // " << t_stat.GetDescription(); + const auto &result_set_2 = q_transaction->GetResultSet(); + for (const auto &entity : result_set_2) { + std::cout << entity.ToString() << std::endl; + } + return 0; } catch (const caosdb::exceptions::ConfigurationError &exc) { std::cout << "ConfigurationError: " << exc.what() << std::endl; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9cacb63b0f6b74368508df6920e2dc03db81a929..12741c41d4e31e12548711f14dc716b4eb7f65c8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -110,5 +110,10 @@ if (LCOV_PATH) set_target_properties(ccaosdb PROPERTIES COMPILE_FLAGS "${TARGET_CCAOSDB_COMPILE_FLAGS}") else () - message(WARNING "Could not generate code coverage report. Please install lcov.") + if (NOT SKIP_CODE_COVERAGE) + message(WARNING "Could not generate code coverage report. Please install lcov.") + add_custom_target(unit_test_coverage ctest -L caosdb-cpplib-unit-tests + DEPENDS caosdb ccaosdb ${test_cases} + ) + endif() endif () diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp index 1059f161525d513389efd4df95cdd04ec5a088db..71c2a829316b5b5418702686c6ea0fdfa48e5198 100644 --- a/test/test_ccaosdb.cpp +++ b/test/test_ccaosdb.cpp @@ -386,8 +386,8 @@ TEST_F(test_ccaosdb, test_entity) { EXPECT_EQ(return_code, 0); // cannot be created again without deletion - return_code = caosdb_entity_create_entity(&entity); - EXPECT_EQ(return_code, caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR); + // return_code = caosdb_entity_create_entity(&entity); + // EXPECT_EQ(return_code, caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR); // deletion and re-creation is ok return_code = caosdb_entity_delete_entity(&entity); @@ -431,8 +431,8 @@ TEST_F(test_ccaosdb, test_entity) { caosdb_entity_entity_set_datatype(&entity, &in_type); // verify that this doesn't work ... - return_code = caosdb_entity_entity_get_datatype(&entity, &in_type); - EXPECT_EQ(return_code, caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR); + // return_code = caosdb_entity_entity_get_datatype(&entity, &in_type); + // EXPECT_EQ(return_code, caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR); caosdb_entity_datatype out_type; // ... but does with a clean property return_code = caosdb_entity_entity_get_datatype(&entity, &out_type); @@ -827,8 +827,8 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) { char *out = nullptr; // NOLINT // cannot assign an already assigned property - return_code = caosdb_entity_entity_get_property(&entity, &input_property, 0); - EXPECT_EQ(return_code, caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR); + // return_code = caosdb_entity_entity_get_property(&entity, &input_property, 0); + // EXPECT_EQ(return_code, caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR); caosdb_entity_property output_property; return_code = caosdb_entity_entity_get_property(&entity, &output_property, 0); EXPECT_EQ(return_code, 0); diff --git a/test/test_connection.cpp b/test/test_connection.cpp index 4a5260e10964bc652c4ac803bf376b6b6cf39ead..00c3bcf58e605e112a404fdfe6ece62e829562ea 100644 --- a/test/test_connection.cpp +++ b/test/test_connection.cpp @@ -26,7 +26,7 @@ #include "caosdb_test_utility.h" // for EXPECT_THROW_MESSAGE, TEST_... #include <gtest/gtest-message.h> // for Message #include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestPartR... -#include "gtest/gtest_pred_impl.h" // for AssertionResult, TestInfo +#include <gtest/gtest_pred_impl.h> // for AssertionResult, TestInfo #include <memory> // for allocator, operator!=, shar... #include <string> // for operator+, string diff --git a/test/test_data_type.cpp b/test/test_data_type.cpp index c846dceb5ca196db3b58a5aae901f735ee9dc3f2..bccc853e283cb00fd6fd1b40838f5a8ac1faae64 100644 --- a/test/test_data_type.cpp +++ b/test/test_data_type.cpp @@ -65,6 +65,7 @@ TEST(test_data_type, test_atomic) { EXPECT_TRUE(data_type.IsAtomic()); EXPECT_EQ(data_type.GetAsAtomic(), map_el.first); } + caosdb::utility::reset_arena(); } TEST(test_data_type, test_reference) { diff --git a/test/test_entity.cpp b/test/test_entity.cpp index a027ad7e8e3e5bac30d7e8c33e15f0e15ee6a91f..5f5aaaab4a5f6727f38ea30c0205ea8d79a925b1 100644 --- a/test/test_entity.cpp +++ b/test/test_entity.cpp @@ -143,33 +143,34 @@ TEST(test_entity, test_append_property) { } TEST(test_entity, entity_copy_constructor) { - ProtoParent parent; - parent.set_description("the parent desc"); - parent.set_id("the parent id"); - parent.set_name("the parent name"); - ProtoProperty property; - property.set_id("the-prop-id"); - property.set_description("the prop-desc"); - property.set_name("the-prop-name"); - property.mutable_value()->mutable_list_values()->mutable_values()->Add()->set_double_value(25.5); - property.mutable_data_type()->mutable_list_data_type()->set_atomic_data_type( + Arena arena; + auto *parent = Arena::CreateMessage<ProtoParent>(&arena); + parent->set_description("the parent desc"); + parent->set_id("the parent id"); + parent->set_name("the parent name"); + auto *property = Arena::CreateMessage<ProtoProperty>(&arena); + property->set_id("the-prop-id"); + property->set_description("the prop-desc"); + property->set_name("the-prop-name"); + property->mutable_value()->mutable_list_values()->mutable_values()->Add()->set_double_value(25.5); + property->mutable_data_type()->mutable_list_data_type()->set_atomic_data_type( ProtoAtomicDataType::ATOMIC_DATA_TYPE_DOUBLE); - EntityResponse entity_response; - entity_response.mutable_entity()->set_id("the-id"); - entity_response.mutable_entity()->set_name("the-name"); - entity_response.mutable_entity()->set_role(ProtoEntityRole::ENTITY_ROLE_RECORD); - entity_response.mutable_entity()->set_description("the description"); - entity_response.mutable_entity()->set_unit("the-unit"); - entity_response.mutable_entity()->mutable_value()->mutable_scalar_value()->set_string_value( + auto *entity_response = Arena::CreateMessage<EntityResponse>(&arena); + entity_response->mutable_entity()->set_id("the-id"); + entity_response->mutable_entity()->set_name("the-name"); + entity_response->mutable_entity()->set_role(ProtoEntityRole::ENTITY_ROLE_RECORD); + entity_response->mutable_entity()->set_description("the description"); + entity_response->mutable_entity()->set_unit("the-unit"); + entity_response->mutable_entity()->mutable_value()->mutable_scalar_value()->set_string_value( "the-value"); - entity_response.mutable_entity()->mutable_version()->set_id("version-id"); - entity_response.mutable_entity()->mutable_data_type()->mutable_reference_data_type()->set_name( + entity_response->mutable_entity()->mutable_version()->set_id("version-id"); + entity_response->mutable_entity()->mutable_data_type()->mutable_reference_data_type()->set_name( "refname"); - entity_response.mutable_entity()->mutable_file_descriptor(); - entity_response.mutable_entity()->mutable_properties()->Add()->CopyFrom(property); - entity_response.mutable_entity()->mutable_parents()->Add()->CopyFrom(parent); + entity_response->mutable_entity()->mutable_file_descriptor(); + entity_response->mutable_entity()->mutable_properties()->Add()->CopyFrom(*property); + entity_response->mutable_entity()->mutable_parents()->Add()->CopyFrom(*parent); - Entity this_entity(&entity_response); + Entity this_entity(entity_response); Entity copy_entity(this_entity); EXPECT_EQ(this_entity, copy_entity); @@ -198,39 +199,40 @@ TEST(test_entity, entity_copy_constructor) { } TEST(test_entity, entity_move_constructor) { - ProtoParent parent; - parent.set_description("the parent desc"); - parent.set_id("the parent id"); - parent.set_name("the parent name"); - ProtoProperty property; - property.set_id("the-prop-id"); - property.set_description("the prop-desc"); - property.set_name("the-prop-name"); - property.mutable_value()->mutable_list_values()->mutable_values()->Add()->set_double_value(25.5); - property.mutable_data_type()->mutable_list_data_type()->set_atomic_data_type( + Arena arena; + auto *parent = Arena::CreateMessage<ProtoParent>(&arena); + parent->set_description("the parent desc"); + parent->set_id("the parent id"); + parent->set_name("the parent name"); + auto *property = Arena::CreateMessage<ProtoProperty>(&arena); + property->set_id("the-prop-id"); + property->set_description("the prop-desc"); + property->set_name("the-prop-name"); + property->mutable_value()->mutable_list_values()->mutable_values()->Add()->set_double_value(25.5); + property->mutable_data_type()->mutable_list_data_type()->set_atomic_data_type( ProtoAtomicDataType::ATOMIC_DATA_TYPE_DOUBLE); - EntityResponse entity_response; - entity_response.mutable_errors()->Add()->set_code(25); - entity_response.mutable_errors()->Mutable(0)->set_description("asdf"); - entity_response.mutable_warnings()->Add()->set_code(23); - entity_response.mutable_warnings()->Mutable(0)->set_description("asdgsafdg"); - entity_response.mutable_infos()->Add()->set_code(235); - entity_response.mutable_infos()->Mutable(0)->set_description("asdfsad"); - entity_response.mutable_entity()->set_id("the-id"); - entity_response.mutable_entity()->set_name("the-name"); - entity_response.mutable_entity()->set_role(ProtoEntityRole::ENTITY_ROLE_RECORD); - entity_response.mutable_entity()->set_description("the description"); - entity_response.mutable_entity()->set_unit("the-unit"); - entity_response.mutable_entity()->mutable_value()->mutable_scalar_value()->set_string_value( + auto *entity_response = Arena::CreateMessage<EntityResponse>(&arena); + entity_response->mutable_errors()->Add()->set_code(25); + entity_response->mutable_errors()->Mutable(0)->set_description("asdf"); + entity_response->mutable_warnings()->Add()->set_code(23); + entity_response->mutable_warnings()->Mutable(0)->set_description("asdgsafdg"); + entity_response->mutable_infos()->Add()->set_code(235); + entity_response->mutable_infos()->Mutable(0)->set_description("asdfsad"); + entity_response->mutable_entity()->set_id("the-id"); + entity_response->mutable_entity()->set_name("the-name"); + entity_response->mutable_entity()->set_role(ProtoEntityRole::ENTITY_ROLE_RECORD); + entity_response->mutable_entity()->set_description("the description"); + entity_response->mutable_entity()->set_unit("the-unit"); + entity_response->mutable_entity()->mutable_value()->mutable_scalar_value()->set_string_value( "the-value"); - entity_response.mutable_entity()->mutable_version()->set_id("version-id"); - entity_response.mutable_entity()->mutable_data_type()->mutable_reference_data_type()->set_name( + entity_response->mutable_entity()->mutable_version()->set_id("version-id"); + entity_response->mutable_entity()->mutable_data_type()->mutable_reference_data_type()->set_name( "refname"); - entity_response.mutable_entity()->mutable_file_descriptor(); - entity_response.mutable_entity()->mutable_properties()->Add()->CopyFrom(property); - entity_response.mutable_entity()->mutable_parents()->Add()->CopyFrom(parent); + entity_response->mutable_entity()->mutable_file_descriptor(); + entity_response->mutable_entity()->mutable_properties()->Add()->CopyFrom(*property); + entity_response->mutable_entity()->mutable_parents()->Add()->CopyFrom(*parent); - Entity this_entity(&entity_response); + Entity this_entity(entity_response); std::string original_string = this_entity.ToString(); Entity copy_entity(this_entity); EXPECT_EQ(this_entity, copy_entity); @@ -321,7 +323,7 @@ TEST(test_entity, property_move_assignment) { // we compare the moved one with this one const Property copy_prop(prop); - Property other_prop = std::move(prop); + Property other_prop = std::move(prop); // NOLINT EXPECT_NE(prop, copy_prop); // NOLINT EXPECT_NE(prop, other_prop); // NOLINT EXPECT_NE(prop.ToString(), prop_string); // NOLINT @@ -791,10 +793,11 @@ TEST(test_entity, test_description) { entity.SetDescription("desc entity"); property.SetDescription("desc property"); - // Parent has not setter - ProtoParent protoParent; - protoParent.set_description("desc parent"); - parent = Parent(&protoParent); + // Parent has no setter + Arena arena; + auto *protoParent = Arena::CreateMessage<ProtoParent>(&arena); + protoParent->set_description("desc parent"); + parent = Parent(protoParent); EXPECT_EQ(entity.GetDescription(), "desc entity"); EXPECT_EQ(property.GetDescription(), "desc property"); @@ -901,13 +904,14 @@ TEST(test_entity, test_parent_to_string) { } TEST(test_entity, test_messages_to_string) { - IdResponse idResponse; - idResponse.set_id("entity_id"); - auto *error = idResponse.add_errors(); + Arena arena; + auto *idResponse = Arena::CreateMessage<IdResponse>(&arena); + idResponse->set_id("entity_id"); + auto *error = idResponse->add_errors(); error->set_code(MessageCode::ENTITY_DOES_NOT_EXIST); error->set_description("error_desc"); - Entity entity(&idResponse); + Entity entity(idResponse); // Messages are not printed, currently. EXPECT_EQ(entity.ToString(), "{\n \"id\": \"entity_id\",\n \"version\": {}\n}\n"); @@ -916,13 +920,14 @@ TEST(test_entity, test_messages_to_string) { } TEST(test_entity, test_message_to_string) { - IdResponse idResponse; - idResponse.set_id("entity_id"); - auto *error = idResponse.add_errors(); + Arena arena; + auto *idResponse = Arena::CreateMessage<IdResponse>(&arena); + idResponse->set_id("entity_id"); + auto *error = idResponse->add_errors(); error->set_code(MessageCode::ENTITY_DOES_NOT_EXIST); error->set_description("error_desc"); - Entity entity(&idResponse); + Entity entity(idResponse); // Messages are not printed, currently. EXPECT_EQ(entity.ToString(), "{\n \"id\": \"entity_id\",\n \"version\": {}\n}\n"); diff --git a/test/test_file_transmission.cpp b/test/test_file_transmission.cpp index 7c5eb745e8f451b0282fa844510dc71ad402ed18..c5847a0842ae8a3bb46a8126e42b31bb5b1d6451 100644 --- a/test/test_file_transmission.cpp +++ b/test/test_file_transmission.cpp @@ -19,15 +19,14 @@ */ #include "caosdb/file_transmission/file_writer.h" #include "caosdb/file_transmission/file_reader.h" -#include <boost/filesystem/operations.hpp> // for exists, file_size, remove -#include <boost/filesystem/path.hpp> // for path -#include <boost/filesystem/path_traits.hpp> // for filesystem -#include <gtest/gtest-message.h> // for Message -#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiResolver -#include <gtest/gtest_pred_impl.h> // for Test, EXPECT_EQ, AssertionResult -#include <string> // for string - -namespace fs = boost::filesystem; +#include <chrono> // for filesystem +#include <filesystem> // for path +#include <gtest/gtest-message.h> // for Message +#include <gtest/gtest-test-part.h> // for TestPartResult, SuiteApiResolver +#include <gtest/gtest_pred_impl.h> // for Test, EXPECT_EQ, AssertionResult +#include <string> // for string + +namespace fs = std::filesystem; namespace caosdb::transaction { diff --git a/test/test_protobuf.cpp b/test/test_protobuf.cpp index 8e5c84e2e5ccb80e4a03d99cf8914593df996131..42e1e574437e47f0129cb30b336ab336613daede 100644 --- a/test/test_protobuf.cpp +++ b/test/test_protobuf.cpp @@ -22,6 +22,7 @@ #include "caosdb/data_type.h" // for DataType, ReferenceDataType #include "caosdb/entity.h" // for Entity #include "caosdb/entity/v1/main.pb.h" // for RepeatedPtrField, Message +#include <google/protobuf/arena.h> // for Arena #include <gtest/gtest-message.h> // for Message #include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestPa... #include <gtest/gtest_pred_impl.h> // for Test, TestInfo, TEST @@ -31,77 +32,81 @@ namespace caosdb { using ProtoEntity = caosdb::entity::v1::Entity; using caosdb::entity::Entity; using caosdb::entity::v1::Message; +using google::protobuf::Arena; TEST(test_protobuf, test_swap_trivial) { - Message message_source; - message_source.set_code(1234); - message_source.set_description("desc"); + Arena arena; + auto *message_source = Arena::CreateMessage<Message>(&arena); + message_source->set_code(1234); + message_source->set_description("desc"); - Message message_destination; + auto *message_destination = Arena::CreateMessage<Message>(&arena); - EXPECT_EQ(message_source.code(), 1234); - EXPECT_EQ(message_source.description(), "desc"); - EXPECT_EQ(message_destination.code(), 0); - EXPECT_EQ(message_destination.description(), ""); + EXPECT_EQ(message_source->code(), 1234); + EXPECT_EQ(message_source->description(), "desc"); + EXPECT_EQ(message_destination->code(), 0); + EXPECT_EQ(message_destination->description(), ""); - message_source.Swap(&message_destination); + message_source->Swap(message_destination); - EXPECT_EQ(message_source.code(), 0); - EXPECT_EQ(message_source.description(), ""); - EXPECT_EQ(message_destination.code(), 1234); - EXPECT_EQ(message_destination.description(), "desc"); + EXPECT_EQ(message_source->code(), 0); + EXPECT_EQ(message_source->description(), ""); + EXPECT_EQ(message_destination->code(), 1234); + EXPECT_EQ(message_destination->description(), "desc"); } TEST(test_protobuf, test_swap_nested) { - ProtoEntity entity_source; - entity_source.set_id("entity_id"); - auto *version_source = entity_source.mutable_version(); + Arena arena; + auto *entity_source = Arena::CreateMessage<ProtoEntity>(&arena); + entity_source->set_id("entity_id"); + auto *version_source = entity_source->mutable_version(); version_source->set_id("version_id"); - ProtoEntity entity_destination; - auto *version_destination = entity_destination.mutable_version(); + auto *entity_destination = Arena::CreateMessage<ProtoEntity>(&arena); + auto *version_destination = entity_destination->mutable_version(); - EXPECT_EQ(entity_source.id(), "entity_id"); - EXPECT_EQ(entity_source.version().id(), "version_id"); + EXPECT_EQ(entity_source->id(), "entity_id"); + EXPECT_EQ(entity_source->version().id(), "version_id"); EXPECT_EQ(version_source->id(), "version_id"); - EXPECT_EQ(entity_destination.id(), ""); - EXPECT_EQ(entity_destination.version().id(), ""); + EXPECT_EQ(entity_destination->id(), ""); + EXPECT_EQ(entity_destination->version().id(), ""); EXPECT_EQ(version_destination->id(), ""); - entity_source.Swap(&entity_destination); + entity_source->Swap(entity_destination); - EXPECT_EQ(entity_source.id(), ""); - EXPECT_EQ(entity_source.version().id(), ""); - EXPECT_EQ(entity_destination.id(), "entity_id"); - EXPECT_EQ(entity_destination.version().id(), "version_id"); + EXPECT_EQ(entity_source->id(), ""); + EXPECT_EQ(entity_source->version().id(), ""); + EXPECT_EQ(entity_destination->id(), "entity_id"); + EXPECT_EQ(entity_destination->version().id(), "version_id"); // has not been swapped! EXPECT_EQ(version_source->id(), "version_id"); EXPECT_EQ(version_destination->id(), ""); // Member pointers to nested messages have been swapped - EXPECT_EQ(entity_source.mutable_version(), version_destination); - EXPECT_EQ(entity_destination.mutable_version(), version_source); + EXPECT_EQ(entity_source->mutable_version(), version_destination); + EXPECT_EQ(entity_destination->mutable_version(), version_source); } TEST(test_protobuf, test_copy_nested) { - ProtoEntity entity_source; - auto *data_type_source = entity_source.mutable_data_type(); + Arena arena; + auto *entity_source = Arena::CreateMessage<ProtoEntity>(&arena); + auto *data_type_source = entity_source->mutable_data_type(); data_type_source->mutable_reference_data_type()->set_name("src_per"); - ProtoEntity entity_destination; - auto *data_type_destination = entity_destination.mutable_data_type(); + auto *entity_destination = Arena::CreateMessage<ProtoEntity>(&arena); + auto *data_type_destination = entity_destination->mutable_data_type(); data_type_destination->mutable_reference_data_type()->set_name("dest_per"); - EXPECT_EQ(entity_source.data_type().reference_data_type().name(), "src_per"); - EXPECT_EQ(entity_destination.data_type().reference_data_type().name(), "dest_per"); + EXPECT_EQ(entity_source->data_type().reference_data_type().name(), "src_per"); + EXPECT_EQ(entity_destination->data_type().reference_data_type().name(), "dest_per"); - entity_destination.CopyFrom(entity_source); + entity_destination->CopyFrom(*entity_source); - EXPECT_EQ(entity_source.data_type().reference_data_type().name(), "src_per"); - EXPECT_EQ(entity_destination.data_type().reference_data_type().name(), "src_per"); + EXPECT_EQ(entity_source->data_type().reference_data_type().name(), "src_per"); + EXPECT_EQ(entity_destination->data_type().reference_data_type().name(), "src_per"); - Entity entity(&entity_destination); + Entity entity(entity_destination); EXPECT_EQ(entity.GetDataType().GetAsReference().GetName(), "src_per"); const Entity ©_entity(entity); diff --git a/test/test_transaction.cpp b/test/test_transaction.cpp index 535f7587aca4ef4e2b44225b5db8eef9ebdc8fd6..797b6acc37a43a882b83aa540f17124b462add02 100644 --- a/test/test_transaction.cpp +++ b/test/test_transaction.cpp @@ -17,16 +17,18 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ -#include "caosdb/configuration.h" // for InsecureConnectionConfig... -#include "caosdb/connection.h" // for Connection -#include "caosdb/entity.h" // for Entity -#include "caosdb/entity/v1/main.pb.h" // for Entity -#include "caosdb/exceptions.h" // for ConnectionError -#include "caosdb/status_code.h" +#include "caosdb/configuration.h" // for InsecureConnectionConfig... +#include "caosdb/connection.h" // for Connection +#include "caosdb/entity.h" // for Entity +#include "caosdb/entity/v1/main.pb.h" // for Entity +#include "caosdb/exceptions.h" // for ConnectionError +#include "caosdb/status_code.h" // for StatusCode #include "caosdb/transaction.h" // for Transaction #include "caosdb/transaction_handler.h" // for MultiTransactionResponse #include "caosdb/transaction_status.h" // for ConnectionError #include "caosdb_test_utility.h" // for EXPECT_THROW_MESSAGE +#include <algorithm> // for max +#include <google/protobuf/arena.h> // for Arena #include <gtest/gtest-message.h> // for Message #include <gtest/gtest-test-part.h> // for SuiteApiResolver, TestPa... #include <gtest/gtest_pred_impl.h> // for Test, TestInfo, TEST @@ -113,9 +115,10 @@ TEST(test_transaction, test_multi_result_set_empty) { TEST(test_transaction, test_multi_result_iterator) { std::vector<std::unique_ptr<Entity>> one_elem; - RetrieveResponse response; - response.mutable_entity_response()->mutable_entity()->set_id("100"); - one_elem.push_back(std::make_unique<Entity>(response.release_entity_response())); + Arena arena; + auto *response = Arena::CreateMessage<RetrieveResponse>(&arena); + response->mutable_entity_response()->mutable_entity()->set_id("100"); + one_elem.push_back(std::make_unique<Entity>(response->mutable_entity_response())); MultiResultSet rs(std::move(one_elem)); EXPECT_EQ(rs.size(), 1); @@ -127,9 +130,10 @@ TEST(test_transaction, test_multi_result_iterator) { TEST(test_transaction, test_multi_result_set_one) { std::vector<std::unique_ptr<Entity>> one_elem; - RetrieveResponse response; - response.mutable_entity_response()->mutable_entity()->set_id("100"); - one_elem.push_back(std::make_unique<Entity>(response.release_entity_response())); + Arena arena; + auto *response = Arena::CreateMessage<RetrieveResponse>(&arena); + response->mutable_entity_response()->mutable_entity()->set_id("100"); + one_elem.push_back(std::make_unique<Entity>(response->mutable_entity_response())); MultiResultSet rs(std::move(one_elem)); EXPECT_EQ(rs.size(), 1); @@ -139,27 +143,28 @@ TEST(test_transaction, test_multi_result_set_one) { TEST(test_transaction, test_multi_result_set_three) { std::vector<std::unique_ptr<Entity>> three_elem; - MultiTransactionResponse response; - response.add_responses() + Arena arena; + auto *response = Arena::CreateMessage<MultiTransactionResponse>(&arena); + response->add_responses() ->mutable_retrieve_response() ->mutable_entity_response() ->mutable_entity() ->set_id("100"); auto *entity_with_error = - response.add_responses()->mutable_retrieve_response()->mutable_entity_response(); + response->add_responses()->mutable_retrieve_response()->mutable_entity_response(); entity_with_error->mutable_entity()->set_id("101"); entity_with_error->add_errors()->set_code(1); - response.add_responses() + response->add_responses() ->mutable_retrieve_response() ->mutable_entity_response() ->mutable_entity() ->set_id("102"); - auto *responses = response.mutable_responses(); + auto *responses = response->mutable_responses(); std::vector<std::unique_ptr<Entity>> entities; for (auto sub_response : *responses) { three_elem.push_back(std::make_unique<Entity>( - sub_response.mutable_retrieve_response()->release_entity_response())); + sub_response.mutable_retrieve_response()->mutable_entity_response())); } MultiResultSet rs(std::move(three_elem)); diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index d11580a845a3660e22be3ade1a3cc04cb95f1dd3..6e0db0446b0d4a2e1767f1ecdf2156ffb5dbb295 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -14,7 +14,7 @@ set(test_cases # dependencies include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup() +conan_basic_setup(KEEP_RPATHS) # supress warnings during build of gtest cmake_policy(SET CMP0054 NEW) @@ -33,6 +33,9 @@ foreach (i RANGE "${len_test_cases}") ${CONAN_LIBS_GTEST} ${CONAN_LIBS_GRPC} ${CONAN_LIBS_ABSEIL} ${CONAN_LIBS_OPENSSL} ${CONAN_LIBS_C-ARES} ${CONAN_LIBS_BZIP2} ${CONAN_LIBS_PROTOBUF} ${CONAN_LIBS_ZLIB}) + if("${CMAKE_BUILD_TYPE}" MATCHES "Debug") + target_link_libraries(${test_case_name} PRIVATE caosdb_grpc) + endif() target_include_directories(${test_case_name} PUBLIC ${CONAN_INCLUDE_DIRS}) set_target_properties(${test_case_name} PROPERTIES diff --git a/test_package/conanfile.py b/test_package/conanfile.py index a003a6b0b97b32b30632b12fb4659a086cf36ddf..541113405bfca3b1222de81124a13586fe4bbda5 100644 --- a/test_package/conanfile.py +++ b/test_package/conanfile.py @@ -6,6 +6,9 @@ from conans import ConanFile, CMake, tools class LibcaosdbTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "cmake" + build_requires = [ + ("gtest/1.11.0"), + ] def build(self): cmake = CMake(self)