diff --git a/.gitea/workflows/aur.yml b/.forgejo/workflows/aur.yml similarity index 100% rename from .gitea/workflows/aur.yml rename to .forgejo/workflows/aur.yml diff --git a/.gitea/workflows/main.yml b/.forgejo/workflows/main.yml similarity index 78% rename from .gitea/workflows/main.yml rename to .forgejo/workflows/main.yml index ed68bb0..44dba97 100644 --- a/.gitea/workflows/main.yml +++ b/.forgejo/workflows/main.yml @@ -1,4 +1,4 @@ -name: Main LMDBAL workfow +name: Main LMDBAL workflow run-name: ${{ gitea.actor }} is running LMDBAL main workflow on: push: @@ -8,13 +8,13 @@ on: jobs: test-qt5: name: Test LMDBAL with qt5 - uses: ./.gitea/workflows/test.yml + uses: ./.forgejo/workflows/test.yml with: flags: -D QT_VERSION_MAJOR=5 -D LMDBAL_NAME=LMDBAL-QT5 test-qt6: name: Test LMDBAL with qt6 - uses: ./.gitea/workflows/test.yml + uses: ./.forgejo/workflows/test.yml with: flags: -D QT_VERSION_MAJOR=6 -D LMDBAL_NAME=LMDBAL-QT6 @@ -31,7 +31,7 @@ jobs: - name: Configure working-directory: ./build - run: cmake .. BUILD_DOC_HTML=True -D BUILD_DOC_XML=True -D BUILD_DOC_MAN=True -D BUILD_DOXYGEN_AWESOME=True + run: cmake .. LMDBAL_BUILD_DOC_HTML=True -D LMDBAL_BUILD_DOC_XML=True -D LMDBAL_BUILD_DOC_MAN=True -D LMDBAL_BUILD_DOXYGEN_AWESOME=True - name: Build working-directory: ./build @@ -39,7 +39,7 @@ jobs: - name: Copy docs via scp uses: appleboy/scp-action@master - # working-directory: ./build/doc //doesn't work + # working-directory: ./build/doc //doesn't work with: host: ${{ secrets.DOMAIN_ROOT }} username: ${{ secrets.DEPLOY_USER_NAME }} diff --git a/.gitea/workflows/release.yml b/.forgejo/workflows/release.yml similarity index 93% rename from .gitea/workflows/release.yml rename to .forgejo/workflows/release.yml index 733957a..1af4d7c 100644 --- a/.gitea/workflows/release.yml +++ b/.forgejo/workflows/release.yml @@ -7,7 +7,7 @@ on: jobs: qt5: name: Release qt5 build to AUR - uses: ./.gitea/workflows/aur.yml + uses: ./.forgejo/workflows/aur.yml with: package-name: lmdbal-qt5 description: LMDB Abstraction Layer, qt5 version @@ -20,7 +20,7 @@ jobs: qt6: name: Release qt6 build to AUR - uses: ./.gitea/workflows/aur.yml + uses: ./.forgejo/workflows/aur.yml with: package-name: lmdbal-qt6 description: LMDB Abstraction Layer, qt6 version diff --git a/.gitea/workflows/test.yml b/.forgejo/workflows/test.yml similarity index 82% rename from .gitea/workflows/test.yml rename to .forgejo/workflows/test.yml index 922e361..a0f3867 100644 --- a/.gitea/workflows/test.yml +++ b/.forgejo/workflows/test.yml @@ -14,7 +14,7 @@ on: jobs: test: - name: Building and rinning unit tests + name: Building and running unit tests runs-on: archlinux steps: - name: Check out repository code @@ -25,7 +25,7 @@ jobs: - name: Configure working-directory: ./build - run: cmake .. -D BUILD_TESTS=True -D QT_VERSION_MAJOR= ${{ inputs.flags }} + run: cmake .. -D LMDBAL_STRICT=True -D LMDBAL_BUILD_TESTS=True -D QT_VERSION_MAJOR= ${{ inputs.flags }} - name: Build working-directory: ./build diff --git a/CMakeLists.txt b/CMakeLists.txt index 97b21ff..325901b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required(VERSION 3.16) project(LMDBAL - VERSION 0.6.0 - DESCRIPTION "LMDB (Lightning Memory-Mapped Database Manager) Abstraction Layer" - LANGUAGES CXX + VERSION 0.6.0 + DESCRIPTION "LMDB (Lightning Memory-Mapped Database Manager) Abstraction Layer" + LANGUAGES CXX ) cmake_policy(SET CMP0076 NEW) @@ -11,12 +11,16 @@ cmake_policy(SET CMP0079 NEW) set(LMDBAL_NAME ${PROJECT_NAME} CACHE STRING "Override for library name and install path") -option(BUILD_STATIC "Builds library as static library" OFF) -option(BUILD_TESTS "Builds tests" OFF) -option(BUILD_DOC_MAN "Builds man page documentation" OFF) -option(BUILD_DOC_HTML "Builds html documentation" OFF) -option(BUILD_DOC_XML "Builds xml documentation" OFF) -option(BUILD_DOXYGEN_AWESOME "Builds documentation alternative style" OFF) +option(LMDBAL_BUILD_STATIC "Builds library as static library" OFF) +option(LMDBAL_BUILD_TESTS "Builds tests" OFF) +option(LMDBAL_BUILD_DOC_MAN "Builds man page documentation" OFF) +option(LMDBAL_BUILD_DOC_HTML "Builds html documentation" OFF) +option(LMDBAL_BUILD_DOC_XML "Builds xml documentation" OFF) +option(LMDBAL_BUILD_DOXYGEN_AWESOME "Builds documentation alternative style" OFF) +option(LMDBAL_STRICT "Builds with extra compiler warnings" OFF) +option(LMDBAL_ASAN "Enables Address Sanitizer" OFF) +option(LMDBAL_UBSAN "Enables Undefined Behavior Sanitizer" OFF) +option(LMDBAL_TSAN "Enables Thread Sanitizer" OFF) include(GNUInstallDirs) include(CMakePackageConfigHelpers) @@ -29,40 +33,80 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") string(TOLOWER ${LMDBAL_NAME} LMDBAL_NAME_LOW) if (NOT DEFINED QT_VERSION_MAJOR) - find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) -endif() + find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core) +endif () find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core) find_package(LMDB REQUIRED) # Build type if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Debug) + set(CMAKE_BUILD_TYPE Debug) endif () -if (BUILD_STATIC) - add_library(${LMDBAL_NAME} STATIC) +if (LMDBAL_BUILD_STATIC) + add_library(${LMDBAL_NAME} STATIC) else () - add_library(${LMDBAL_NAME} SHARED) + add_library(${LMDBAL_NAME} SHARED) endif() -if (CMAKE_BUILD_TYPE STREQUAL "Release") - list(APPEND COMPILE_OPTIONS -O3) -elseif (CMAKE_BUILD_TYPE STREQUAL "Debug") - list(APPEND COMPILE_OPTIONS -g) - list(APPEND COMPILE_OPTIONS -Wall) - list(APPEND COMPILE_OPTIONS -Wextra) -endif() + +if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + list(APPEND COMPILE_OPTIONS -Wall) + list(APPEND COMPILE_OPTIONS -Wextra) + list(APPEND COMPILE_OPTIONS -Wpedantic) + + if (CMAKE_BUILD_TYPE STREQUAL "Release") + list(APPEND COMPILE_OPTIONS -O3) + list(APPEND COMPILE_OPTIONS -DNDEBUG) + elseif (CMAKE_BUILD_TYPE STREQUAL "Debug") + list(APPEND COMPILE_OPTIONS -O0) + list(APPEND COMPILE_OPTIONS -g3) + list(APPEND COMPILE_OPTIONS -ggdb) + endif () + + if (LMDBAL_STRICT) + list(APPEND COMPILE_OPTIONS -Wall) + list(APPEND COMPILE_OPTIONS -Werror) + list(APPEND COMPILE_OPTIONS -Wconversion) + list(APPEND COMPILE_OPTIONS -Wnon-virtual-dtor) + list(APPEND COMPILE_OPTIONS -Wold-style-cast) + list(APPEND COMPILE_OPTIONS -Wcast-align) + list(APPEND COMPILE_OPTIONS -Wunused) + list(APPEND COMPILE_OPTIONS -Woverloaded-virtual) + list(APPEND COMPILE_OPTIONS -Wsign-conversion) + list(APPEND COMPILE_OPTIONS -Wnull-dereference) + endif () + + if(JAY_ENABLE_ASAN) + list(APPEND COMPILE_OPTIONS -fsanitize=address) + list(APPEND COMPILE_OPTIONS -fno-omit-frame-pointer) + list(APPEND LINK_OPTIONS -fsanitize=address) + add_link_options() + endif() + + if(JAY_ENABLE_UBSAN) + list(APPEND COMPILE_OPTIONS -fsanitize=undefined) + list(APPEND LINK_OPTIONS -fsanitize=undefined) + endif() + + if(JAY_ENABLE_TSAN) + list(APPEND COMPILE_OPTIONS -fsanitize=thread) + list(APPEND LINK_OPTIONS -fsanitize=thread) + endif() +endif () message("Compilation options: " ${COMPILE_OPTIONS}) +message("Linking options: " ${LINK_OPTIONS}) target_compile_options(${LMDBAL_NAME} PRIVATE ${COMPILE_OPTIONS}) +target_link_options(${LMDBAL_NAME} PRIVATE ${LINK_OPTIONS}) set_property(TARGET ${LMDBAL_NAME} PROPERTY VERSION ${version}) set_property(TARGET ${LMDBAL_NAME} PROPERTY SOVERSION 1) set_property(TARGET ${LMDBAL_NAME} PROPERTY EXPORT_NAME ${LMDBAL_NAME}) set_property(TARGET ${LMDBAL_NAME} PROPERTY INTERFACE_${LMDBAL_NAME}_MAJOR_VERSION 1) set_property(TARGET ${LMDBAL_NAME} APPEND PROPERTY - COMPATIBLE_INTERFACE_STRING ${LMDBAL_NAME}_MAJOR_VERSION + COMPATIBLE_INTERFACE_STRING ${LMDBAL_NAME}_MAJOR_VERSION ) if (UNIX) @@ -70,36 +114,36 @@ if (UNIX) set_property(TARGET ${LMDBAL_NAME} PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE) set_property(TARGET ${LMDBAL_NAME} PROPERTY SKIP_BUILD_RPATH FALSE) set_property(TARGET ${LMDBAL_NAME} PROPERTY BUILD_WITH_INSTALL_RPATH FALSE) -endif() +endif () add_subdirectory(src) -if (BUILD_DOC_MAN OR BUILD_DOC_HTML OR BUILD_DOC_XML) - find_package(Doxygen) - if (DOXYGEN_FOUND) - add_subdirectory(doc) - else() - message("Was trying to build documentation, but Doxygen was not found, skipping documentation") - endif() -endif() +if (LMDBAL_BUILD_DOC_MAN OR LMDBAL_BUILD_DOC_HTML OR LMDBAL_BUILD_DOC_XML) + find_package(Doxygen) + if (DOXYGEN_FOUND) + add_subdirectory(doc) + else () + message("Was trying to build documentation, but Doxygen was not found, skipping documentation") + endif () +endif () -if (BUILD_TESTS) - add_subdirectory(test) +if (LMDBAL_BUILD_TESTS) + add_subdirectory(test) endif () target_include_directories( - ${LMDBAL_NAME} - PUBLIC - $ - $ - $ + ${LMDBAL_NAME} + PUBLIC + $ + $ + $ ) target_include_directories(${LMDBAL_NAME} PRIVATE ${Qt${QT_VERSION_MAJOR}_INCLUDE_DIRS}) target_include_directories(${LMDBAL_NAME} PRIVATE ${Qt${QT_VERSION_MAJOR}Core_INCLUDE_DIRS}) target_link_libraries( - ${LMDBAL_NAME} - Qt${QT_VERSION_MAJOR}::Core - lmdb + ${LMDBAL_NAME} + Qt${QT_VERSION_MAJOR}::Core + lmdb ) configure_package_config_file( @@ -127,7 +171,7 @@ install(EXPORT ${LMDBAL_NAME_LOW}Targets ) install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/${LMDBAL_NAME_LOW}Config.cmake" - "${CMAKE_CURRENT_BINARY_DIR}/${LMDBAL_NAME_LOW}ConfigVersion.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${LMDBAL_NAME_LOW}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/${LMDBAL_NAME_LOW}ConfigVersion.cmake" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${LMDBAL_NAME_LOW} ) diff --git a/README.md b/README.md index 1226357..3c5d671 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ #### As a system library -If you're using LMDBAL as a system library you probably have no control over it's build options. The easiest way to include the project is to add following +If you're using LMDBAL as a system library, you probably have no control over its build options. +The easiest way to include the project is to add the following ``` find_package(lmdbal) @@ -29,14 +30,14 @@ if (LMDBAL_FOUND) endif() ``` -#### As an embeded subproject +#### As an embedded subproject -If you're using LMDBAL as a embeded library you might want to control it's build options, for example you can run +If you're using LMDBAL as a embedded library, you might want to control its build options, for example, you can run ``` -set(BUILD_STATIC ON) +set(LMDBAL_BUILD_STATIC ON) ``` -before including the library in your project. This will set the library to be build in a static mode. +... before including the library in your project. This will set the library to be build in a static mode. Then you want to run something like this ``` @@ -67,9 +68,11 @@ $ cmake --build . $ cmake --install . --prefix install ``` -This way will create you a `lmdbal/build` directory with temporary files, and `lmdbal/build/install` with all the export files for installation to the system. +This way will create you a `lmdbal/build` directory with temporary files, and `lmdbal/build/install` +with all the export files for installation to the system. -After `cmake ..` you can specify keys to alter the building process. In this context building keys are transfered like so +After `cmake ..` you can specify keys to alter the building process. +In this context building keys are transferred like so ``` cmake .. -D KEY1=VALUE1 -D KEY2=VALUE2 ... @@ -80,22 +83,26 @@ cmake .. -D KEY1=VALUE1 -D KEY2=VALUE2 ... Here is the list of keys you can pass to configuration phase of `cmake ..`: - `CMAKE_BUILD_TYPE` - `Debug` just builds showing all warnings, `Release` builds with no warnings and applies optimizations (default is `Debug`); -- `BUILD_STATIC` - `True` builds project as a static library, `False` builds as dynamic (default is `False`); -- `BUILD_TESTS` - `True` build unit tests, `False` does not (default is `False`); +- `LMDBAL_BUILD_STATIC` - `True` builds project as a static library, `False` builds as dynamic (default is `False`); +- `LMDBAL_BUILD_TESTS` - `True` build unit tests, `False` does not (default is `False`); - `BUILD_DOC` - `True` build doxygen documentation, `False` does not (default is `False`); -- `BUILD_DOXYGEN_AWESOME` - `True` build doxygen awesome theme if `BUILD_DOC` is also `True` (default is `False`); -- `QT_VERSION_MAJOR` - `5` links against Qt5, `6` links agains Qt6, there is no default, so, if you didn't specify it the project will chose automatically; -- `LMDBAL_NAME` - `LMDBAL` builds main target with this name, also install path witll be this name lowercase, usefull if you want to build `LMDBAL-QT6` not to conflict with `LMDBAL-QT5`; +- `LMDBAL_BUILD_DOXYGEN_AWESOME` - `True` build doxygen awesome theme if `BUILD_DOC` is also `True` (default is `False`); +- `QT_VERSION_MAJOR` - `5` links against Qt5, `6` links against Qt6, there is no default, so, if you didn't specify it, the project will choose automatically; +- `LMDBAL_NAME` - `LMDBAL` builds the main target with this name, also the installation path will be this name lowercase, useful if you want to build `LMDBAL-QT6` not to conflict with `LMDBAL-QT5`; +- `LMDBAL_STRICT` - `True` builds with extra warnings and considers them errors (default is `False`); +- `LMDBAL_ASAN` - `True` builds with address sanitizer (default is `False`); +- `LMDBAL_TSAN` - `True` builds with thread sanitizer (default is `False`); +- `LMDBAL_UBSAN` - `True` builds with undefined behavior sanitizer (default is `False`); #### Running tests -If you built the library with `-D BUILD_TESTS=True`, then there will be `lmdbal/build/tests/runUnitTests` executable file. You can simply run it as +If you built the library with `-D LMDBAL_BUILD_TESTS=True`, then there will be `lmdbal/build/tests/runUnitTests` executable file. You can run it as ``` ./runUnitTests ``` -if you're in the same directory with it +... if you're in the same directory with it ## License diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 0757340..66f3b76 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,14 +1,14 @@ -if (BUILD_DOC_HTML) +if (LMDBAL_BUILD_DOC_HTML) set(DOXYGEN_GENERATE_HTML YES) endif() -if (BUILD_DOC_MAN) +if (LMDBAL_BUILD_DOC_MAN) set(DOXYGEN_GENERATE_MAN YES) endif() -if (BUILD_DOC_XML) +if (LMDBAL_BUILD_DOC_XML) set(DOXYGEN_GENERATE_XML YES) endif() -if (BUILD_DOXYGEN_AWESOME) +if (LMDBAL_BUILD_DOXYGEN_AWESOME) include(ExternalProject) ExternalProject_Add(doxygen-awesome-css GIT_REPOSITORY https://github.com/jothepro/doxygen-awesome-css.git @@ -42,25 +42,25 @@ doxygen_add_docs( ALL COMMENT "Generate man and html pages" ) -if (BUILD_DOC_MAN) +if (LMDBAL_BUILD_DOC_MAN) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man TYPE DOC ) endif() -if (BUILD_DOC_HTML) +if (LMDBAL_BUILD_DOC_HTML) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html TYPE DOC ) endif() -if (BUILD_DOC_XML) +if (LMDBAL_BUILD_DOC_XML) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/xml TYPE DOC ) endif() -if (BUILD_DOXYGEN_AWESOME) +if (LMDBAL_BUILD_DOXYGEN_AWESOME) add_dependencies(documentation doxygen-awesome-css) endif() \ No newline at end of file diff --git a/src/base.cpp b/src/base.cpp index cac914b..5100c83 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -28,13 +28,13 @@ * \brief Database abstraction * * This is a basic class that represents the database as a collection of storages. - * Storages is something key-value database has instead of tables in classic SQL databases. + * Storages are something that key-value databases have instead of tables in classic SQL databases. */ /** * \brief Creates the database * - * \param[in] _name - name of the database, it is going to affect folder name that is created to store data + * \param[in] _name - name of the database, it is going to affect the folder name that is created to store data * \param[in] _mapSize - LMDB map size (MiB), multiplied by 1024^2 and passed to mdb_env_set_mapsize during the call of LMDBAL::Base::open() */ LMDBAL::Base::Base(const QString& _name, uint16_t _mapSize): @@ -60,13 +60,13 @@ LMDBAL::Base::~Base() { * \brief Closes the database * * Closes all lmdb handles, aborts all public transactions. - * This function will do nothing on closed database + * This function will do nothing on a closed database * * \exception LMDBAL::Unknown - thrown if something went wrong aborting transactions */ void LMDBAL::Base::close() { if (opened) { - for (const std::pair pair : transactions) { + for (const std::pair pair : transactions) { abortTransaction(pair.first, emptyName); pair.second->reset(); } @@ -84,8 +84,8 @@ void LMDBAL::Base::close() { * \brief Opens the database * * Almost every LMDBAL::Base require it to be opened, this function does it. - * It laso creates the directory for the database if it was an initial launch. - * This function will do nothing on opened database + * It also creates the directory for the database if it was an initial launch. + * This function will do nothing on an opened database * * \exception LMDBAL::Unknown - thrown if something went wrong opening storages and caches */ @@ -94,15 +94,14 @@ void LMDBAL::Base::open() { mdb_env_create(&environment); QString path = createDirectory(); - mdb_env_set_maxdbs(environment, storages.size()); + mdb_env_set_maxdbs(environment, static_cast(storages.size())); mdb_env_set_mapsize(environment, size * 1024UL * 1024UL); mdb_env_open(environment, path.toStdString().c_str(), 0, 0664); TransactionID txn = beginPrivateTransaction(emptyName); for (const std::pair& pair : storages) { StorageCommon* storage = pair.second; - int rc = storage->open(txn); - if (rc) + if (const int rc = storage->open(txn)) throw Unknown(name, mdb_strerror(rc)); } commitPrivateTransaction(txn, emptyName); @@ -113,9 +112,9 @@ void LMDBAL::Base::open() { /** * \brief Removes database directory * - * \returns true if removal was successfull of if no directory was created where it's expected to be, false otherwise + * \returns true if removal was successful of if no directory was created where it's expected to be, false otherwise * - * \exception LMDBAL::Opened - thrown if this function was called on opened database + * \exception LMDBAL::Opened - thrown if this function was called on an opened database */ bool LMDBAL::Base::removeDirectory() { if (opened) @@ -141,7 +140,7 @@ bool LMDBAL::Base::removeDirectory() { * * \returns the path of the created directory * - * \exception LMDBAL::Opened - thrown if called on opened database + * \exception LMDBAL::Opened - thrown if called on an opened database * \exception LMDBAL::Directory - if the database couldn't create the folder */ QString LMDBAL::Base::createDirectory() { diff --git a/src/base.h b/src/base.h index a4b60a7..4ccf45d 100644 --- a/src/base.h +++ b/src/base.h @@ -48,7 +48,7 @@ template class Cache; typedef MDB_txn* TransactionID; /**<\brief I'm going to use transaction pointers as transaction IDs*/ -typedef uint32_t SizeType; /**<\brief All LMDBAL sizes are uint32_t*/ +typedef uint32_t SizeType; /**<\brief All LMDBAL sizes are uint32*/ class Base { friend class StorageCommon; @@ -135,8 +135,8 @@ LMDBAL::Storage* LMDBAL::Base::addStorage(const std::string& storageName, if (opened) throw Opened(name, "add storage " + storageName); - Storage* storage = new Storage(this, storageName, duplicates); - std::pair pair = storages.insert(std::make_pair(storageName, (StorageCommon *)storage)); + auto storage = new Storage(this, storageName, duplicates); + std::pair pair = storages.emplace(storageName, static_cast(storage)); if (!pair.second) throw StorageDuplicate(name, storageName); @@ -163,8 +163,8 @@ LMDBAL::Cache * LMDBAL::Base::addCache(const std::string& storageName) { if (opened) throw Opened(name, "add cache " + storageName); - Cache* cache = new Cache(this, storageName, false); - std::pair pair = storages.insert(std::make_pair(storageName, (StorageCommon *)cache)); + auto cache = new Cache(this, storageName, false); + std::pair pair = storages.emplace(storageName, static_cast(cache)); if (!pair.second) throw StorageDuplicate(name, storageName); diff --git a/src/serializer/serializer.hpp b/src/serializer/serializer.hpp index b3353f5..03bfaed 100644 --- a/src/serializer/serializer.hpp +++ b/src/serializer/serializer.hpp @@ -114,7 +114,7 @@ T LMDBAL::Serializer::deserialize(const MDB_val& value) { template void LMDBAL::Serializer::deserialize(const MDB_val& value, T& result) { clear(); - bytes.setRawData((char*)value.mv_data, value.mv_size); + bytes.setRawData(static_cast(value.mv_data), value.mv_size); stream >> result; } @@ -154,7 +154,7 @@ MDB_val LMDBAL::Serializer::getData() { MDB_val val; val.mv_size = buffer.pos(); - val.mv_data = (char*)bytes.data(); + val.mv_data = bytes.data(); return val; } diff --git a/src/serializer/serializer_qbytearray.hpp b/src/serializer/serializer_qbytearray.hpp index daf3027..2d3f494 100644 --- a/src/serializer/serializer_qbytearray.hpp +++ b/src/serializer/serializer_qbytearray.hpp @@ -34,7 +34,17 @@ public: return value; }; void deserialize(const MDB_val& data, QByteArray& result) { - result.setRawData((char*)data.mv_data, data.mv_size); +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + if (data.mv_size > static_cast(std::numeric_limits::max())) + throw std::runtime_error("Data size exceeds QByteArray capacity"); + + result.setRawData(static_cast(data.mv_data), static_cast(data.mv_size)); +#else + if (data.mv_size > static_cast(std::numeric_limits::max())) + throw std::runtime_error("Data size exceeds QByteArray capacity"); + + result.setRawData(static_cast(data.mv_data), static_cast(data.mv_size)); +#endif } MDB_val setData(const QByteArray& data) { value = data; @@ -43,7 +53,7 @@ public: MDB_val getData() { MDB_val result; result.mv_data = value.data(); - result.mv_size = value.size(); + result.mv_size = static_cast(value.size()); return result; }; void clear() { diff --git a/src/serializer/serializer_qstring.hpp b/src/serializer/serializer_qstring.hpp index fb9310e..a00aea5 100644 --- a/src/serializer/serializer_qstring.hpp +++ b/src/serializer/serializer_qstring.hpp @@ -31,11 +31,33 @@ public: ~Serializer() {}; QString deserialize(const MDB_val& data) { - value = QByteArray((char*)data.mv_data, data.mv_size); +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + if (data.mv_size > static_cast(std::numeric_limits::max())) + throw std::runtime_error("Data size exceeds QByteArray capacity"); + + value = QByteArray(static_cast(data.mv_data), static_cast(data.mv_size)); +#else + if (data.mv_size > static_cast(std::numeric_limits::max())) + throw std::runtime_error("Data size exceeds QByteArray capacity"); + + value = QByteArray(static_cast(data.mv_data), static_cast(data.mv_size)); +#endif + return QString::fromUtf8(value); }; void deserialize(const MDB_val& data, QString& result) { - value = QByteArray((char*)data.mv_data, data.mv_size); +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + if (data.mv_size > static_cast(std::numeric_limits::max())) + throw std::runtime_error("Data size exceeds QByteArray capacity"); + + value = QByteArray(static_cast(data.mv_data), static_cast(data.mv_size)); +#else + if (data.mv_size > static_cast(std::numeric_limits::max())) + throw std::runtime_error("Data size exceeds QByteArray capacity"); + + value = QByteArray(static_cast(data.mv_data), static_cast(data.mv_size)); +#endif + result = QString::fromUtf8(value); } MDB_val setData(const QString& data) { @@ -45,7 +67,7 @@ public: MDB_val getData() { MDB_val result; result.mv_data = value.data(); - result.mv_size = value.size(); + result.mv_size = static_cast(value.size()); return result; }; void clear() {}; //not possible; @@ -54,4 +76,4 @@ private: QByteArray value; }; -} +} \ No newline at end of file diff --git a/src/serializer/serializer_stdstring.hpp b/src/serializer/serializer_stdstring.hpp index 1856e8c..659cb89 100644 --- a/src/serializer/serializer_stdstring.hpp +++ b/src/serializer/serializer_stdstring.hpp @@ -34,7 +34,7 @@ public: return value; }; void deserialize(const MDB_val& data, std::string& result) { - result.assign((char*)data.mv_data, data.mv_size); + result.assign(static_cast(data.mv_data), data.mv_size); } MDB_val setData(const std::string& data) { value = data; @@ -42,7 +42,7 @@ public: }; MDB_val getData() { MDB_val result; - result.mv_data = (char*)value.c_str(); + result.mv_data = const_cast(value.c_str()); result.mv_size = value.size(); return result; }; diff --git a/src/storagecommon.cpp b/src/storagecommon.cpp index 3d7e92c..7202d23 100644 --- a/src/storagecommon.cpp +++ b/src/storagecommon.cpp @@ -23,13 +23,13 @@ #define UNUSED(x) (void)(x) /** - * \class LMDBAL::iStorage + * \class LMDBAL::StorageCommon * * \brief Storage interface * - * This is a interface-like class, it's designed to be an inner database interface to - * be used as a polymorphic entity, and provide protected interaction with the database - * from the heirs code + * This is an interface-like class, it's designed to be an inner database interface to + * be used as a polymorphic entity and provide protected interaction with the database + * from the heir code */ /** @@ -49,7 +49,7 @@ LMDBAL::StorageCommon::StorageCommon(Base* parent, const std::string& name, bool /** * \brief Destroys a storage interface */ -LMDBAL::StorageCommon::~StorageCommon () {} +LMDBAL::StorageCommon::~StorageCommon () = default; /** * \brief A private virtual function to close each storage in the database @@ -103,7 +103,7 @@ void LMDBAL::StorageCommon::drop() { * * Just performs content drop * - * \param[in] transaction - transaction ID, must be writable transaction! + * \param[in] transaction - transaction ID; must be writable transaction! * \returns MDB_SUCCESS if everything went fine, MDB_ code otherwise */ int LMDBAL::StorageCommon::drop(TransactionID transaction) { @@ -115,7 +115,7 @@ int LMDBAL::StorageCommon::drop(TransactionID transaction) { * * Just performs content drop * - * \param[in] txn - transaction ID, must be writable transaction! + * \param[in] txn - transaction ID; must be writable transaction! * \returns MDB_SUCCESS if everything went fine, MDB_ code otherwise * * \exception LMDBAL::TransactionTerminated thrown if the transaction was not active @@ -126,7 +126,7 @@ int LMDBAL::StorageCommon::drop(const WriteTransaction& txn) { } /** - * \brief Helper function, thows exception if the database is not opened + * \brief Helper function; throws an exception if the database is not opened * * \param[in] methodName - name of the method this function is called from, just for display in std::exception::what() message * @@ -140,7 +140,7 @@ void LMDBAL::StorageCommon::ensureOpened(const std::string& methodName) const { /** * \brief Storage size * - * \returns amount of records in the storage + * \returns number of records in the storage * * \exception LMDBAL::Closed thrown if the database was closed * \exception LMDBAL::Unknown thrown if something unexpected happened @@ -162,7 +162,7 @@ LMDBAL::SizeType LMDBAL::StorageCommon::count() const { } /** - * \brief Retrieves public transaction object for a cursor handle + * \brief Retrieves a public transaction object for a cursor handle * * Cursor must be still opened by a public transaction * @@ -222,25 +222,27 @@ void LMDBAL::StorageCommon::closeCursorTransaction (MDB_cursor* cursor, bool clo /** * \brief Storage size (private transaction variant) * - * \param[in] txn - transaction ID, can be read-only transaction - * \returns amount of records in the storage + * \param[in] txn - transaction ID; can be read-only transaction + * \returns number of records in the storage * * \exception LMDBAL::Unknown thrown if something unexpected happened */ LMDBAL::SizeType LMDBAL::StorageCommon::count(TransactionID txn) const { MDB_stat stat; - int rc = mdb_stat(txn, dbi, &stat); - if (rc != MDB_SUCCESS) + if (const int rc = mdb_stat(txn, dbi, &stat); rc != MDB_SUCCESS) throw Unknown(db->name, mdb_strerror(rc), name); - return stat.ms_entries; + if (stat.ms_entries > std::numeric_limits::max()) + throw Unknown(db->name, "Storage size exceeds it's limits", name); + + return static_cast(stat.ms_entries); } /** * \brief Storage size (public transaction variant) * - * \param[in] txn - transaction, can be read-only transaction - * \returns amount of records in the storage + * \param[in] txn - transaction; can be read-only transaction + * \returns number of records in the storage * * \exception LMDBAL::Closed thrown if the database was closed * \exception LMDBAL::Unknown thrown if something unexpected happened diff --git a/src/storagecommon.h b/src/storagecommon.h index 77a56d2..d54c8d2 100644 --- a/src/storagecommon.h +++ b/src/storagecommon.h @@ -19,7 +19,7 @@ #pragma once #include -#include +#include #include