Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 108-implement-rpc-call-for-server-side-scripting
  • dev
  • f-consol-message
  • f-rel-path
  • f-related-projects
  • f-remote-path
  • f-role
  • f-sss4grpc
  • f-to-string
  • f-update-requirements
  • f-windows-conan-create
  • main
  • v0.0.1
  • v0.0.10
  • v0.0.15
  • v0.0.16
  • v0.0.18
  • v0.0.19
  • v0.0.2
  • v0.0.3
  • v0.0.4
  • v0.0.5
  • v0.0.6
  • v0.0.7
  • v0.0.8
  • v0.0.9
  • v0.1
  • v0.1.1
  • v0.1.2
  • v0.2.0
  • v0.2.1
  • v0.2.2
  • v0.3.0
33 results

Target

Select target project
  • caosdb/src/caosdb-cpplib
1 result
Select Git revision
  • 108-implement-rpc-call-for-server-side-scripting
  • dev
  • f-consol-message
  • f-rel-path
  • f-related-projects
  • f-remote-path
  • f-role
  • f-sss4grpc
  • f-to-string
  • f-update-requirements
  • f-windows-conan-create
  • main
  • v0.0.1
  • v0.0.10
  • v0.0.15
  • v0.0.16
  • v0.0.18
  • v0.0.19
  • v0.0.2
  • v0.0.3
  • v0.0.4
  • v0.0.5
  • v0.0.6
  • v0.0.7
  • v0.0.8
  • v0.0.9
  • v0.1
  • v0.1.1
  • v0.1.2
  • v0.2.0
  • v0.2.1
  • v0.2.2
  • v0.3.0
