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

Target

Select target project
  • caosdb/src/caosdb-cpplib
1 result
Show changes
Commits on Source (15)
Showing
with 558 additions and 513 deletions
......@@ -54,7 +54,7 @@ BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 80
ColumnLimit: 100
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
......
......@@ -24,6 +24,7 @@ variables:
CPPLIB_REGISTRY_IMAGE: $CI_REGISTRY/caosdb/src/caosdb-cpplib/testenv:$CI_COMMIT_REF_NAME
CPPINTTEST_PIPELINE: https://gitlab.indiscale.com/api/v4/projects/111/trigger/pipeline
CPPINTTEST_BRANCHES: https://gitlab.indiscale.com/api/v4/projects/111/repository/branches
GIT_SUBMODULE_STRATEGY: normal
## FOR DEBUGGING
......@@ -101,8 +102,13 @@ trigger_inttest:
# ... use an f-branch if posible...
- F_BRANCH=dev
- if echo "$CI_COMMIT_REF_NAME" | grep -c "^f-" ; then
CPPINT_REF=$CI_COMMIT_REF_NAME ;
F_BRANCH=$CI_COMMIT_REF_NAME ;
if curl -o /dev/null -s -w "%{http_code}" $CPPINTTEST_BRANCHES/$CI_COMMIT_REF_NAME | grep "404"; then
CPPINT_REF=dev ;
F_BRANCH=dev ;
else
CPPINT_REF=$CI_COMMIT_REF_NAME ;
F_BRANCH=$CI_COMMIT_REF_NAME ;
fi
fi;
# ... or use main if possible...
- if [[ "$CI_COMMIT_REF_NAME" == "main" ]] ; then
......
......@@ -5,10 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [0.0.13 - Unreleased]
### Added
- New functions getEnumNameFromValue() and getEnumValueFromName().
### Changed
### Deprecated
......
# 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 "cppstd=11"`
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.
### 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-install`
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 ..`
4. `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)
doc/README_SETUP.md
\ No newline at end of file
......@@ -81,10 +81,20 @@ if (DOXYGEN_FOUND)
-c ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR}
sphinx_out
DEPENDS doc-doxygen
DEPENDS doc-doxygen
Examples.rst
README_SETUP.md
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Sphinx"
VERBATIM )
VERBATIM
)
# Copying files is necessary: https://stackoverflow.com/a/45808534/232888
# TODO fix for docs
#FILE(COPY
#Examples.rst
#README_SETUP.md
# Tutorial.rst
#DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
else ()
message("Sphinx need to be installed to generate the sphinx documentation")
endif ()
......
Examples
========
Connect to a CaosDB server
--------------------------
See also the hints on how to :doc:`get started<README_SETUP>`, and set-up of
libcaosdb. In order to connect to a CaosDB server with libcaosdb you first have to configure the
connection via a configuration file as explained in the :ref:`configuration section <Client Configuration>`. Once the configuration is set up, connecting to the server is
as easy as
.. code:: cpp
const auto &connection =
caosdb::connection::ConnectionManager::GetDefaultConnection();
You can print the full version of the server that you are connected to (and
therby test the connection) via:
.. code:: cpp
// get version info of the server
connection.RetrieveVersionInfo()
const auto &v_info = connection->GetVersionInfo();
std::cout << "Server Version: " << v_info->GetMajor() << "."
<< v_info->GetMinor() << "." << v_info->GetPatch() << "-"
<< v_info->GetPreRelease() << "-" << v_info->GetBuild()
<< std::endl;
Retrieve a Record
-----------------
With libcaosdb you can create a transaction
object, fill it with sub-requests, execute it, and retrieve the
result(s) . This
is handy when you want to have several requests in the same transaction.
However, most of the time, e.g., when retrieving one or multiple
Records, this is not necessary. libcaosdb provides helper functions so
you don’t have to worry about transactions and their executions. Assume
you want to retrieve an Entity with id=123. This is done via
.. code:: cpp
const auto &connection =
caosdb::connection::ConnectionManager::GetDefaultConnection();
auto transaction(connection->CreateTransaction());
const auto *id = "1231";
transaction->RetrieveById(id);
auto status = transaction->Execute();
const auto &result_set = transaction->GetResultSet();
const auto &entity = result_set.at(0)
You can then use the getter methods like :cpp:any:`GetId<caosdb::entity::Entity::GetId>`,
:cpp:any:`GetParents<caosdb::entity::Entity::GetParents>`, or :cpp:any:`GetProperties`<caosdb::entity::Entity::GetProperties>` to get the
name, the parents, or the properties of the retrieved entity.
Retrieving multiple entities works in the same way. Type
.. code:: cpp
const std::vector<std::string> ids = {"1220", "1221", "1222"};
transaction->RetrieveById(ids.begin(), ids.end());
to retrieve the entities with ids 1220, 1221 and 1222. They can then be
accessed using ``result_set.at(1)`` etc.
The same (and more) can be achieved by building and executing the
transaction manually. This is done by
.. code:: cpp
const auto &connection =
caosdb::connection::ConnectionManager::GetDefaultConnection();
auto transaction(connection->CreateTransaction());
transaction->RetrieveById("1231");
transaction->RetrieveById("1233");
auto status = transaction->Execute();
A result set can be obtained
via :cpp:any:`GetResultSet`<caosdb::transaction::Transaction::GetResultSet>` which contains the resulting entities
and can, e.g., be checked for length.
Execute queries
---------------
Executing queries works very similar to the retrieval of entities via
ids.
FIND and SELECT queries
~~~~~~~~~~~~~~~~~~~~~~~
In general, entities can be found using CaosDB’s query language like
.. code:: cpp
const auto &connection =
caosdb::connection::ConnectionManager::GetDefaultConnection();
auto query_transaction(connection->CreateTransaction());
query_transaction->Query("FIND ENTITY WITH id = 1222");
query_transaction->Execute();
auto result_set = query_transaction->GetResultSet();
std::cout << "Found " << result_set.size()
<< "entity with id="
<< result_set.at(0).GetId() << std::endl;
``result_set`` is a (possibly empty) list of entities that can be
inspected as above.
::
SELECT queries haven't been implemented in the C++ client yet and
thus cannot be executed from libcaosdb right now. SELECT queries
will be added in a future release.
COUNT queries
~~~~~~~~~~~~~
COUNT queries are different from FIND or SELECT queries in two ways.
Firstly, they do not return entities but a single number which is why,
secondly, they do not have a result set that could be returned.
The result of the count is
obtained using the :cpp:any:`GetCountResult<caosdb::transaction::Transaction::GetCountResult>` function:
.. code:: cpp
const auto &connection =
caosdb::connection::ConnectionManager::GetDefaultConnection();
auto query_transaction(connection->CreateTransaction());
query_transaction->Query("COUNT RECORD person WITH NAME LIKE '*Baggins'");
query_transaction->Execute();
std::cout << "Found " << query_transaction->GetCountResult()
<< "entities."<< std::endl;
Insert, update, and delete entities
-----------------------------------
Insert, update and delete operations function the same way. The respective
task is added to a transaction and the transaction is executed.
.. code:: cpp
const auto &connection =
caosdb::connection::ConnectionManager::GetDefaultConnection();
// ######## INSERT ########
// create the entity
Entity entity;
entity.SetRole(Role::RECORD_TYPE);
entity.SetName("RT1");
// create the transaction, add the task and execute the transaction
auto insert_transaction(connection->CreateTransaction());
insert_transaction->InsertEntity(&entity);
auto insert_status = insert_transaction->Execute();
const auto &insert_result_set = insert_transaction->GetResultSet();
// the result is an entity with the new id
const auto &new_entity = insert_result_set.at(0);
std::cout << "The newly inserted entity has the id "
<< new_entity.GetId() << std::endl;
// get the inserted entity
// RETRIEVE
auto retrieve_transaction(connection->CreateTransaction());
retrieve_transaction->RetrieveById(new_entity.GetId());
retrieve_transaction->Execute();
// save the entity from the result set in a new variable
auto update_entity(retrieve_transaction->GetResultSet().at(0));
// ######## UPDATE ########
// and change it
update_entity.SetName("RT1-Update");
// create update transaction
auto update_transaction(connection->CreateTransaction());
update_transaction->UpdateEntity(&update_entity);
auto update_status = update_transaction->Execute();
// same as with insert transaction, the update transaction returns an entity
// with the id
const auto &updated_entity = update_transaction->GetResultSet().at(0);
std::cout << "The entity with the id "
<< update_entity.GetId() << "was updated." << std::endl;
// ######## DELETE ########
auto delete_transaction(connection->CreateTransaction());
delete_transaction->DeleteById(updated_entity .GetId());
auto delete_status = delete_transaction->Execute();
// again, the delete transaction returns a result set with entities
// with the ids that where deleted
const auto &delete_result_set = delete_transaction->GetResultSet();
Up- and Download a file
---------------
.. code:: cpp
const auto &connection =
caosdb::connection::ConnectionManager::GetDefaultConnection();
Entity file;
file.SetRole(Role::FILE);
file.SetFilePath("test.txt");
file.SetLocalPath(test_upload_file_1);
// in order to upload a file, the corresponding entity simply has to be
// inserted
auto insert_transaction(connection->CreateTransaction());
insert_transaction->InsertEntity(&file);
insert_transaction->Execute();
// entity in the result set contains the new id
const auto &insert_results = insert_transaction->GetResultSet();
const auto &inserted_file = insert_results.at(0);
// for the download you need to use the RetrieveAndDownloadFilesById task and
// supply the path where the file shall be stored
test_download_file = fs::path("test_download_file_delete_me.dat");
auto download_transaction(connection->CreateTransaction());
download_transaction->RetrieveAndDownloadFilesById(
inserted_file.GetId(), test_download_file.string());
download_transaction->ExecuteAsynchronously();
download_transaction->WaitForIt().GetCode()
const auto &download_results = download_transaction->GetResultSet();
const auto &downloaded_file = download_results.at(0);
# 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 "cppstd=11"`
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.
### 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-install`
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 ..`
4. `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)
......@@ -45,7 +45,8 @@ extensions = [
'sphinx.ext.viewcode',
'sphinx_sitemap',
'sphinx.ext.inheritance_diagram',
'breathe'
'breathe',
"recommonmark" # For markdown files.
]
# Add any paths that contain templates here, relative to this directory.
......
......@@ -25,13 +25,13 @@
Welcome to |PROJECT_NAME|'s documentation!
==========================================
This is work in progress.
.. toctree::
:maxdepth: 4
:caption: Contents:
Welcome <self>
Getting Started <README_SETUP>
Examples.rst
cppapi/index
capi/index
......
......@@ -2,6 +2,7 @@ alabaster==0.7.12
Babel==2.9.1
breathe==4.30.0
certifi==2020.12.5
recommonmark
chardet==4.0.0
docutils==0.16
idna==2.10
......
......@@ -70,8 +70,7 @@ public:
auto GetMetadata(string_ref service_url, string_ref method_name,
const AuthContext &channel_auth_context,
std::multimap<grpc::string, grpc::string> *metadata)
-> Status override;
std::multimap<grpc::string, grpc::string> *metadata) -> Status override;
};
class PlainPasswordAuthenticator : public Authenticator {
......@@ -79,11 +78,9 @@ private:
std::string basic;
public:
PlainPasswordAuthenticator(const std::string &username,
const std::string &password);
PlainPasswordAuthenticator(const std::string &username, const std::string &password);
[[nodiscard]] auto GetCallCredentials() const
-> std::shared_ptr<grpc::CallCredentials> override;
[[nodiscard]] auto GetCallCredentials() const -> std::shared_ptr<grpc::CallCredentials> override;
};
} // namespace authentication
} // namespace caosdb
......
......@@ -62,8 +62,7 @@ private:
public:
ConnectionConfiguration(const std::string &host, int port);
virtual ~ConnectionConfiguration() = default;
friend auto operator<<(std::ostream &out,
const ConnectionConfiguration &configuration)
friend auto operator<<(std::ostream &out, const ConnectionConfiguration &configuration)
-> std::ostream &;
[[nodiscard]] auto virtual ToString() const -> std::string = 0;
......@@ -79,8 +78,7 @@ private:
public:
InsecureConnectionConfiguration(const std::string &host, int port);
[[nodiscard]] auto GetChannelCredentials() const
-> std::shared_ptr<ChannelCredentials> override;
[[nodiscard]] auto GetChannelCredentials() const -> std::shared_ptr<ChannelCredentials> override;
[[nodiscard]] auto ToString() const -> std::string override;
};
......@@ -91,15 +89,13 @@ private:
public:
TlsConnectionConfiguration(const std::string &host, int port);
TlsConnectionConfiguration(const std::string &host, int port,
const Authenticator &authenticator);
TlsConnectionConfiguration(const std::string &host, int port, const Authenticator &authenticator);
TlsConnectionConfiguration(const std::string &host, int port,
const CertificateProvider &certificate_provider);
TlsConnectionConfiguration(const std::string &host, int port,
const CertificateProvider &certificate_provider,
const Authenticator &authenticator);
[[nodiscard]] auto GetChannelCredentials() const
-> std::shared_ptr<ChannelCredentials> override;
[[nodiscard]] auto GetChannelCredentials() const -> std::shared_ptr<ChannelCredentials> override;
[[nodiscard]] auto ToString() const -> std::string override;
};
......@@ -114,17 +110,13 @@ public:
private:
auto ConvertLogLevel(const std::string &string_level) const -> int;
auto CreateConsoleSinkConfiguration(const object &from,
const std::string &name, int level) const
auto CreateConsoleSinkConfiguration(const object &from, const std::string &name, int level) const
-> std::shared_ptr<caosdb::logging::SinkConfiguration>;
auto CreateSyslogSinkConfiguration(const object &from,
const std::string &name, int level) const
auto CreateSyslogSinkConfiguration(const object &from, const std::string &name, int level) const
-> std::shared_ptr<caosdb::logging::SinkConfiguration>;
auto CreateFileSinkConfiguration(const object &from, const std::string &name,
int level) const
auto CreateFileSinkConfiguration(const object &from, const std::string &name, int level) const
-> std::shared_ptr<caosdb::logging::SinkConfiguration>;
auto CreateSinkConfiguration(const object &from, const std::string &name,
int default_level) const
auto CreateSinkConfiguration(const object &from, const std::string &name, int default_level) const
-> std::shared_ptr<caosdb::logging::SinkConfiguration>;
auto CreateLoggingConfiguration(const object &from) const
-> caosdb::logging::LoggingConfiguration;
......@@ -143,23 +135,19 @@ private:
/**
* @param from - a single connection configuration.
*/
auto CreateCertificateProvider(const object &from) const
-> std::unique_ptr<CertificateProvider>;
auto CreateCertificateProvider(const object &from) const -> std::unique_ptr<CertificateProvider>;
/**
* @param from - a single connection configuration.
*/
auto CreateAuthenticator(const object &from) const
-> std::unique_ptr<Authenticator>;
auto CreateAuthenticator(const object &from) const -> std::unique_ptr<Authenticator>;
/**
* @param from - a single connection configuration.
*/
auto
CreateConnectionConfiguration(const bool tls, const std::string &host,
const int port,
const CertificateProvider *certificate_provider,
const Authenticator *authenticator) const
auto CreateConnectionConfiguration(const bool tls, const std::string &host, const int port,
const CertificateProvider *certificate_provider,
const Authenticator *authenticator) const
-> std::unique_ptr<ConnectionConfiguration>;
/**
......@@ -200,8 +188,7 @@ public:
/**
* See mLoadSingleJSONConfiguration.
*/
inline static auto LoadSingleJSONConfiguration(const path &json_file)
-> void {
inline static auto LoadSingleJSONConfiguration(const path &json_file) -> void {
GetInstance().mLoadSingleJSONConfiguration(json_file);
}
......@@ -218,8 +205,7 @@ public:
*/
inline static auto GetDefaultConnectionConfiguration()
-> std::unique_ptr<ConnectionConfiguration> {
return GetInstance().mGetConnectionConfiguration(
GetInstance().mGetDefaultConnectionName());
return GetInstance().mGetConnectionConfiguration(GetInstance().mGetDefaultConnectionName());
}
/**
......
......@@ -85,8 +85,7 @@ public:
* RetrieveVersionInfoNoExceptions() before the version info is locally
* available. Otherwise a nullptr is being returned.
*/
[[nodiscard]] inline auto GetVersionInfo() const noexcept
-> const VersionInfo * {
[[nodiscard]] inline auto GetVersionInfo() const noexcept -> const VersionInfo * {
return this->version_info.get();
};
......@@ -128,8 +127,7 @@ private:
auto mHasConnection(const std::string &name) const -> bool;
auto mGetConnection(const std::string &name) const
-> const std::shared_ptr<Connection> &;
auto mGetConnection(const std::string &name) const -> const std::shared_ptr<Connection> &;
auto mGetDefaultConnection() const -> const std::shared_ptr<Connection> &;
......@@ -148,22 +146,18 @@ public:
return ConnectionManager::GetInstance().mHasConnection(name);
};
inline static auto GetConnection(const std::string &name)
-> const std::shared_ptr<Connection> & {
inline static auto GetConnection(const std::string &name) -> const std::shared_ptr<Connection> & {
return ConnectionManager::GetInstance().mGetConnection(name);
};
/**
* Get the connection marked by the "default" key in the configuration.
*/
inline static auto GetDefaultConnection()
-> const std::shared_ptr<Connection> & {
inline static auto GetDefaultConnection() -> const std::shared_ptr<Connection> & {
return ConnectionManager::GetInstance().mGetDefaultConnection();
};
inline static auto Reset() -> void {
return ConnectionManager::GetInstance().mReset();
};
inline static auto Reset() -> void { return ConnectionManager::GetInstance().mReset(); };
ConnectionManager(ConnectionManager const &) = delete;
void operator=(ConnectionManager const &) = delete;
......
......@@ -38,17 +38,16 @@ 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 ListDataTypeCase = caosdb::entity::v1alpha1::ListDataType::ListDataTypeCase;
using caosdb::utility::ProtoMessageWrapper;
class Entity;
class Property;
// Atomic data types.
enum AtomicDataType {
enum class AtomicDataType {
// The data type is unset/unknown.
UNSPECIFIED_DATA_TYPE = ProtoAtomicDataType::ATOMIC_DATA_TYPE_UNSPECIFIED,
UNSPECIFIED = ProtoAtomicDataType::ATOMIC_DATA_TYPE_UNSPECIFIED,
// TEXT data type.
TEXT = ProtoAtomicDataType::ATOMIC_DATA_TYPE_TEXT,
// DOUBLE data type.
......@@ -61,13 +60,18 @@ enum AtomicDataType {
BOOLEAN = ProtoAtomicDataType::ATOMIC_DATA_TYPE_BOOLEAN,
};
const std::map<AtomicDataType, std::string> atomicdatatype_names = {
{AtomicDataType::UNSPECIFIED, "UNSPECIFIED"}, {AtomicDataType::TEXT, "TEXT"},
{AtomicDataType::DOUBLE, "DOUBLE"}, {AtomicDataType::DATETIME, "DATETIME"},
{AtomicDataType::INTEGER, "INTEGER"}, {AtomicDataType::BOOLEAN, "BOOLEAN"}};
class DataType;
class ListDataType;
class ReferenceDataType : public ProtoMessageWrapper<ProtoDataType> {
public:
[[nodiscard]] inline auto GetName() const noexcept -> const std::string & {
// is list of refrence?
// is list of reference?
if (this->wrapped->data_type_case() == DataTypeCase::kListDataType) {
return this->wrapped->list_data_type().reference_data_type().name();
}
......@@ -84,13 +88,11 @@ protected:
static ReferenceDataType instance;
return instance;
}
inline static auto Create(ProtoDataType *wrapped)
-> std::unique_ptr<ReferenceDataType> {
inline static auto Create(ProtoDataType *wrapped) -> std::unique_ptr<ReferenceDataType> {
return std::unique_ptr<ReferenceDataType>(new ReferenceDataType(wrapped));
}
ReferenceDataType() : ProtoMessageWrapper<ProtoDataType>() {}
ReferenceDataType(ProtoDataType *wrapped)
: ProtoMessageWrapper<ProtoDataType>(wrapped) {}
ReferenceDataType(ProtoDataType *wrapped) : ProtoMessageWrapper<ProtoDataType>(wrapped) {}
};
class ListDataType : public ProtoMessageWrapper<ProtoDataType> {
......@@ -99,14 +101,13 @@ public:
return this->wrapped->list_data_type().list_data_type_case() ==
ListDataTypeCase::kReferenceDataType;
}
[[nodiscard]] inline auto GetReferenceDataType() const
-> const ReferenceDataType & {
[[nodiscard]] inline auto GetReferenceDataType() const -> const ReferenceDataType & {
if (!IsListOfReference()) {
return ReferenceDataType::GetEmptyInstance();
}
if (reference_data_type == nullptr) {
this->reference_data_type = std::unique_ptr<ReferenceDataType>(
ReferenceDataType::Create(this->wrapped).release());
this->reference_data_type =
std::unique_ptr<ReferenceDataType>(ReferenceDataType::Create(this->wrapped).release());
}
return *this->reference_data_type;
}
......@@ -116,8 +117,7 @@ public:
ListDataTypeCase::kAtomicDataType;
}
[[nodiscard]] inline auto GetAtomicDataType() const -> AtomicDataType {
return static_cast<AtomicDataType>(
this->wrapped->list_data_type().atomic_data_type());
return static_cast<AtomicDataType>(this->wrapped->list_data_type().atomic_data_type());
}
friend class DataType;
......@@ -127,33 +127,43 @@ protected:
static auto empty_instance = ListDataType();
return empty_instance;
}
inline static auto Create(ProtoDataType *wrapped)
-> std::unique_ptr<ListDataType> {
inline static auto Create(ProtoDataType *wrapped) -> std::unique_ptr<ListDataType> {
return std::unique_ptr<ListDataType>(new ListDataType(wrapped));
}
ListDataType() : ProtoMessageWrapper<ProtoDataType>() {}
ListDataType(ProtoDataType *wrapped)
: ProtoMessageWrapper<ProtoDataType>(wrapped) {}
ListDataType(ProtoDataType *wrapped) : ProtoMessageWrapper<ProtoDataType>(wrapped) {}
mutable std::unique_ptr<ReferenceDataType> reference_data_type;
};
class DataType : public ProtoMessageWrapper<ProtoDataType> {
public:
DataType(ProtoDataType *wrapped)
: ProtoMessageWrapper<ProtoDataType>(wrapped) {}
DataType(ProtoDataType *wrapped) : ProtoMessageWrapper<ProtoDataType>(wrapped) {}
DataType() : ProtoMessageWrapper<ProtoDataType>() {}
DataType(AtomicDataType data_type) : DataType() {
this->wrapped->set_atomic_data_type(
static_cast<ProtoAtomicDataType>(data_type));
/**
* Create an AtomicDataType typed DataType. For references, use the std::string constructor.
*/
DataType(AtomicDataType data_type, bool list_type = false) : DataType() {
if (list_type) {
this->wrapped->mutable_list_data_type()->set_atomic_data_type(
static_cast<ProtoAtomicDataType>(data_type));
} else {
this->wrapped->set_atomic_data_type(static_cast<ProtoAtomicDataType>(data_type));
}
}
DataType(const std::string &data_type) : DataType() {
this->wrapped->mutable_reference_data_type()->set_name(data_type);
/**
* Create a reference typed DataType.
*/
DataType(const std::string &data_type, bool list_type = false) : DataType() {
if (list_type) {
this->wrapped->mutable_list_data_type()->mutable_reference_data_type()->set_name(data_type);
} else {
this->wrapped->mutable_reference_data_type()->set_name(data_type);
}
}
inline static auto ListOf(const AtomicDataType &atomic_data_type)
-> DataType {
inline static auto ListOf(const AtomicDataType &atomic_data_type) -> DataType {
DataType result;
result.wrapped->mutable_list_data_type()->set_atomic_data_type(
static_cast<ProtoAtomicDataType>(atomic_data_type));
......@@ -161,9 +171,8 @@ public:
}
inline static auto ListOf(const std::string reference_data_type) -> DataType {
DataType result;
result.wrapped->mutable_list_data_type()
->mutable_reference_data_type()
->set_name(reference_data_type);
result.wrapped->mutable_list_data_type()->mutable_reference_data_type()->set_name(
reference_data_type);
return result;
}
......@@ -177,13 +186,12 @@ public:
[[nodiscard]] inline auto IsReference() const noexcept -> bool {
return this->wrapped->data_type_case() == DataTypeCase::kReferenceDataType;
}
[[nodiscard]] inline auto AsReference() const noexcept
-> const ReferenceDataType & {
[[nodiscard]] inline auto AsReference() const noexcept -> const ReferenceDataType & {
if (!IsReference()) {
return ReferenceDataType::GetEmptyInstance();
} else if (reference_data_type == nullptr) {
reference_data_type = std::unique_ptr<ReferenceDataType>(
ReferenceDataType::Create(this->wrapped).release());
reference_data_type =
std::unique_ptr<ReferenceDataType>(ReferenceDataType::Create(this->wrapped).release());
}
return *reference_data_type;
}
......@@ -196,16 +204,14 @@ public:
if (!IsList()) {
return ListDataType::GetEmptyInstance();
} else if (list_data_type == nullptr) {
list_data_type = std::unique_ptr<ListDataType>(
ListDataType::Create(this->wrapped).release());
list_data_type = std::unique_ptr<ListDataType>(ListDataType::Create(this->wrapped).release());
}
return *list_data_type;
}
inline auto operator==(const DataType &other) const noexcept -> bool {
// TODO(tf) Is this safe?
return this->wrapped->SerializeAsString() ==
other.wrapped->SerializeAsString();
return this->wrapped->SerializeAsString() == other.wrapped->SerializeAsString();
}
friend class Entity;
......
......@@ -46,12 +46,12 @@
#include <google/protobuf/message.h> // for RepeatedPtrField
#include <google/protobuf/util/json_util.h> // for MessageToJson...
#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 <vector> // for vector
#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 <vector> // for vector
namespace caosdb::entity {
using boost::filesystem::exists;
......@@ -75,27 +75,35 @@ static const std::string logger_name = "caosdb::entity";
/**
* The property importance.
*/
enum Importance {
IMPORTANCE_UNSPECIFIED =
ProtoImportance::IMPORTANCE_UNSPECIFIED, ///< Unset/None
OBLIGATORY =
ProtoImportance::IMPORTANCE_OBLIGATORY, ///< Obligatory importance.
RECOMMENDED =
ProtoImportance::IMPORTANCE_RECOMMENDED, ///< Recommended importance.
SUGGESTED = ProtoImportance::IMPORTANCE_SUGGESTED, ///< Suggested importance.
FIX = ProtoImportance::IMPORTANCE_FIX, ///< Fix importance.
enum class Importance {
UNSPECIFIED = ProtoImportance::IMPORTANCE_UNSPECIFIED, ///< Unset/None
OBLIGATORY = ProtoImportance::IMPORTANCE_OBLIGATORY, ///< Obligatory importance.
RECOMMENDED = ProtoImportance::IMPORTANCE_RECOMMENDED, ///< Recommended importance.
SUGGESTED = ProtoImportance::IMPORTANCE_SUGGESTED, ///< Suggested importance.
FIX = ProtoImportance::IMPORTANCE_FIX, ///< Fix importance.
};
const std::map<Importance, std::string> importance_names = {
{Importance::UNSPECIFIED, "UNSPECIFIED"},
{Importance::OBLIGATORY, "OBLIGATORY"},
{Importance::RECOMMENDED, "RECOMMENDED"},
{Importance::SUGGESTED, "SUGGESTED"},
{Importance::FIX, "FIX"}};
/**
* The entity role.
*/
enum Role {
ROLE_UNSPECIFIED = EntityRole::ENTITY_ROLE_UNSPECIFIED, ///< Unset/None
RECORD_TYPE = EntityRole::ENTITY_ROLE_RECORD_TYPE, ///< RecordType
RECORD = EntityRole::ENTITY_ROLE_RECORD, ///< Record
PROPERTY = EntityRole::ENTITY_ROLE_PROPERTY, ///< Property
FILE = EntityRole::ENTITY_ROLE_FILE, ///< File
enum class Role {
UNSPECIFIED = EntityRole::ENTITY_ROLE_UNSPECIFIED, ///< Unset/None
RECORD_TYPE = EntityRole::ENTITY_ROLE_RECORD_TYPE, ///< RecordType
RECORD = EntityRole::ENTITY_ROLE_RECORD, ///< Record
PROPERTY = EntityRole::ENTITY_ROLE_PROPERTY, ///< Property
FILE = EntityRole::ENTITY_ROLE_FILE, ///< File
};
const std::map<Role, std::string> role_names = {{Role::UNSPECIFIED, "UNSPECIFIED"},
{Role::RECORD_TYPE, "RECORD_TYPE"},
{Role::RECORD, "RECORD"},
{Role::PROPERTY, "PROPERTY"},
{Role::FILE, "FILE"}};
struct FileDescriptor {
FileTransmissionId *file_transmission_id;
......@@ -119,9 +127,7 @@ public:
/**
* Return a const reference to the element at the given index.
*/
[[nodiscard]] inline auto at(int index) const -> const T & {
return *mutable_at(index);
}
[[nodiscard]] inline auto at(int index) const -> const T & { return *mutable_at(index); }
/**
* Return a mutable pointer to the element at the given index.
......@@ -158,8 +164,7 @@ public:
protected:
RepeatedPtrFieldWrapper(){};
explicit inline RepeatedPtrFieldWrapper(
::google::protobuf::RepeatedPtrField<P> *wrapped)
explicit inline RepeatedPtrFieldWrapper(::google::protobuf::RepeatedPtrField<P> *wrapped)
: wrapped(wrapped){};
/**
......@@ -203,8 +208,7 @@ protected:
private:
class iterator : public std::iterator<std::output_iterator_tag, T> {
public:
explicit iterator(const RepeatedPtrFieldWrapper<T, P> *instance,
int index = 0);
explicit iterator(const RepeatedPtrFieldWrapper<T, P> *instance, int index = 0);
// TODO(henrik) add unit tests
auto operator*() const -> T &;
auto operator++() -> iterator &;
......@@ -218,8 +222,8 @@ private:
};
template <class T, class P>
RepeatedPtrFieldWrapper<T, P>::iterator::iterator(
const RepeatedPtrFieldWrapper<T, P> *instance, int index)
RepeatedPtrFieldWrapper<T, P>::iterator::iterator(const RepeatedPtrFieldWrapper<T, P> *instance,
int index)
: current_index(index), instance(instance) {}
template <typename T, typename P>
......@@ -243,32 +247,27 @@ auto RepeatedPtrFieldWrapper<T, P>::iterator::operator++(int)
}
template <typename T, typename P>
auto RepeatedPtrFieldWrapper<T, P>::iterator::operator!=(
const iterator &rhs) const -> bool {
auto RepeatedPtrFieldWrapper<T, P>::iterator::operator!=(const iterator &rhs) const -> bool {
return this->current_index != rhs.current_index;
}
template <typename T, typename P>
auto RepeatedPtrFieldWrapper<T, P>::begin()
-> RepeatedPtrFieldWrapper<T, P>::iterator {
auto RepeatedPtrFieldWrapper<T, P>::begin() -> RepeatedPtrFieldWrapper<T, P>::iterator {
return RepeatedPtrFieldWrapper<T, P>::iterator(this, 0);
}
template <typename T, typename P>
auto RepeatedPtrFieldWrapper<T, P>::end()
-> RepeatedPtrFieldWrapper<T, P>::iterator {
auto RepeatedPtrFieldWrapper<T, P>::end() -> RepeatedPtrFieldWrapper<T, P>::iterator {
return RepeatedPtrFieldWrapper<T, P>::iterator(this, size());
}
template <typename T, typename P>
auto RepeatedPtrFieldWrapper<T, P>::begin() const
-> const RepeatedPtrFieldWrapper<T, P>::iterator {
auto RepeatedPtrFieldWrapper<T, P>::begin() const -> const RepeatedPtrFieldWrapper<T, P>::iterator {
return RepeatedPtrFieldWrapper<T, P>::iterator(this, 0);
}
template <typename T, typename P>
auto RepeatedPtrFieldWrapper<T, P>::end() const
-> const RepeatedPtrFieldWrapper<T, P>::iterator {
auto RepeatedPtrFieldWrapper<T, P>::end() const -> const RepeatedPtrFieldWrapper<T, P>::iterator {
return RepeatedPtrFieldWrapper<T, P>::iterator(this, size());
}
......@@ -296,9 +295,7 @@ public:
*
* The description is intended for a human reader.
*/
[[nodiscard]] inline auto GetDescription() const -> std::string {
return wrapped->description();
}
[[nodiscard]] inline auto GetDescription() const -> std::string { return wrapped->description(); }
friend class Entity;
// TODO(fspreck) Re-enable once we have decided how messages are
......@@ -372,8 +369,7 @@ public:
inline auto ToString() const -> const std::string {
google::protobuf::util::JsonOptions options;
std::string out;
google::protobuf::util::MessageToJsonString(*(this->wrapped), &out,
options);
google::protobuf::util::MessageToJsonString(*(this->wrapped), &out, options);
return out;
}
......@@ -443,8 +439,7 @@ public:
private:
inline Parents() : RepeatedPtrFieldWrapper(){};
explicit inline Parents(
::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Parent>
*wrapped)
::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Parent> *wrapped)
: RepeatedPtrFieldWrapper(wrapped){};
};
......@@ -457,8 +452,8 @@ private:
class Property {
public:
explicit inline Property(ProtoProperty *other)
: value(Value(other->mutable_value())),
data_type(DataType(other->mutable_data_type())), wrapped(other){};
: value(Value(other->mutable_value())), data_type(DataType(other->mutable_data_type())),
wrapped(other){};
Property();
/**
......@@ -534,8 +529,8 @@ public:
* Set the datatype of this property.
*/
auto SetDataType(const DataType &new_data_type) -> StatusCode;
auto SetDataType(const AtomicDataType new_data_type) -> StatusCode;
auto SetDataType(const std::string &new_data_type) -> StatusCode;
auto SetDataType(const AtomicDataType new_data_type, bool list_type = false) -> StatusCode;
auto SetDataType(const std::string &new_data_type, bool list_type = false) -> StatusCode;
/**
* Return a json string representing this property.
......@@ -545,8 +540,7 @@ public:
inline auto ToString() const -> const std::string {
google::protobuf::util::JsonOptions options;
std::string out;
google::protobuf::util::MessageToJsonString(*(this->wrapped), &out,
options);
google::protobuf::util::MessageToJsonString(*(this->wrapped), &out, options);
return out;
}
......@@ -578,9 +572,7 @@ private:
* for (auto &property : my_properties) {...}
* \endcode
*/
class Properties
: public RepeatedPtrFieldWrapper<Property,
caosdb::entity::v1alpha1::Property> {
class Properties : public RepeatedPtrFieldWrapper<Property, caosdb::entity::v1alpha1::Property> {
public:
~Properties() = default;
friend class Entity;
......@@ -588,10 +580,8 @@ public:
private:
inline Properties(){};
explicit inline Properties(
::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Property>
*wrapped)
: RepeatedPtrFieldWrapper<Property, caosdb::entity::v1alpha1::Property>(
wrapped){};
::google::protobuf::RepeatedPtrField<caosdb::entity::v1alpha1::Property> *wrapped)
: RepeatedPtrFieldWrapper<Property, caosdb::entity::v1alpha1::Property>(wrapped){};
};
/**
......@@ -601,8 +591,7 @@ class Entity {
public:
Entity();
inline Entity(const Entity &original)
: wrapped(original.wrapped),
value(Value(original.wrapped->mutable_value())),
: wrapped(original.wrapped), value(Value(original.wrapped->mutable_value())),
data_type(DataType(original.wrapped->mutable_data_type())) {
this->wrapped->CopyFrom(*original.wrapped);
data_type.wrapped = this->wrapped->mutable_data_type();
......@@ -625,56 +614,35 @@ public:
warnings.wrapped = CreateMessagesField();
infos.wrapped = CreateMessagesField();
};
explicit inline Entity(EntityResponse *response)
: Entity(response->release_entity()) {
explicit inline Entity(EntityResponse *response) : Entity(response->release_entity()) {
errors.wrapped->Swap(response->mutable_errors());
warnings.wrapped->Swap(response->mutable_warnings());
infos.wrapped->Swap(response->mutable_infos());
};
[[nodiscard]] inline auto GetId() const noexcept -> const std::string & {
return wrapped->id();
};
[[nodiscard]] inline auto HasId() const noexcept -> bool {
return !wrapped->id().empty();
}
[[nodiscard]] inline auto GetId() const noexcept -> const std::string & { return wrapped->id(); };
[[nodiscard]] inline auto HasId() const noexcept -> bool { return !wrapped->id().empty(); }
[[nodiscard]] inline auto GetVersionId() const -> const std::string & {
return wrapped->version().id();
};
[[nodiscard]] inline auto GetRole() const -> Role {
return static_cast<Role>(wrapped->role());
};
[[nodiscard]] inline auto GetName() const -> const std::string & {
return wrapped->name();
};
[[nodiscard]] inline auto GetRole() const -> Role { return static_cast<Role>(wrapped->role()); };
[[nodiscard]] inline auto GetName() const -> const std::string & { return wrapped->name(); };
[[nodiscard]] inline auto GetDescription() const -> const std::string & {
return wrapped->description();
};
[[nodiscard]] inline auto GetDataType() const -> const DataType & {
return this->data_type;
};
[[nodiscard]] inline auto GetUnit() const -> const std::string & {
return wrapped->unit();
};
[[nodiscard]] inline auto GetValue() const -> const Value & {
return this->value;
};
[[nodiscard]] inline auto GetDataType() const -> const DataType & { return this->data_type; };
[[nodiscard]] inline auto GetUnit() const -> const std::string & { return wrapped->unit(); };
[[nodiscard]] inline auto GetValue() const -> const Value & { return this->value; };
[[nodiscard]] auto GetParents() const -> const Parents &;
// TODO(henrik) const prevents properties from being changed
// what about an interface that operates on the list directly?
[[nodiscard]] auto GetProperties() const -> const Properties &;
[[nodiscard]] inline auto GetErrors() const -> const Messages & {
return errors;
}
[[nodiscard]] inline auto HasErrors() const -> bool {
return this->errors.wrapped->size() > 0;
}
[[nodiscard]] auto GetWarnings() const -> const Messages & {
return warnings;
}
[[nodiscard]] inline auto GetErrors() const -> const Messages & { return errors; }
[[nodiscard]] inline auto HasErrors() const -> bool { return this->errors.wrapped->size() > 0; }
[[nodiscard]] auto GetWarnings() const -> const Messages & { return warnings; }
[[nodiscard]] inline auto HasWarnings() const -> bool {
return this->warnings.wrapped->size() > 0;
}
......@@ -683,8 +651,7 @@ public:
inline auto ToString() const -> const std::string {
google::protobuf::util::JsonOptions options;
std::string out;
google::protobuf::util::MessageToJsonString(*(this->wrapped), &out,
options);
google::protobuf::util::MessageToJsonString(*(this->wrapped), &out, options);
return out;
}
......@@ -710,8 +677,8 @@ public:
auto SetUnit(const std::string &unit) -> void;
auto SetDataType(const DataType &new_data_type) -> StatusCode;
auto SetDataType(const AtomicDataType new_data_type) -> StatusCode;
auto SetDataType(const std::string &new_data_type) -> StatusCode;
auto SetDataType(const AtomicDataType new_data_type, bool list_type = false) -> StatusCode;
auto SetDataType(const std::string &new_data_type, bool list_type = false) -> StatusCode;
auto AppendProperty(const Property &property) -> void;
auto RemoveProperty(int index) -> void;
......@@ -724,47 +691,36 @@ public:
auto CopyTo(ProtoEntity *target) -> void;
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 {
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 GetFileDescriptor() -> FileDescriptor & { return this->file_descriptor; }
inline auto GetLocalPath() const noexcept -> const boost::filesystem::path & {
return this->file_descriptor.local_path;
}
inline auto SetLocalPath(const boost::filesystem::path &local_path) noexcept
-> StatusCode {
inline auto SetLocalPath(const boost::filesystem::path &local_path) noexcept -> StatusCode {
if (GetRole() != Role::FILE) {
CAOSDB_LOG_WARN(logger_name)
<< "Entity::SetLocalPath failed. This is not a file entity.";
CAOSDB_LOG_WARN(logger_name) << "Entity::SetLocalPath failed. This is not a file entity.";
return StatusCode::NOT_A_FILE_ENTITY;
}
if (!exists(local_path)) {
CAOSDB_LOG_WARN(logger_name)
<< "Entity::SetLocalPath failed. This file does not exists: "
<< local_path.string();
<< "Entity::SetLocalPath failed. This file does not exists: " << local_path.string();
return StatusCode::FILE_DOES_NOT_EXIST_LOCALLY;
}
if (is_directory(local_path)) {
CAOSDB_LOG_WARN(logger_name)
<< "Entity::SetLocalPath failed. This file is a directory: "
<< local_path.string();
<< "Entity::SetLocalPath failed. This file is a directory: " << local_path.string();
return StatusCode::PATH_IS_A_DIRECTORY;
}
CAOSDB_LOG_TRACE(logger_name)
<< "Entity::SetLocalPath(" << local_path.string() << ");";
CAOSDB_LOG_TRACE(logger_name) << "Entity::SetLocalPath(" << local_path.string() << ");";
this->file_descriptor.local_path = local_path;
return StatusCode::SUCCESS;
}
......
......@@ -65,8 +65,7 @@ public:
*/
class TransactionError : public Exception {
protected:
TransactionError(StatusCode code, const std::string &what_arg)
: Exception(code, what_arg) {}
TransactionError(StatusCode code, const std::string &what_arg) : Exception(code, what_arg) {}
public:
explicit TransactionError(const std::string &what_arg)
......
......@@ -74,8 +74,7 @@ using caosdb::transaction::HandlerTag;
class DownloadRequestHandler final : public HandlerInterface {
public:
DownloadRequestHandler(HandlerTag tag, FileTransmissionService::Stub *stub,
grpc::CompletionQueue *cq,
FileDescriptor file_descriptor);
grpc::CompletionQueue *cq, FileDescriptor file_descriptor);
~DownloadRequestHandler() override = default;
......
......@@ -73,8 +73,7 @@ public:
~RegisterFileUploadHandler();
RegisterFileUploadHandler(const RegisterFileUploadHandler &) = delete;
RegisterFileUploadHandler &
operator=(const RegisterFileUploadHandler &) = delete;
RegisterFileUploadHandler &operator=(const RegisterFileUploadHandler &) = delete;
RegisterFileUploadHandler(RegisterFileUploadHandler &&) = delete;
RegisterFileUploadHandler &operator=(RegisterFileUploadHandler &&) = delete;
......@@ -85,8 +84,7 @@ protected:
FileTransmissionService::Stub *stub_;
std::unique_ptr<grpc::ClientAsyncResponseReader<RegisterFileUploadResponse>>
rpc_;
std::unique_ptr<grpc::ClientAsyncResponseReader<RegisterFileUploadResponse>> rpc_;
RegisterFileUploadRequest *request_;
RegisterFileUploadResponse *response_;
......
......@@ -72,8 +72,7 @@ using caosdb::transaction::HandlerTag;
class UploadRequestHandler final : public HandlerInterface {
public:
UploadRequestHandler(HandlerTag tag, FileTransmissionService::Stub *stub,
grpc::CompletionQueue *cq,
FileDescriptor file_descriptor);
grpc::CompletionQueue *cq, FileDescriptor file_descriptor);
~UploadRequestHandler() override = default;
......@@ -89,13 +88,7 @@ public:
void Cancel() override;
protected:
enum class CallState {
NewCall,
SendingHeader,
SendingFile,
ExpectingResponse,
CallComplete
};
enum class CallState { NewCall, SendingHeader, SendingFile, ExpectingResponse, CallComplete };
void handleNewCallState();
void handleSendingHeaderState();
......