33 results
Show changes
Showing
with 472 additions and 298 deletions
# Features
This library provides a client for communication with a CaosDB server over the
CaosDB GRPC-APIs. The client supports
* Transaction of entities and file transmission.
* Authentication via Username/Password.
* Secure communication via TLS.
* Multiple connections with different servers.
* Logging.
* File-based configuration.
The core is written in C++ and makes heavy use of object-oriented patterns. It
results in a c++ library -- libcaosdb.
For using the library in a plain C context, a thin wrapper is included
-- libccaosdb. It wrapps the C++ classes into structs and the member methods
into functions which operate on the wrapped C++ instances.
Minimal testing executables in C++ and C are included as well, but they only
serve as just that -- minimal testing.
## CaosDB Entitiy API
This library implements a subset of the CaosDB Entitiy API (caosdb.entity.v1) as a client.
Current limitations: The implementation does not support mixing retrievals with write-transactions.
## CaosDB Info API
This library implements the CaosDB Info API (caosdb.info.v1) as a client without limitations.
## Thread-safety and Concurrency
Currently, the library should not be considered thread-safe.
The `caosdb::transaction::Transaction` class is designed with an with an
interface ready for concurrent and asyncronous transactions. However, the
functions are actually implemented in a blocking, synchronous way.
How to use and develop libcaosdb
================================
Dependencies
------------
- See the `dependencies <DEPENDENCIES.md>`__ file.
Build
-----
Building with ``make``
~~~~~~~~~~~~~~~~~~~~~~
Make sure that the dependencies (see above) are fulfilled. On systems
which have ``make`` installed, type this in your command line terminal:
.. code:: console
make conan
Manual build
~~~~~~~~~~~~
We use `cmake <https://cmake.org>`__ as build tool, with Conan as
package manager. The compiler must support the C++17 standard.
1. clone/update the subrepo ``git submodule update --init proto``
2. ``mkdir build && cd build``
3. ``conan install .. -s "compiler.libcxx=libstdc++11"``
4. ``cmake -B . ..``
5. ``cmake --build .``
You may also want to install libcaosdb system-wide to
``CMAKE_INSTALL_PREFIX/lib`` by
1. ``cmake --install .``
The default install prefix is ``~/.local``. It can be set by adding
``-DCMAKE_INSTALL_PREFIX=/path/to/install/prefix`` to the first cmake
command (3.).
.. Note::
The C++ CaosDB library links against other libraries which are installed by Conan. So if you want
to switch to newer versions of those libraries (possible reasons may be security releases or bug
fixes), it is not sufficient to update your system libraries, but you have to update your Conan
content and then rebuild libcaosdb.
If you want to build or install libcaosdb without the use of Conan, feel
free to rewrite the CMakeLists.txt as needed. The CaosDB project is open
to merge requests which support multiple ways of installation.
How to build on MacOS
~~~~~~~~~~~~~~~~~~~~~
If you use apple-clang as the compiler: Instead of the above conan
command (2.) use
1. ``conan install .. -s "compiler.cppstd=17"``
and continue as you would when building on a Linux system. You may have
to add ``build/lib/`` (or, alternatively after installation,
``CMAKE_INSTALL_PREFIX/lib``) to your ``DYLD_LIBRARY_PATH``
environmental variable.
Problems and solutions
^^^^^^^^^^^^^^^^^^^^^^
- Make sure that your Conan version supports your XCode version. A
typical symptom of version mismatch is for example conan complaining
about incompatible ``compiler.version`` settings. You may need to
rerun any conan and cmake commands (and delete cache files first)
after compiler updates.
How to build on Windows
~~~~~~~~~~~~~~~~~~~~~~~
We use `Visual Studio
2019 <https://visualstudio.microsoft.com/de/vs/features/cplusplus/>`__
as compiler. We use `cmake <https://cmake.org/download/>`__ as build
tool.
1. clone/update the subrepo ``git submodule update --init proto``
2. ``mkdir build``
3. ``cd build``
4. ``conan install .. -g visual_studio -s arch=x86_64 -s build_type=Release -s compiler.toolset=v142 -s compiler.version=16 -s compiler.runtime=MD --build=missing --update``
5. ``cmake -B . ..``
6. open ``libcaosdb.sln`` with Visual Studio, change the buildtype to
``Release`` and build the project. (You can open Tools/Command
Line/Developer Command Prompt and execute
``msbuild libcaosdb.sln /property:Configuration=Release``)
Known problems
^^^^^^^^^^^^^^
- Linking dynamic libraries currently fails on Windows. So probably
other CaosDB libraries which make use of libcaosdb also will not
build. This is a known bug and we hope to fix this in the next
release. See
`#34 <https://gitlab.indiscale.com/caosdb/src/caosdb-cpplib/-/issues/34>`__
Troubleshooting
~~~~~~~~~~~~~~~
``conan install`` fails due to missing prebuilts
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
When ``conan install`` fails during the installation of the dependencies
because a precompiled package is not available for your specific
settings, try adding the ``--build=missing`` option:
``conan install .. [ other options ] --build=missing``. This should
download and compile the sources of the dependencies.
cmake fails when using the debug flag
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Depending on the clang version it might be necessary to additionally use
the following flag: ``-DCMAKE_CXX_FLAGS="-Wno-unused-parameter"``
conan uses outdated cppstd during install
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you experience compiler errors during a ``conan install`` process due
to, e.g., ``std::string_view`` being unavailable, try specifying the cpp
standard manually by
``conan install .. [other options] -s "compiler.cppstd=17"``.
Client Configuration
--------------------
You can use a json file for the configuration of the client. See
``test/test_data/test_caosdb_client.json`` for an example. You may use
``caosdb-client-configuration-schema.json`` to validate your schema.
Typically, you will need to provide the path to your SSL certificate.
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``.
2. ``$PWD/caosdb_client.json``
3. ``$PWD/caosdb-client.json``
4. ``$PWD/.caosdb_client.json``
5. ``$PWD/.caosdb-client.json``
6. ``$HOME/caosdb_client.json``
7. ``$HOME/caosdb-client.json``
8. ``$HOME/.caosdb_client.json``
9. ``$HOME/.caosdb-client.json``
Develop
-------
Unit tests
~~~~~~~~~~
.. _build-1:
Build
^^^^^
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 ..`` (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 may be necessary to also add
``-DCMAKE_CXX_FLAGS="-Wno-unused-parameter"``
4. ``cmake --build .``
Run
^^^
In the build directory, run ``ctest``
Framework
^^^^^^^^^
We use `GoogleTest <https://google.github.io/googletest/>`__ for unit
testing.
Test coverage
^^^^^^^^^^^^^
We use `gcov <https://gcc.gnu.org/onlinedocs/gcc/Gcov.html>`__ and
`lcov <https://github.com/linux-test-project/lcov>`__ for generating
test coverage reports.
In the build directory, generate the coverage report by running
``cmake --build . --target unit_test_coverage``.
Note that this special target will run the tests again. Thus it is not
necessary to run ``ctest`` prior to this target.
The coverage report can be viewed in a browser by opening
``<build_directory>/unit_test_coverage/index.html``.
Code formatting
~~~~~~~~~~~~~~~
- install clang-format on your system.
- ``clang-format -i --verbose $(find test/ src/ include/ -type f -iname "*.cpp" -o -iname "*.h" -o -iname "*.h.in")``
Naming conventions
~~~~~~~~~~~~~~~~~~
Please adhere to `Google’s C++ naming
conventions <https://google.github.io/styleguide/cppguide.html#Naming>`__.
Documentation
~~~~~~~~~~~~~
To build the documentation, run in the build directory
- ``cmake --build . --target doc-doxygen`` (generate Doxygen)
- ``cmake --build . --target doc-sphinx`` (generate Sphinx)
# How to Develop and Use Libcaosdb
## Dependencies
* See [DEPENDENCIES.md](Dependencies.md)
## Build
We use [cmake](https://cmake.org) as build tool.
0. clone/update the subrepo `git submodule update --init proto`
1. `mkdir build && cd build`
2. `conan install .. -s "compiler.libcxx=libstdc++11"`
3. `cmake -B . ..`
4. `cmake --build .`
You may also want to install libcaosdb system-wide to
`CMAKE_INSTALL_PREFIX/lib` by
5. `cmake --install .`
The default install prefix is `~/.local`. It can be set by adding
`-DCMAKE_INSTALL_PREFIX=/path/to/install/prefix` to the first cmake
command (3.).
### How to build on MacOS
Instead of the above conan command (2.) use
2. `conan install .. -s "compiler.cppstd=17"`
and continue as you would when building on a Linux system. You may
have to add `build/lib/` (or, alternatively after installation,
`CMAKE_INSTALL_PREFIX/lib`) to your `DYLD_LIBRARY_PATH` environmental
variable.
#### Problems and solutions ####
- Make sure that your conan version supports your XCode version. A typical symptom of version
mismatch is for example conan complaining about incompatible `compiler.version` settings. You may
need to rerun any conan and cmake commands (and delete cache files first) after compiler updates.
### How to build on Windows
We use [Visual Studio 2019](https://visualstudio.microsoft.com/de/vs/features/cplusplus/)
as compiler. We use [cmake](https://cmake.org/download/) as build tool.
0. clone/update the subrepo `git submodule update --init proto`
1. `mkdir build`
2. `cd build`
3. `conan install .. -g visual_studio -s arch=x86_64 -s build_type=Release -s compiler.toolset=v142 -s compiler.version=16 -s compiler.runtime=MD --build=missing --update`
4. `cmake -B . ..`
5. open ` libcaosdb.sln` with Visual Studio, change the buildtype to `Release`
and build the project. (You can open Tools/Command Line/Developer Command
Prompt and execute `msbuild libcaosdb.sln /property:Configuration=Release`)
### Creating a Local Conan Package ##
Building and installing libcaosdb with Conan is just a single command: `make conan`
For MacOS, you probably should adjust the option as mentioned above.
### Troubleshooting
#### `conan install` Fails Due to Missing Prebuilts
When `conan install` fails during the installation of the dependencies because
a precompiled package is not available for your specific settings, try adding
the `--build=missing` option: `conan install .. [ other options
] --build=missing`. This should download and compile the sources of the
dependencies.
#### cmake fails when using the Debug flag
Depending on the clang version it might be necessary to use additionally the following flag:
`-DCMAKE_CXX_FLAGS="-Wno-unused-parameter"`
## Unit Tests
### Build
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"`
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"`
5. `cmake --build .`
### Run
In the build directory, run `ctest`
### Framework
We use [GoogleTest](https://google.github.io/googletest/) for unit testing.
### Coverage
We use [gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html) and
[lcov](https://github.com/linux-test-project/lcov) for generating test coverage
reports.
In the build directory, generate the coverage report by running
`cmake --build . --target unit_test_coverage`.
Note that this special target will run the tests again. Thus it is not
necessary to run `ctest` prior to this target.
The coverage report can be viewed in a browser by opening
`<build_directory>/unit_test_coverage/index.html`.
## Code Formatting
* install clang-format on your system.
* `clang-format -i --verbose $(find test/ src/ include/ -type f -iname "*.cpp" -o -iname "*.h" -o -iname "*.h.in")`
## Naming Convention
Please adhere to [Google's C++ naming conventions](https://google.github.io/styleguide/cppguide.html#Naming).
## Client Configuration
You can use a json file for the configuration of the client. See
`test/test_data/test_caosdb_client.json` for an example. You may use
`caosdb-client-configuration-schema.json` to validate your schema.
Typically, you will need to provide the path to your SSL certificate.
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`.
2. `$PWD/caosdb_client.json`
3. `$PWD/caosdb-client.json`
4. `$PWD/.caosdb_client.json`
5. `$PWD/.caosdb-client.json`
6. `$HOME/caosdb_client.json`
7. `$HOME/caosdb-client.json`
8. `$HOME/.caosdb_client.json`
9. `$HOME/.caosdb-client.json`
## Documentation
In the build directory, run
* `cmake --build . --target doc-doxygen` (generate Doxygen)
* `cmake --build . --target doc-sphinx` (generate Sphinx)
......@@ -21,19 +21,25 @@
.. _capi_root:
=======
C API
=====
=======
.. warning::
The C API is intended for developers of other libraries. Special carre needs to be taken for
correct memory management.
.. note::
When working with libcaosdb's C API keep the following in
mind. Delete all objects (transactions, entities, properties,
parents, ...) that you created using a `caosdb_..._create_...`
function or released using a `caosdb_..._release_...` and only
those. This means, that any objects set by a `caosdb_..._get_...`
function, are managed by another owning object (e.g., a connection
object managed by the connection manager) should not be deleted
manually.
When working with libcaosdb's C API keep the following in mind:
Delete all objects (transactions, entities, properties, parents, ...) that you created using a
call to ``caosdb_..._create_...`` or released using ``caosdb_..._release_...`` and only those.
Specifically, any objects set by a ``caosdb_..._get_...`` function are managed by another owning
object (e.g., a connection object is managed by the connection manager) and thus should not be
deleted manually.
The underlying reason is that all C++ objects are realized in the
Extern C interface as mutable structs containing a void pointer to
......
......@@ -18,7 +18,7 @@
# -- Project information -----------------------------------------------------
project = '@CMAKE_PROJECT_NAME@'
copyright = '2021 IndiScale GmbH'
copyright = '2022 IndiScale GmbH'
author = 'Timm Fitschen'
version = '@CMAKE_PROJECT_VERSION@'
release = '@CMAKE_PROJECT_VERSION@'
......@@ -46,7 +46,7 @@ extensions = [
'sphinx_sitemap',
'sphinx.ext.inheritance_diagram',
'breathe',
"recommonmark" # For markdown files.
"recommonmark", # For markdown files.
]
# Add any paths that contain templates here, relative to this directory.
......
......@@ -21,8 +21,13 @@
.. _cppapi_root:
=========
C++ API
=======
=========
This is the C++ library for connecting to CaosDB. If you are interested in code examples, please
refer to the corresponding :doc:`documentation section<examples.rst>`.
.. toctree::
:glob:
......
......@@ -30,9 +30,12 @@ Welcome to |PROJECT_NAME|'s documentation!
:caption: Contents:
Welcome <self>
Getting Started <README_SETUP>
Getting Started <Install_develop>
Examples.rst
cppapi/index
capi/index
Changelog <CHANGELOG>
Dependencies <DEPENDENCIES>
Features <FEATURES>
* :ref:`genindex`
Legacy code
===========
- Older GCC compilers (before gcc-9) need explicit linking against libstdc++fs.a. The related
specifications can be removed from the CMakeLists.txt files once no such compilers are expected in
the wild anymore.
......@@ -16,13 +16,13 @@ pytz==2021.1
requests==2.25.1
six==1.16.0
snowballstemmer==2.1.0
Sphinx==4.0.1
sphinx-rtd-theme==0.5.2
Sphinx==4.5.0
sphinx-rtd-theme==1.0.0
sphinx-sitemap==2.2.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==1.0.3
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.4
urllib3==1.26.4
sphinxcontrib-serializinghtml==1.1.5
urllib3==1.26.7
......@@ -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
......
......@@ -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:
......
......@@ -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
// 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/logging.h" // for SinkConfiguration, Loggin...
#include "caosdb/utility.h" // for load_json_file
#include "grpcpp/security/credentials.h" // for ChannelCredentials
#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 <filesystem> // for path, exists
#include <iosfwd> // for ostream
#include <memory> // for unique_ptr, shared_ptr
#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;
......
......@@ -27,29 +27,29 @@
* @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/v1alpha1/main.grpc.pb.h" // for EntityTransactionSe...
#include "caosdb/entity/v1/main.grpc.pb.h" // for EntityTransactionSe...
#include "caosdb/info.h" // for VersionInfo
#include "caosdb/info/v1alpha1/main.grpc.pb.h" // for GeneralInfoService:...
#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::v1alpha1::EntityTransactionService;
using caosdb::entity::v1alpha1::FileTransmissionService;
using caosdb::entity::v1::EntityTransactionService;
using caosdb::entity::v1::FileTransmissionService;
using caosdb::info::VersionInfo;
using caosdb::info::v1alpha1::GeneralInfoService;
using caosdb::info::v1::GeneralInfoService;
using caosdb::transaction::Transaction;
using caosdb::transaction::TransactionStatus;
using std::filesystem::path;
/**
* @brief A reusable connection to a CaosDBServer.
......
......@@ -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",
......
......@@ -29,16 +29,16 @@
#ifndef CAOSDB_DATA_TYPE_H
#define CAOSDB_DATA_TYPE_H
#include "caosdb/protobuf_helper.h" // for ProtoMessageWrapper
#include "caosdb/entity/v1alpha1/main.pb.h" // for RepeatedPtrField, Message
#include "caosdb/entity/v1/main.pb.h" // for RepeatedPtrField, Message
#include <memory> // for unique_ptr
#include <string> // for string
namespace caosdb::entity {
using ProtoAtomicDataType = caosdb::entity::v1alpha1::AtomicDataType;
using ProtoDataType = caosdb::entity::v1alpha1::DataType;
using ProtoListDataType = caosdb::entity::v1alpha1::ListDataType;
using ProtoReferenceDataType = caosdb::entity::v1alpha1::ReferenceDataType;
using DataTypeCase = caosdb::entity::v1alpha1::DataType::DataTypeCase;
using ListDataTypeCase = caosdb::entity::v1alpha1::ListDataType::ListDataTypeCase;
using ProtoAtomicDataType = caosdb::entity::v1::AtomicDataType;
using ProtoDataType = caosdb::entity::v1::DataType;
using ProtoListDataType = caosdb::entity::v1::ListDataType;
using ProtoReferenceDataType = caosdb::entity::v1::ReferenceDataType;
using DataTypeCase = caosdb::entity::v1::DataType::DataTypeCase;
using ListDataTypeCase = caosdb::entity::v1::ListDataType::ListDataTypeCase;
using caosdb::utility::ProtoMessageWrapper;
using caosdb::utility::ScalarProtoMessageWrapper;
......@@ -181,6 +181,8 @@ public:
}
}
~DataType() = default;
inline static auto ListOf(const AtomicDataType &atomic_data_type) -> DataType {
return DataType(atomic_data_type, true);
}
......
......@@ -30,46 +30,45 @@
#define CAOSDB_ENTITY_H
#include "caosdb/data_type.h" // for DataType
#include "caosdb/entity/v1alpha1/main.pb.h" // for RepeatedPtrField
#include "caosdb/entity/v1/main.pb.h" // for RepeatedPtrField
#include "caosdb/logging.h" // for CAOSDB_LOG_WARN
#include "caosdb/message_code.h" // for get_message_code
#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::v1alpha1::IdResponse;
using ProtoParent = caosdb::entity::v1alpha1::Parent;
using ProtoProperty = caosdb::entity::v1alpha1::Property;
using ProtoEntity = caosdb::entity::v1alpha1::Entity;
using ProtoFileDescriptor = caosdb::entity::v1alpha1::FileDescriptor;
using ProtoMessage = caosdb::entity::v1alpha1::Message;
using ProtoValue = caosdb::entity::v1alpha1::Value;
using ProtoDataType = caosdb::entity::v1alpha1::DataType;
using caosdb::entity::v1alpha1::EntityRole;
using ProtoImportance = caosdb::entity::v1alpha1::Importance;
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;
using ProtoFileDescriptor = caosdb::entity::v1::FileDescriptor;
using ProtoMessage = caosdb::entity::v1::Message;
using ProtoValue = caosdb::entity::v1::Value;
using ProtoDataType = caosdb::entity::v1::DataType;
using caosdb::entity::v1::EntityRole;
using ProtoImportance = caosdb::entity::v1::Importance;
using caosdb::StatusCode;
using caosdb::entity::v1alpha1::EntityResponse;
using caosdb::entity::v1alpha1::FileTransmissionId;
using caosdb::entity::v1::EntityResponse;
using caosdb::entity::v1::FileTransmissionId;
using caosdb::utility::get_arena;
using caosdb::utility::ProtoMessageWrapper;
using ::google::protobuf::RepeatedPtrField;
......@@ -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.
*
......@@ -383,6 +385,37 @@ class Parent : public ScalarProtoMessageWrapper<ProtoParent> {
public:
explicit inline Parent(ProtoParent *wrapped) : ScalarProtoMessageWrapper<ProtoParent>(wrapped){};
Parent() : ScalarProtoMessageWrapper<ProtoParent>(){};
~Parent() = default;
/**
* Copy constructor.
*/
inline Parent(const Parent &other)
: Parent(ProtoMessageWrapper<ProtoParent>::CopyProtoMessage(other.wrapped)) {}
/**
* Move constructor.
*/
inline Parent(Parent &&other) : Parent(other.wrapped) { other.wrapped = nullptr; }
/**
* Copy assignment operator.
*/
inline auto operator=(const Parent &other) -> Parent & {
if (this != &other) {
this->wrapped->CopyFrom(*other.wrapped);
}
return *this;
}
/**
* Move assignment operator.
*/
inline auto operator=(Parent &&other) -> Parent & {
this->wrapped = other.wrapped;
other.wrapped = nullptr;
return *this;
}
/**
* Return the id of the parent entity.
......@@ -454,11 +487,13 @@ public:
private:
inline Parents() : RepeatedPtrFieldWrapper<Parent, ProtoParent>(){};
explicit inline Parents(
::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Parent> *wrapped)
explicit inline Parents(::google::protobuf::RepeatedPtrField<caosdb::entity::v1::Parent> *wrapped)
: RepeatedPtrFieldWrapper<Parent, ProtoParent>(wrapped){};
};
///////////////////////////////////////////////////////////////////////////////
// class Property /////////////////////////////////////////////////////////////
/**
* Property of an Entity.
*
......@@ -497,6 +532,8 @@ public:
: ScalarProtoMessageWrapper<ProtoProperty>(), value(static_cast<ProtoValue *>(nullptr)),
data_type(static_cast<ProtoDataType *>(nullptr)){};
~Property() = default;
/**
* Return the id of this property
*/
......@@ -639,6 +676,9 @@ private:
: RepeatedPtrFieldWrapper<Property, ProtoProperty>(wrapped){};
};
///////////////////////////////////////////////////////////////////////////////
// class Entity ///////////////////////////////////////////////////////////////
/**
* Entity is the central and basic data object of CaosDB.
*
......@@ -648,14 +688,17 @@ private:
* Overview of the Constructors:
*
* <li> Entity() - Calls Entity(ProtoEntity *) with a fresh ProtoEntity
* <li> Entity(Entity) - Copy constructor, calls Entity(ProtoEntity *) after copying wrapped
* ProtoEntity of the original, then also copies all Messages. <li> Entity(ProtoEntity *) - The
* workhorse of the constructors. Initializes everything and does not call other Entity
* constructors. <li> Entity(EntityResponse *) - Constructor which is used by the Transaction class
* to create an Entity from the server's response, calls Entity(ProtoEntity). <li> Entity(IdResponse
* *) - Constructor which is used by the Transaction class to create an Entity from the servers's
* response. calls Entity(), then moves the data to the wrapped ProtoEntity.
*
* <li> Entity(const Entity&) - Copy constructor, calls Entity(ProtoEntity *) after
* copying wrapped ProtoEntity of the original, then also copies all Messages.
* <li> Entity(ProtoEntity *) - The workhorse of the constructors. Initializes
* everything and does not call other Entity constructors.
* <li> Entity(EntityResponse *) - Constructor which is used by the Transaction class
* to create an Entity from the server's response, calls Entity(ProtoEntity).
* <li> Entity(IdResponse *) - Constructor which is used by the Transaction
* class to create an Entity from the servers's response. calls Entity(),
* then moves the data to the wrapped ProtoEntity.
* <li> Entity(Entity&&) - Move constructor, calls Entity(ProtoEntity *), then
* moves the messages and resets the original,
*/
class Entity : public ScalarProtoMessageWrapper<ProtoEntity> {
public:
......@@ -677,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());
......@@ -698,6 +741,8 @@ public:
parents.wrapped = this->wrapped->mutable_parents();
};
~Entity() = default;
/**
* Move constructor.
*/
......@@ -705,8 +750,8 @@ public:
original.wrapped = nullptr;
original.value.wrapped = nullptr;
original.data_type.wrapped = nullptr;
this->properties = std::move(original.properties);
this->parents = std::move(original.parents);
original.properties.wrapped = nullptr;
original.parents.wrapped = nullptr;
this->errors = std::move(original.errors);
this->warnings = std::move(original.warnings);
this->infos = std::move(original.infos);
......@@ -738,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);
......@@ -825,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 &registration_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;
......@@ -874,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;
......
......@@ -101,12 +101,12 @@ public:
};
/**
* @brief The connection isn't known to the ConnectionManager under this name.
* @brief Exception for errors during the configuration of the connection.
*/
class UnknownConnectionError : public Exception {
class ConnectionConfigurationError : public Exception {
public:
explicit UnknownConnectionError(const std::string &what_arg)
: Exception(StatusCode::UNKNOWN_CONNECTION_ERROR, what_arg) {}
explicit ConnectionConfigurationError(const std::string &what_arg)
: Exception(StatusCode::CONNECTION_CONFIGURATION_ERROR, what_arg) {}
};
} // namespace caosdb::exceptions
......
......@@ -50,8 +50,8 @@
#define CAOSDB_FILE_TRANSMISSION_DOWNLOAD_REQUEST_HANDLER_H
#include "caosdb/entity.h" // for FileDescriptor
#include "caosdb/entity/v1alpha1/main.grpc.pb.h" // for FileTransmissionS...
#include "caosdb/entity/v1alpha1/main.pb.h" // for FileDownloadResponse
#include "caosdb/entity/v1/main.grpc.pb.h" // for FileTransmissionS...
#include "caosdb/entity/v1/main.pb.h" // for FileDownloadResponse
#include "caosdb/file_transmission/file_writer.h" // for FileWriter
#include "caosdb/handler_interface.h" // for HandlerTag, Handl...
#include <grpcpp/impl/codegen/async_stream.h> // for ClientAsyncReader
......@@ -62,9 +62,9 @@
namespace caosdb::transaction {
using caosdb::entity::FileDescriptor;
using caosdb::entity::v1alpha1::FileDownloadRequest;
using caosdb::entity::v1alpha1::FileDownloadResponse;
using caosdb::entity::v1alpha1::FileTransmissionService;
using caosdb::entity::v1::FileDownloadRequest;
using caosdb::entity::v1::FileDownloadResponse;
using caosdb::entity::v1::FileTransmissionService;
using caosdb::transaction::HandlerInterface;
using caosdb::transaction::HandlerTag;
......
......@@ -49,20 +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 <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;
......@@ -80,7 +79,7 @@ private:
void openFile();
std::ifstream stream_;
boost::filesystem::path filename_;
std::filesystem::path filename_;
unsigned long long size_;
};
......
......@@ -49,7 +49,7 @@
#ifndef CAOSDB_FILE_TRANSMISSION_FILE_WRITER_H
#define CAOSDB_FILE_TRANSMISSION_FILE_WRITER_H
#include <boost/filesystem/path.hpp> // for path
#include <filesystem> // for path
#include <fstream> // for ofstream
#include <string> // for string
......@@ -57,7 +57,7 @@ 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
......