Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
75aafd2750 | |||
4fd3799c19 | |||
def2b8bc4d | |||
fc55ec6737 | |||
3282524c8b | |||
c60bb10923 | |||
9baade7b8c | |||
deded0c4e1 | |||
a09030cd4e | |||
d2a68ef5ee | |||
8ad684144f | |||
a6ea9bedc5 | |||
dcf2d289dc | |||
f638228d24 | |||
6dddd06f93 | |||
d62eddc47e | |||
79240aa535 | |||
6b475f615e | |||
77ba8f9e7b |
79
.gitea/workflows/aur.yml
Normal file
79
.gitea/workflows/aur.yml
Normal file
@ -0,0 +1,79 @@
|
||||
name: Release to AUR
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
package-name:
|
||||
required: true
|
||||
type: string
|
||||
version:
|
||||
required: true
|
||||
type: string
|
||||
description:
|
||||
required: true
|
||||
type: string
|
||||
depends:
|
||||
required: true
|
||||
type: string
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
package-name:
|
||||
description: "The name under which the package is going to be packaged to AUR"
|
||||
type: string
|
||||
default: "lmdbal"
|
||||
version:
|
||||
description: "The version of the published package"
|
||||
type: string
|
||||
default: "1.0.0"
|
||||
description:
|
||||
description: "The description of the package"
|
||||
type: string
|
||||
default: "LMDB Abstraction Layer"
|
||||
depends:
|
||||
description: "Additional dependencies"
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
jobs:
|
||||
aur:
|
||||
name: Release ${{ inputs.package-name }} to AUR
|
||||
runs-on: archlinux
|
||||
steps:
|
||||
- name: Download the release tarball
|
||||
run: curl -sL ${{ gitea.server_url }}/${{ gitea.repository }}/archive/${{ gitea.event.release.tag_name }}.tar.gz --output tarball.tar.gz
|
||||
|
||||
- name: Calculate SHA256 for the tarball
|
||||
run: echo "tbSum=$(sha256sum tarball.tar.gz | cut -d ' ' -f 1)" >> $GITHUB_ENV
|
||||
|
||||
- name: Unarchive tarball
|
||||
run: tar -xvzf tarball.tar.gz
|
||||
|
||||
- name: Clone the AUR repository
|
||||
run: |
|
||||
echo "${{ secrets.DEPLOY_TO_AUR_PRIVATE_KEY }}" > key
|
||||
chmod 600 key
|
||||
GIT_SSH_COMMAND="ssh -i key -o 'IdentitiesOnly yes' -o 'StrictHostKeyChecking no'" git clone ssh://aur@aur.archlinux.org/${{ inputs.package-name }}.git aur
|
||||
chmod 777 -R aur
|
||||
cd aur
|
||||
git config user.name ${{ secrets.DEPLOY_TO_AUR_USER_NAME }}
|
||||
git config user.email ${{ secrets.DEPLOY_TO_AUR_EMAIL }}
|
||||
|
||||
|
||||
- name: Copy PKGBUILD to the directory
|
||||
run: cp lmdbal/packaging/Archlinux/PKGBUILD aur/
|
||||
|
||||
- name: Patch PKGBUILD file, and generate .SRCINFO
|
||||
working-directory: aur
|
||||
run: |
|
||||
sed -i "/sha256sums=/c\sha256sums=('${{ env.tbSum }}')" PKGBUILD
|
||||
sed -i "/pkgname=lmdbal/c\pkgname=(${{ inputs.package-name }})" PKGBUILD
|
||||
sed -i "/pkgver=1.0.0/c\pkgver=(${{ inputs.version }})" PKGBUILD
|
||||
sed -i "/pkgdesc=\"LMDB Abstraction Layer\"/c\pkgdesc=(\"${{ inputs.description }}\")" PKGBUILD
|
||||
sed -i "/depends=( 'lmdb' )/c\depends=( 'lmdb' ${{ inputs.depends }} ))" PKGBUILD
|
||||
sudo -u build makepkg --printsrcinfo > .SRCINFO
|
||||
|
||||
- name: Commit package to aur
|
||||
working-directory: aur
|
||||
run: |
|
||||
git add PKGBUILD .SRCINFO
|
||||
git commit -m "${{ gitea.event.release.body }}"
|
||||
GIT_SSH_COMMAND="ssh -i ../key -o 'IdentitiesOnly yes' -o 'StrictHostKeyChecking no'" git push
|
@ -17,7 +17,7 @@ jobs:
|
||||
|
||||
- name: Configure
|
||||
working-directory: ./build
|
||||
run: cmake .. -D BUILD_TESTS=True -D BUILD_DOC=True -D BUILD_DOXYGEN_AWESOME=True -D QT_VERSION_MAJOR=5
|
||||
run: cmake .. -D BUILD_TESTS=True -D BUILD_DOC_HTML=True -D BUILD_DOC_XML=True -D BUILD_DOC_MAN=True -D BUILD_DOXYGEN_AWESOME=True -D QT_VERSION_MAJOR=5
|
||||
|
||||
- name: Build
|
||||
working-directory: ./build
|
||||
@ -35,5 +35,5 @@ jobs:
|
||||
username: ${{ secrets.DEPLOY_USER_NAME }}
|
||||
key: ${{ secrets.DEPLOY_PRIVATE_KEY }}
|
||||
source: "build/doc/html/*,build/doc/xml/*,build/doc/man/*"
|
||||
target: ${{ secrets.LMDBAL_DOCS_DEPLOY_PATH }}
|
||||
target: "/srv/lmdbal/doc"
|
||||
strip_components: 2
|
||||
|
@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
# LMDBAL 0.5.3 (November 14, 2023)
|
||||
### Improvements
|
||||
- Now you don't need to link agains lmdb, just linking against LMDBAL is enough
|
||||
|
||||
### Bug fixes
|
||||
- transaction error in LMDBAL::Cache::readAll
|
||||
|
||||
## LMDBAL 0.5.2 (November 01, 2023)
|
||||
### Improvements
|
||||
- RAII cursors
|
||||
|
@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
project(LMDBAL
|
||||
VERSION 0.5.2
|
||||
VERSION 0.5.4
|
||||
DESCRIPTION "LMDB (Lightning Memory-Mapped Database Manager) Abstraction Layer"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
@ -12,7 +12,9 @@ cmake_policy(SET CMP0079 NEW)
|
||||
|
||||
option(BUILD_STATIC "Builds library as static library" OFF)
|
||||
option(BUILD_TESTS "Builds tests" OFF)
|
||||
option(BUILD_DOC "Builds documentation" 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)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
@ -21,7 +23,7 @@ include(CMakePackageConfigHelpers)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
if (NOT DEFINED QT_VERSION_MAJOR)
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Core)
|
||||
@ -54,14 +56,21 @@ target_compile_options(${PROJECT_NAME} PRIVATE ${COMPILE_OPTIONS})
|
||||
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY VERSION ${version})
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY SOVERSION 1)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY
|
||||
INTERFACE_${PROJECT_NAME}_MAJOR_VERSION 1)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY EXPORT_NAME ${PROJECT_NAME})
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY INTERFACE_${PROJECT_NAME}_MAJOR_VERSION 1)
|
||||
set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_STRING ${PROJECT_NAME}_MAJOR_VERSION
|
||||
)
|
||||
|
||||
if (UNIX)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/${PROJECT_LOW}")
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY SKIP_BUILD_RPATH FALSE)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
if (BUILD_DOC)
|
||||
if (BUILD_DOC_MAN OR BUILD_DOC_HTML OR BUILD_DOC_XML)
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
add_subdirectory(doc)
|
||||
@ -74,13 +83,20 @@ if (BUILD_TESTS)
|
||||
add_subdirectory(test)
|
||||
endif ()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_LOW}>")
|
||||
target_include_directories(
|
||||
${PROJECT_NAME}
|
||||
PUBLIC
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_LOW}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/serializer>
|
||||
)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${Qt${QT_VERSION_MAJOR}_INCLUDE_DIRS})
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${Qt${QT_VERSION_MAJOR}Core_INCLUDE_DIRS})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||
Qt${QT_VERSION_MAJOR}::Core
|
||||
lmdb
|
||||
target_link_libraries(
|
||||
${PROJECT_NAME}
|
||||
Qt${QT_VERSION_MAJOR}::Core
|
||||
lmdb
|
||||
)
|
||||
|
||||
configure_package_config_file(
|
||||
@ -97,8 +113,7 @@ write_basic_package_version_file(
|
||||
|
||||
install(TARGETS ${PROJECT_NAME}
|
||||
EXPORT ${PROJECT_LOW}Targets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/${PROJECT_LOW}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_LOW}
|
||||
)
|
||||
|
||||
|
45
LICENSE.md
45
LICENSE.md
@ -1,4 +1,4 @@
|
||||
### GNU GENERAL PUBLIC LICENSE
|
||||
# GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 3, 29 June 2007
|
||||
|
||||
@ -8,7 +8,7 @@ Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
### Preamble
|
||||
## Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
@ -73,9 +73,9 @@ assures that patents cannot be used to render the program non-free.
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
### TERMS AND CONDITIONS
|
||||
## TERMS AND CONDITIONS
|
||||
|
||||
#### 0. Definitions.
|
||||
### 0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
@ -115,7 +115,7 @@ work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
#### 1. Source Code.
|
||||
### 1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work for
|
||||
making modifications to it. "Object code" means any non-source form of
|
||||
@ -156,7 +156,7 @@ regenerate automatically from other parts of the Corresponding Source.
|
||||
The Corresponding Source for a work in source code form is that same
|
||||
work.
|
||||
|
||||
#### 2. Basic Permissions.
|
||||
### 2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
@ -181,7 +181,7 @@ Conveying under any other circumstances is permitted solely under the
|
||||
conditions stated below. Sublicensing is not allowed; section 10 makes
|
||||
it unnecessary.
|
||||
|
||||
#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
@ -197,7 +197,7 @@ operation or modification of the work as a means of enforcing, against
|
||||
the work's users, your or third parties' legal rights to forbid
|
||||
circumvention of technological measures.
|
||||
|
||||
#### 4. Conveying Verbatim Copies.
|
||||
### 4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
@ -210,7 +210,7 @@ recipients a copy of this License along with the Program.
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
#### 5. Conveying Modified Source Versions.
|
||||
### 5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
@ -245,7 +245,7 @@ beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
#### 6. Conveying Non-Source Forms.
|
||||
### 6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms of
|
||||
sections 4 and 5, provided that you also convey the machine-readable
|
||||
@ -341,7 +341,7 @@ documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
#### 7. Additional Terms.
|
||||
### 7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
@ -400,7 +400,7 @@ Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions; the
|
||||
above requirements apply either way.
|
||||
|
||||
#### 8. Termination.
|
||||
### 8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
@ -428,7 +428,7 @@ this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
#### 9. Acceptance Not Required for Having Copies.
|
||||
### 9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or run
|
||||
a copy of the Program. Ancillary propagation of a covered work
|
||||
@ -439,7 +439,7 @@ modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
#### 10. Automatic Licensing of Downstream Recipients.
|
||||
### 10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
@ -464,7 +464,7 @@ rights granted under this License, and you may not initiate litigation
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
#### 11. Patents.
|
||||
### 11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
@ -533,7 +533,7 @@ Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
#### 12. No Surrender of Others' Freedom.
|
||||
### 12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
@ -546,7 +546,7 @@ from those to whom you convey the Program, the only way you could
|
||||
satisfy both those terms and this License would be to refrain entirely
|
||||
from conveying the Program.
|
||||
|
||||
#### 13. Use with the GNU Affero General Public License.
|
||||
### 13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
@ -557,7 +557,7 @@ but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
#### 14. Revised Versions of this License.
|
||||
### 14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU General Public License from time to time. Such new versions
|
||||
@ -583,7 +583,7 @@ permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
#### 15. Disclaimer of Warranty.
|
||||
### 15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
@ -595,7 +595,7 @@ PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
|
||||
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
||||
CORRECTION.
|
||||
|
||||
#### 16. Limitation of Liability.
|
||||
### 16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
|
||||
@ -607,7 +607,7 @@ LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
|
||||
TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
||||
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
#### 17. Interpretation of Sections 15 and 16.
|
||||
### 17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
@ -618,7 +618,7 @@ copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
### How to Apply These Terms to Your New Programs
|
||||
## How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@ -673,3 +673,4 @@ library, you may consider it more useful to permit linking proprietary
|
||||
applications with the library. If this is what you want to do, use the
|
||||
GNU Lesser General Public License instead of this License. But first,
|
||||
please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
|
||||
|
@ -97,4 +97,4 @@ if you're in the same directory with it
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the GPLv3 License - see the [LICENSE.md](LICENSE.md) file for details
|
||||
This project is available under the GPL-3.0 License or any later version. The file [cmake/FindLMDB.cmake](cmake/FindLMDB.cmake) is available under the GPL-3.0 License only, - see the [LICENSE.md](LICENSE.md) file for details
|
||||
|
@ -1,6 +1,12 @@
|
||||
set(DOXYGEN_GENERATE_HTML YES)
|
||||
set(DOXYGEN_GENERATE_MAN YES)
|
||||
set(DOXYGEN_GENERATE_XML YES)
|
||||
if (BUILD_DOC_HTML)
|
||||
set(DOXYGEN_GENERATE_HTML YES)
|
||||
endif()
|
||||
if (BUILD_DOC_MAN)
|
||||
set(DOXYGEN_GENERATE_MAN YES)
|
||||
endif()
|
||||
if (BUILD_DOC_XML)
|
||||
set(DOXYGEN_GENERATE_XML YES)
|
||||
endif()
|
||||
|
||||
if (BUILD_DOXYGEN_AWESOME)
|
||||
include(ExternalProject)
|
||||
@ -36,12 +42,24 @@ doxygen_add_docs(
|
||||
ALL
|
||||
COMMENT "Generate man and html pages"
|
||||
)
|
||||
install(DIRECTORY
|
||||
if (BUILD_DOC_MAN)
|
||||
install(DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}/man
|
||||
TYPE DOC
|
||||
)
|
||||
endif()
|
||||
if (BUILD_DOC_HTML)
|
||||
install(DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}/html
|
||||
TYPE DOC
|
||||
)
|
||||
endif()
|
||||
if (BUILD_DOC_XML)
|
||||
install(DIRECTORY
|
||||
${CMAKE_CURRENT_BINARY_DIR}/xml
|
||||
TYPE DOC
|
||||
)
|
||||
endif()
|
||||
|
||||
if (BUILD_DOXYGEN_AWESOME)
|
||||
add_dependencies(documentation doxygen-awesome-css)
|
||||
|
@ -4,6 +4,15 @@
|
||||
* It repesents a collection of key-value storages that are going to be stored in a sigle data base directory.
|
||||
* To create a LMDBAL::Base you need to pick up a name of a directory that is going to be created on your machine.
|
||||
*
|
||||
* @code{.cpp}
|
||||
*
|
||||
* #include "base.h"
|
||||
*
|
||||
* //...
|
||||
*
|
||||
* LMDBAL::Base base("myDataBase");
|
||||
* @endcode
|
||||
*
|
||||
* LMDBAL::Base creates or opens existing directory with the given name in the location acquired with
|
||||
* <a class="el" href="https://doc.qt.io/qt-6/qstandardpaths.html">QStandardPaths</a>::<a class="el" href="https://doc.qt.io/qt-6/qstandardpaths.html#writableLocation">writableLocation</a>(<a class="el" href="https://doc.qt.io/qt-6/qstandardpaths.html">QStandardPaths</a>::<a class="el" href="https://doc.qt.io/qt-6/qstandardpaths.html#StandardLocation-enum">CacheLocation</a>)
|
||||
* so, the file system destination of your data depends on the
|
||||
@ -15,17 +24,55 @@
|
||||
* <a class="el" href="https://en.cppreference.com/w/cpp/container/map">std::map</a>
|
||||
* to speed up the access.
|
||||
*
|
||||
* @code{.cpp}
|
||||
*
|
||||
* #include "storage.h"
|
||||
* #include "cache.h"
|
||||
*
|
||||
* //...
|
||||
*
|
||||
* LMDBAL::Storage<uint32_t, uint32_t> storage = base.addStorage<uint32_t, uint32_t>("storage");
|
||||
* LMDBAL::Cache<int8_t, std::string> cache = base.addCache<int8_t, std::string>("cache");
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* You can obtain handlers by calling LMDBAL::Base::addStorage() or LMDBAL::Base::addCache().
|
||||
* Note that the handlers still belong to the LMDBAL::Base and it's his responsibility to destroy them.
|
||||
* You are not obliged to save those handlers,
|
||||
* you can obtain them at any time later using methods LMDBAL::Base::getStorage() or LMDBAL::Base::getCache()
|
||||
* calling them with the same template types and names.
|
||||
*
|
||||
* @code{.cpp}
|
||||
*
|
||||
* //...
|
||||
*
|
||||
* base.open();
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* After you have added all the storages you wanted it's time to open the data base with LMDBAL::Base::open().
|
||||
* At this point you are not allowed to add any more storages, otherwise LMDBAL::Opened exception will be thrown.
|
||||
* It's currently the limitation of this little library and I might solve it in the future.
|
||||
* Database will throw no exception if you will try to close the closed LMDBAL::Base or open again already opened one.
|
||||
* Also it will automatically close itself if you'll try to destoroy onpened LMDBAL::Base.
|
||||
*
|
||||
* @code{.cpp}
|
||||
*
|
||||
* //...
|
||||
*
|
||||
* storage->addRecord(54, 75);
|
||||
* cache->addRecord(9, "my value");
|
||||
*
|
||||
* uint32_t value1 = storage->getRecord(54); //75
|
||||
* std::string value2 = cache->getRecord(9); //"myValue"
|
||||
*
|
||||
* uint32_t count1 = storage->count(); //1
|
||||
* uint32_t count2 = cache->count(); //1
|
||||
*
|
||||
* storage->removeRecord(54);
|
||||
* cache->removeRecord(9);
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* To discover how to store read and modify data take a look at LMDBAL::Storage and LMDBAL::Cache classes.
|
||||
*/
|
||||
|
@ -1,12 +1,12 @@
|
||||
# Maintainer: Yury Gubich <blue@macaw.me>
|
||||
pkgname=lmdbal
|
||||
pkgver=0.5.2
|
||||
pkgver=1.0.0
|
||||
pkgrel=1
|
||||
pkgdesc="LMDB Abstraction Layer, qt5 version"
|
||||
pkgdesc="LMDB Abstraction Layer"
|
||||
arch=('i686' 'x86_64')
|
||||
url="https://git.macaw.me/blue/lmdbal"
|
||||
license=('GPL3')
|
||||
depends=( 'lmdb' 'qt5-base')
|
||||
depends=( 'lmdb' )
|
||||
makedepends=('cmake>=3.16' 'gcc')
|
||||
optdepends=()
|
||||
|
||||
|
@ -19,7 +19,6 @@ set(HEADERS
|
||||
)
|
||||
|
||||
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
|
||||
|
||||
add_subdirectory(serializer)
|
||||
|
||||
|
@ -549,7 +549,7 @@ void LMDBAL::Cache<K, V>::readAll(std::map<K, V>& out, TransactionID txn) const
|
||||
} else {
|
||||
if (mode != Mode::full) { //there is a room for optimization
|
||||
mode = Mode::full; //I can read and deserialize only those values
|
||||
Storage<K, V>::readAll(out); //that are missing in the cache
|
||||
Storage<K, V>::readAll(out, txn); //that are missing in the cache
|
||||
*cache = out;
|
||||
abscent->clear();
|
||||
sizeDifference = 0;
|
||||
|
@ -210,7 +210,7 @@ void LMDBAL::Cursor<K, V>::open () {
|
||||
switch (state) {
|
||||
case closed: {
|
||||
TransactionID txn = storage->beginReadOnlyTransaction();
|
||||
int result = mdb_cursor_open(txn, storage->dbi, &cursor);
|
||||
int result = storage->_mdbCursorOpen(txn, &cursor);
|
||||
if (result != MDB_SUCCESS)
|
||||
storage->throwUnknown(result, txn);
|
||||
|
||||
@ -247,7 +247,7 @@ void LMDBAL::Cursor<K, V>::open (const Transaction& transaction) {
|
||||
TransactionID txn = storage->extractTransactionId(transaction, openCursorMethodName);
|
||||
switch (state) {
|
||||
case closed: {
|
||||
int result = mdb_cursor_open(txn, storage->dbi, &cursor);
|
||||
int result = storage->_mdbCursorOpen(txn, &cursor);
|
||||
if (result != MDB_SUCCESS)
|
||||
storage->throwUnknown(result);
|
||||
|
||||
@ -283,14 +283,14 @@ void LMDBAL::Cursor<K, V>::renew () {
|
||||
storage->ensureOpened(renewCursorMethodName);
|
||||
switch (state) {
|
||||
case openedPrivate: {
|
||||
TransactionID txn = mdb_cursor_txn(cursor);
|
||||
TransactionID txn = storage->_mdbCursorTxn(cursor);
|
||||
storage->abortTransaction(txn);
|
||||
storage->transactionAborted(txn);
|
||||
[[fallthrough]];
|
||||
}
|
||||
case openedPublic: {
|
||||
TransactionID txn = storage->beginReadOnlyTransaction();
|
||||
int result = mdb_cursor_renew(txn, cursor);
|
||||
int result = storage->_mdbCursorRenew(txn, cursor);
|
||||
if (result != MDB_SUCCESS)
|
||||
storage->throwUnknown(result, txn);
|
||||
|
||||
@ -331,13 +331,13 @@ void LMDBAL::Cursor<K, V>::renew (const Transaction& transaction) {
|
||||
TransactionID txn = storage->extractTransactionId(transaction, renewCursorMethodName);
|
||||
switch (state) {
|
||||
case openedPrivate: {
|
||||
TransactionID txn = mdb_cursor_txn(cursor);
|
||||
TransactionID txn = storage->_mdbCursorTxn(cursor);
|
||||
storage->abortTransaction(txn);
|
||||
storage->transactionAborted(txn);
|
||||
[[fallthrough]];
|
||||
}
|
||||
case openedPublic: {
|
||||
int result = mdb_cursor_renew(txn, cursor);
|
||||
int result = storage->_mdbCursorRenew(txn, cursor);
|
||||
if (result != MDB_SUCCESS)
|
||||
storage->throwUnknown(result);
|
||||
|
||||
@ -362,13 +362,13 @@ template<class K, class V>
|
||||
void LMDBAL::Cursor<K, V>::close () {
|
||||
switch (state) {
|
||||
case openedPublic: {
|
||||
mdb_cursor_close(cursor);
|
||||
storage->_mdbCursorClose(cursor);
|
||||
|
||||
state = closed;
|
||||
} break;
|
||||
case openedPrivate: {
|
||||
TransactionID txn = mdb_cursor_txn(cursor);
|
||||
mdb_cursor_close(cursor);
|
||||
TransactionID txn = storage->_mdbCursorTxn(cursor);
|
||||
storage->_mdbCursorClose(cursor);
|
||||
storage->abortTransaction(txn);
|
||||
storage->transactionAborted(txn);
|
||||
|
||||
@ -608,7 +608,7 @@ bool LMDBAL::Cursor<K, V>::set (const K& key) {
|
||||
storage->throwCursorNotReady(setMethodName);
|
||||
|
||||
MDB_val mdbKey = storage->keySerializer.setData(key);
|
||||
int result = mdb_cursor_get(cursor, &mdbKey, nullptr, MDB_SET);
|
||||
int result = storage->_mdbCursorSet(cursor, mdbKey);
|
||||
if (result == MDB_SUCCESS)
|
||||
return true;
|
||||
else if (result == MDB_NOTFOUND)
|
||||
@ -645,7 +645,7 @@ void LMDBAL::Cursor<K, V>::operateCursorRead(
|
||||
storage->throwCursorNotReady(methodName);
|
||||
|
||||
MDB_val mdbKey, mdbValue;
|
||||
int result = mdb_cursor_get(cursor, &mdbKey, &mdbValue, operation);
|
||||
int result = storage->_mdbCursorGet(cursor, mdbKey, mdbValue, operation);
|
||||
if (result != MDB_SUCCESS)
|
||||
storage->throwNotFoundOrUnknown(result, operationName);
|
||||
|
||||
@ -655,7 +655,7 @@ void LMDBAL::Cursor<K, V>::operateCursorRead(
|
||||
if (state == openedPrivate)
|
||||
storage->discoveredRecord(key, value);
|
||||
else
|
||||
storage->discoveredRecord(key, value, mdb_cursor_txn(cursor));
|
||||
storage->discoveredRecord(key, value, storage->_mdbCursorTxn(cursor));
|
||||
}
|
||||
|
||||
#endif //LMDBAL_CURSOR_HPP
|
||||
|
@ -16,6 +16,4 @@ set(HEADERS
|
||||
serializer_qbytearray.hpp
|
||||
)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>")
|
||||
|
||||
install(FILES ${HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_LOW})
|
||||
|
@ -446,3 +446,64 @@ void LMDBAL::iStorage::transactionAborted(LMDBAL::TransactionID txn) const {
|
||||
* after the transaction is commited. Used just for optimisations.
|
||||
*/
|
||||
void LMDBAL::iStorage::handleDrop() {}
|
||||
|
||||
int LMDBAL::iStorage::_mdbOpen(MDB_txn *txn, unsigned int flags) {
|
||||
return mdb_dbi_open(txn, name.c_str(), flags, &dbi);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbPut(MDB_txn* txn, MDB_val& key, MDB_val& data, unsigned int flags) {
|
||||
return mdb_put(txn, dbi, &key, &data, flags);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbGet(MDB_txn* txn, MDB_val& key, MDB_val& data) const {
|
||||
return mdb_get(txn, dbi, &key, &data);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbDel(MDB_txn* txn, MDB_val& key) {
|
||||
return mdb_del(txn, dbi, &key, NULL);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbDel(MDB_txn* txn, MDB_val& key, MDB_val& data) {
|
||||
return mdb_del(txn, dbi, &key, &data);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbStat(MDB_txn* txn, MDB_stat& stat) const {
|
||||
return mdb_stat(txn, dbi, &stat);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbFlags(MDB_txn* txn, uint32_t& flags) const {
|
||||
return mdb_dbi_flags(txn, dbi, &flags);
|
||||
}
|
||||
|
||||
|
||||
int LMDBAL::iStorage::_mdbCursorOpen(MDB_txn* txn, MDB_cursor** cursor) const {
|
||||
return mdb_cursor_open(txn, dbi, cursor);
|
||||
}
|
||||
|
||||
void LMDBAL::iStorage::_mdbCursorClose(MDB_cursor *cursor) const {
|
||||
mdb_cursor_close(cursor);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbCursorGet(MDB_cursor* cursor, MDB_val& key, MDB_val& data, MDB_cursor_op operation) const {
|
||||
return mdb_cursor_get(cursor, &key, &data, operation);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbCursorSet(MDB_cursor* cursor, MDB_val& key) const {
|
||||
return mdb_cursor_get(cursor, &key, NULL, MDB_SET);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbCursorDel(MDB_cursor* cursor, unsigned int flags) {
|
||||
return mdb_cursor_del(cursor, flags);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbCursorPut(MDB_cursor* cursor, MDB_val& key, MDB_val& data, unsigned int flags) {
|
||||
return mdb_cursor_put(cursor, &key, &data, flags);
|
||||
}
|
||||
|
||||
int LMDBAL::iStorage::_mdbCursorRenew(MDB_txn* txn, MDB_cursor* cursor) const {
|
||||
return mdb_cursor_renew(txn, cursor);
|
||||
}
|
||||
|
||||
MDB_txn* LMDBAL::iStorage::_mdbCursorTxn(MDB_cursor* cursor) const {
|
||||
return mdb_cursor_txn(cursor);
|
||||
}
|
||||
|
@ -77,6 +77,26 @@ protected:
|
||||
virtual int drop(TransactionID transaction);
|
||||
virtual SizeType count(TransactionID txn) const;
|
||||
|
||||
int _mdbOpen(MDB_txn* txn, unsigned int flags = 0);
|
||||
|
||||
int _mdbPut(MDB_txn* txn, MDB_val& key, MDB_val& data, unsigned int flags = 0);
|
||||
int _mdbGet(MDB_txn* txn, MDB_val& key, MDB_val& data) const;
|
||||
int _mdbDel(MDB_txn* txn, MDB_val& key);
|
||||
int _mdbDel(MDB_txn* txn, MDB_val& key, MDB_val& data);
|
||||
|
||||
int _mdbStat(MDB_txn* txn, MDB_stat& stat) const;
|
||||
int _mdbFlags(MDB_txn* txn, uint32_t& flags) const;
|
||||
|
||||
int _mdbCursorOpen(MDB_txn* txn, MDB_cursor** cursor) const;
|
||||
void _mdbCursorClose(MDB_cursor* cursor) const;
|
||||
int _mdbCursorGet(MDB_cursor* cursor, MDB_val& key, MDB_val& data, MDB_cursor_op operation) const;
|
||||
int _mdbCursorSet(MDB_cursor* cursor, MDB_val& key) const;
|
||||
int _mdbCursorDel(MDB_cursor* cursor, unsigned int flags = 0);
|
||||
int _mdbCursorPut(MDB_cursor* cursor, MDB_val& key, MDB_val& data, unsigned int flags = 0);
|
||||
|
||||
int _mdbCursorRenew(MDB_txn* txn, MDB_cursor* cursor) const;
|
||||
MDB_txn* _mdbCursorTxn(MDB_cursor* cursor) const;
|
||||
|
||||
public:
|
||||
virtual void drop();
|
||||
virtual int drop(const WriteTransaction& txn);
|
||||
|
@ -115,7 +115,7 @@ void LMDBAL::Storage<K, V>::addRecord(const K& key, const V& value, TransactionI
|
||||
else
|
||||
flags |= MDB_NOOVERWRITE;
|
||||
|
||||
int rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, flags);
|
||||
int rc = _mdbPut(txn, lmdbKey, lmdbData, flags);
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwDuplicateOrUnknown(rc, toString(key));
|
||||
}
|
||||
@ -209,7 +209,7 @@ bool LMDBAL::Storage<K, V>::forceRecord(const K& key, const V& value, Transactio
|
||||
MDB_val lmdbKey = keySerializer.setData(key);
|
||||
MDB_val lmdbData;
|
||||
|
||||
int rc = mdb_get(txn, dbi, &lmdbKey, &lmdbData);
|
||||
int rc = _mdbGet(txn, lmdbKey, lmdbData);
|
||||
switch (rc) {
|
||||
case MDB_SUCCESS:
|
||||
added = false;
|
||||
@ -223,7 +223,7 @@ bool LMDBAL::Storage<K, V>::forceRecord(const K& key, const V& value, Transactio
|
||||
}
|
||||
|
||||
lmdbData = valueSerializer.setData(value);
|
||||
rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, 0);
|
||||
rc = _mdbPut(txn, lmdbKey, lmdbData);
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwUnknown(rc);
|
||||
}
|
||||
@ -314,13 +314,13 @@ void LMDBAL::Storage<K, V>::changeRecord(const K& key, const V& value) {
|
||||
template<class K, class V>
|
||||
void LMDBAL::Storage<K, V>::changeRecord(const K& key, const V& value, TransactionID txn) {
|
||||
MDB_cursor* cursor;
|
||||
int rc = mdb_cursor_open(txn, dbi, &cursor);
|
||||
int rc = _mdbCursorOpen(txn, &cursor);
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwUnknown(rc);
|
||||
|
||||
MDB_val lmdbKey = keySerializer.setData(key);
|
||||
MDB_val lmdbData;
|
||||
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_SET);
|
||||
rc = _mdbCursorGet(cursor, lmdbKey, lmdbData, MDB_SET);
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwNotFoundOrUnknown(rc, toString(key));
|
||||
|
||||
@ -330,21 +330,21 @@ void LMDBAL::Storage<K, V>::changeRecord(const K& key, const V& value, Transacti
|
||||
if (sameSize) { //can compare only if they are the same size
|
||||
firstDifferentByte = memcmp(lmdbData.mv_data, lmdbNewData.mv_data, lmdbData.mv_size);
|
||||
if (firstDifferentByte == 0) { //old and new is the same, nothing to do
|
||||
mdb_cursor_close(cursor);
|
||||
_mdbCursorClose(cursor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int flags = MDB_CURRENT;
|
||||
if (duplicates && (!sameSize || firstDifferentByte < 0)) { //if new value is greater than the old one
|
||||
rc = mdb_cursor_del(cursor, 0); //we need to initiate duplicates sort, for it to be in the correct place
|
||||
rc = _mdbCursorDel(cursor); //we need to initiate duplicates sort, for it to be in the correct place
|
||||
flags = MDB_NODUPDATA;
|
||||
}
|
||||
|
||||
if (rc == MDB_SUCCESS)
|
||||
rc = mdb_cursor_put(cursor, &lmdbKey, &lmdbNewData, flags);
|
||||
rc = _mdbCursorPut(cursor, lmdbKey, lmdbNewData, flags);
|
||||
|
||||
mdb_cursor_close(cursor);
|
||||
_mdbCursorClose(cursor);
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwDuplicateOrUnknown(rc, toString(key));
|
||||
}
|
||||
@ -517,7 +517,7 @@ void LMDBAL::Storage<K, V>::getRecord(const K& key, V& value, TransactionID txn)
|
||||
MDB_val lmdbKey = keySerializer.setData(key);
|
||||
MDB_val lmdbData;
|
||||
|
||||
int rc = mdb_get(txn, dbi, &lmdbKey, &lmdbData);
|
||||
int rc = _mdbGet(txn, lmdbKey, lmdbData);
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwNotFoundOrUnknown(rc, toString(key));
|
||||
|
||||
@ -594,7 +594,7 @@ bool LMDBAL::Storage<K, V>::checkRecord(const K& key, TransactionID txn) const {
|
||||
MDB_val lmdbKey = keySerializer.setData(key);
|
||||
MDB_val lmdbData;
|
||||
|
||||
int rc = mdb_get(txn, dbi, &lmdbKey, &lmdbData);
|
||||
int rc = _mdbGet(txn, lmdbKey, lmdbData);
|
||||
if (rc == MDB_SUCCESS)
|
||||
return true;
|
||||
|
||||
@ -729,11 +729,11 @@ void LMDBAL::Storage<K, V>::readAll(std::map<K, V>& result, TransactionID txn) c
|
||||
MDB_cursor* cursor;
|
||||
MDB_val lmdbKey, lmdbData;
|
||||
|
||||
int rc = mdb_cursor_open(txn, dbi, &cursor);
|
||||
int rc = _mdbCursorOpen(txn, &cursor);
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwUnknown(rc);
|
||||
|
||||
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_FIRST);
|
||||
rc = _mdbCursorGet(cursor, lmdbKey, lmdbData, MDB_FIRST);
|
||||
while (rc == MDB_SUCCESS) {
|
||||
K key;
|
||||
keySerializer.deserialize(lmdbKey, key);
|
||||
@ -741,9 +741,9 @@ void LMDBAL::Storage<K, V>::readAll(std::map<K, V>& result, TransactionID txn) c
|
||||
if (probe.second) //I do this to avoid overwrites in case duplicates are enabled
|
||||
valueSerializer.deserialize(lmdbData, probe.first->second);
|
||||
|
||||
rc = mdb_cursor_get(cursor, &lmdbKey, &lmdbData, MDB_NEXT);
|
||||
rc = _mdbCursorGet(cursor, lmdbKey, lmdbData, MDB_NEXT);
|
||||
}
|
||||
mdb_cursor_close(cursor);
|
||||
_mdbCursorClose(cursor);
|
||||
if (rc != MDB_NOTFOUND)
|
||||
throwUnknown(rc);
|
||||
}
|
||||
@ -817,7 +817,7 @@ void LMDBAL::Storage<K, V>::replaceAll(const std::map<K, V>& data, TransactionID
|
||||
lmdbKey = keySerializer.setData(pair.first);
|
||||
lmdbData = valueSerializer.setData(pair.second);
|
||||
|
||||
rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, MDB_NOOVERWRITE); //TODO may be appending with cursor makes sence here?
|
||||
rc = _mdbPut(txn, lmdbKey, lmdbData, MDB_NOOVERWRITE); //TODO may be appending with cursor makes sence here?
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwUnknown(rc);
|
||||
}
|
||||
@ -892,7 +892,7 @@ uint32_t LMDBAL::Storage<K, V>::addRecords(const std::map<K, V>& data, Transacti
|
||||
lmdbKey = keySerializer.setData(pair.first);
|
||||
lmdbData = valueSerializer.setData(pair.second);
|
||||
|
||||
rc = mdb_put(txn, dbi, &lmdbKey, &lmdbData, overwrite ? 0 : MDB_NOOVERWRITE);
|
||||
rc = _mdbPut(txn, lmdbKey, lmdbData, overwrite ? 0 : MDB_NOOVERWRITE);
|
||||
if (rc == MDB_KEYEXIST)
|
||||
throwDuplicate(toString(pair.first));
|
||||
|
||||
@ -901,7 +901,7 @@ uint32_t LMDBAL::Storage<K, V>::addRecords(const std::map<K, V>& data, Transacti
|
||||
}
|
||||
|
||||
MDB_stat stat;
|
||||
rc = mdb_stat(txn, dbi, &stat);
|
||||
rc = _mdbStat(txn, stat);
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwUnknown(rc);
|
||||
|
||||
@ -971,7 +971,7 @@ void LMDBAL::Storage<K, V>::removeRecord(const K& key) {
|
||||
template<class K, class V>
|
||||
void LMDBAL::Storage<K, V>::removeRecord(const K& key, TransactionID txn) {
|
||||
MDB_val lmdbKey = keySerializer.setData(key);
|
||||
int rc = mdb_del(txn, dbi, &lmdbKey, NULL);
|
||||
int rc = _mdbDel(txn, lmdbKey);
|
||||
if (rc != MDB_SUCCESS)
|
||||
throwNotFoundOrUnknown(rc, toString(key));
|
||||
}
|
||||
@ -1071,7 +1071,7 @@ uint32_t LMDBAL::Storage<K, V>::flags() const {
|
||||
uint32_t result;
|
||||
TransactionID txn = beginReadOnlyTransaction();
|
||||
|
||||
int res = mdb_dbi_flags(txn, dbi, &result);
|
||||
int res = _mdbFlags(txn, result);
|
||||
abortTransaction(txn);
|
||||
if (res != MDB_SUCCESS)
|
||||
throwUnknown(res);
|
||||
@ -1140,7 +1140,7 @@ inline int LMDBAL::iStorage::makeStorage(MDB_txn* transaction, bool duplicates)
|
||||
flags |= MDB_INTEGERDUP;
|
||||
}
|
||||
|
||||
return mdb_dbi_open(transaction, name.c_str(), flags, &dbi);
|
||||
return _mdbOpen(transaction, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,6 @@ add_executable(runUnitTests
|
||||
|
||||
target_compile_options(runUnitTests PRIVATE -fPIC -Wall -Wextra -O0)
|
||||
|
||||
target_include_directories(runUnitTests PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
||||
target_include_directories(runUnitTests PRIVATE ${Qt${QT_VERSION_MAJOR}_INCLUDE_DIRS})
|
||||
target_include_directories(runUnitTests PRIVATE ${Qt${QT_VERSION_MAJOR}Core_INCLUDE_DIRS})
|
||||
|
||||
@ -23,7 +22,6 @@ target_link_libraries(
|
||||
GTest::gtest_main
|
||||
${PROJECT_NAME}
|
||||
Qt${QT_VERSION_MAJOR}::Core
|
||||
lmdb
|
||||
)
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(runUnitTests)
|
||||
|
@ -113,10 +113,9 @@ TEST_F(BaseTest, AddingKeysToCache) {
|
||||
EXPECT_EQ(db->ready(), true);
|
||||
c1->addRecord(2, "blah balah");
|
||||
c1->addRecord(-4, "testing goes brrr");
|
||||
c1->addRecord(140, "whatever");
|
||||
c1->addRecord(40, "whatever");
|
||||
c1->addRecord(-37, "aaaaa tss tsss tsss tsss aaaaaaa");
|
||||
EXPECT_EQ(c1->getRecord(140), "whatever");
|
||||
EXPECT_EQ(c1->getRecord(-116), "whatever");
|
||||
EXPECT_EQ(c1->getRecord(40), "whatever");
|
||||
}
|
||||
|
||||
TEST_F(BaseTest, AddingKeysToVariableCache) {
|
||||
@ -189,8 +188,8 @@ TEST_F(BaseTest, Persistence) {
|
||||
EXPECT_EQ(t2->count(), t2Size);
|
||||
|
||||
EXPECT_EQ(c1->count(), c1Size);
|
||||
EXPECT_EQ(c1->checkRecord(-116), true);
|
||||
EXPECT_EQ(c1->getRecord(-116), "whatever");
|
||||
EXPECT_EQ(c1->checkRecord(40), true);
|
||||
EXPECT_EQ(c1->getRecord(40), "whatever");
|
||||
EXPECT_EQ(c1->checkRecord(-4), true);
|
||||
EXPECT_EQ(c1->getRecord(-4), "testing goes brrr");
|
||||
EXPECT_EQ(c1->getRecord(-4), "testing goes brrr");
|
||||
|
@ -130,7 +130,10 @@ TEST_F(DuplicatesTest, Adding) {
|
||||
tu3->addRecord(7.20001, 4.00000001); //not sure how exactly, but it works
|
||||
|
||||
EXPECT_EQ(tu3->count(), 7);
|
||||
EXPECT_EQ(tu3->getRecord(7.2), -113);
|
||||
|
||||
std::set<float> res72({-113, -53.5478, 697, 4, 4.00000001});
|
||||
EXPECT_EQ(res72.count(tu3->getRecord(7.2)), 1);
|
||||
|
||||
float tu3dd = tu3->getRecord(5119);
|
||||
EXPECT_TRUE(tu3ds == tu3dd);
|
||||
EXPECT_EQ(tu3ds, tu3dd);
|
||||
@ -144,8 +147,11 @@ TEST_F(DuplicatesTest, Adding) {
|
||||
EXPECT_THROW(tu4->addRecord(327, 79.624923), LMDBAL::Exist);
|
||||
|
||||
EXPECT_EQ(tu4->count(), 4);
|
||||
EXPECT_EQ(tu4->getRecord(172), 0.00000001);
|
||||
EXPECT_EQ(tu4->getRecord(327), 463.28348); //since they are not int's they are compared sort of lexicographically
|
||||
|
||||
std::set<double> res327({463.28348, 79.624923});
|
||||
std::set<double> res172({0.00001, 0.00000001});
|
||||
EXPECT_EQ(res172.count(tu4->getRecord(172)), 1);
|
||||
EXPECT_EQ(res327.count(tu4->getRecord(327)), 1);
|
||||
|
||||
tu5->addRecord(-84.7, 45656753);
|
||||
EXPECT_THROW(tu5->addRecord(-84.7, 45656753), LMDBAL::Exist);
|
||||
@ -174,13 +180,19 @@ TEST_F(DuplicatesTest, Forcing) {
|
||||
tu1->addRecord(-56, 71);
|
||||
tu1->addRecord(-56, 274);
|
||||
tu1->addRecord(-56, 732);
|
||||
|
||||
std::set<uint16_t> res56({71, 274, 732});
|
||||
EXPECT_EQ(tu1->count(), tu1Size += 3);
|
||||
EXPECT_TRUE(tu1->forceRecord(-56, 322));
|
||||
res56.insert(322);
|
||||
EXPECT_EQ(tu1->count(), tu1Size += 1);
|
||||
EXPECT_EQ(tu1->getRecord(-56), 274); //like yeah, it's really counterintuitive, since it's compared byte by byte
|
||||
EXPECT_EQ(res56.count(tu1->getRecord(-56)), 1);
|
||||
|
||||
res56.insert(14);
|
||||
EXPECT_TRUE(tu1->forceRecord(-56, 14));
|
||||
EXPECT_EQ(tu1->count(), tu1Size += 1);
|
||||
EXPECT_EQ(tu1->getRecord(-56), 14);
|
||||
EXPECT_EQ(res56.count(tu1->getRecord(-56)), 1);
|
||||
|
||||
EXPECT_FALSE(tu1->forceRecord(-56, 274));
|
||||
EXPECT_EQ(tu1->count(), tu1Size);
|
||||
|
||||
@ -201,26 +213,38 @@ TEST_F(DuplicatesTest, Forcing) {
|
||||
tu3->addRecord(17.3, 93.21);
|
||||
tu3->addRecord(17.3, 6.6);
|
||||
tu3->addRecord(17.3, 105.1);
|
||||
std::set<float> res17({93.21, 6.6, 105.1});
|
||||
|
||||
EXPECT_EQ(tu3->count(), tu3Size += 3);
|
||||
EXPECT_TRUE(tu3->forceRecord(17.3, 74.9));
|
||||
res17.insert(74.9);
|
||||
EXPECT_EQ(tu3->count(), tu3Size += 1);
|
||||
EXPECT_EQ(tu3->getRecord(17.3), 105.1f); //here too, really one should not use this function with duplicates,
|
||||
EXPECT_TRUE(tu3->forceRecord(17.3, 5.1)); //unless he wishes for kinda randomish result
|
||||
EXPECT_EQ(res17.count(tu3->getRecord(17.3)), 1);
|
||||
|
||||
EXPECT_TRUE(tu3->forceRecord(17.3, 5.1));
|
||||
res17.insert(5.1);
|
||||
EXPECT_EQ(tu3->count(), tu3Size += 1);
|
||||
EXPECT_EQ(tu3->getRecord(17.3), 5.1f);
|
||||
EXPECT_EQ(res17.count(tu3->getRecord(17.3)), 1);
|
||||
|
||||
EXPECT_FALSE(tu3->forceRecord(17.3, 93.21));
|
||||
EXPECT_EQ(tu3->count(), tu3Size);
|
||||
|
||||
LMDBAL::SizeType tu4Size = tu4->count();
|
||||
tu4->addRecord(84, -359.109);
|
||||
tu4->addRecord(84, 2879.654);
|
||||
std::set<double> res84({-359.109, 2879.654});
|
||||
|
||||
EXPECT_EQ(tu4->count(), tu4Size += 2);
|
||||
EXPECT_TRUE(tu4->forceRecord(84, 72.9));
|
||||
res84.insert(72.9);
|
||||
EXPECT_EQ(tu4->count(), tu4Size += 1);
|
||||
EXPECT_EQ(tu4->getRecord(84), 2879.654);
|
||||
EXPECT_EQ(res84.count(tu4->getRecord(84)), 1);
|
||||
|
||||
EXPECT_TRUE(tu4->forceRecord(84, 2679.5));
|
||||
res84.insert(2679.5);
|
||||
EXPECT_EQ(tu4->count(), tu4Size += 1);
|
||||
EXPECT_EQ(tu4->getRecord(84), 2679.5);
|
||||
EXPECT_EQ(res84.count(tu4->getRecord(84)), 1);
|
||||
|
||||
EXPECT_FALSE(tu4->forceRecord(84, -359.109));
|
||||
EXPECT_EQ(tu4->count(), tu4Size);
|
||||
|
||||
@ -286,6 +310,7 @@ TEST_F(DuplicatesTest, Changing) {
|
||||
EXPECT_THROW(tu2->changeRecord("jeremy spins", -7), LMDBAL::Exist);
|
||||
|
||||
LMDBAL::SizeType tu3Size = tu3->count();
|
||||
std::set<float> res26;
|
||||
EXPECT_THROW(tu3->changeRecord(26.7, 68.22), LMDBAL::NotFound);
|
||||
EXPECT_EQ(tu3->count(), tu3Size);
|
||||
tu3->addRecord(26.7, 68.22);
|
||||
@ -294,11 +319,13 @@ TEST_F(DuplicatesTest, Changing) {
|
||||
tu3->changeRecord(26.7, 68.22); //should just do nothing usefull, but work normally
|
||||
EXPECT_EQ(tu3->getRecord(26.7), 68.22f);
|
||||
tu3->changeRecord(26.7, 23.18);
|
||||
res26.insert(23.18);
|
||||
EXPECT_EQ(tu3->count(), tu3Size);
|
||||
EXPECT_EQ(tu3->getRecord(26.7), 23.18f);
|
||||
tu3->addRecord(26.7, 22.16);
|
||||
res26.insert(22.16);
|
||||
EXPECT_EQ(tu3->count(), tu3Size += 1);
|
||||
EXPECT_EQ(tu3->getRecord(26.7), 23.18f);
|
||||
EXPECT_EQ(res26.count(tu3->getRecord(26.7)), 1);
|
||||
tu3->changeRecord(26.7, 21.7);
|
||||
EXPECT_EQ(tu3->count(), tu3Size);
|
||||
EXPECT_EQ(tu3->getRecord(26.7), 21.7f);
|
||||
@ -316,17 +343,21 @@ TEST_F(DuplicatesTest, Changing) {
|
||||
tu4->changeRecord(852, 6795.349); //should just do nothing usefull, but work normally
|
||||
EXPECT_EQ(tu4->getRecord(852), 6795.349);
|
||||
tu4->changeRecord(852, 13.54);
|
||||
std::set<double> res852({13.54});
|
||||
EXPECT_EQ(tu4->count(), tu4Size);
|
||||
EXPECT_EQ(tu4->getRecord(852), 13.54);
|
||||
tu4->addRecord(852, 213.85);
|
||||
res852.insert(213.85);
|
||||
EXPECT_EQ(tu4->count(), tu4Size += 1);
|
||||
EXPECT_EQ(tu4->getRecord(852), 13.54);
|
||||
EXPECT_EQ(res852.count(tu4->getRecord(852)), 1);
|
||||
tu4->changeRecord(852, 236.21);
|
||||
res852.insert(236.21);
|
||||
EXPECT_EQ(tu4->count(), tu4Size);
|
||||
EXPECT_EQ(tu4->getRecord(852), 236.21);
|
||||
tu4->changeRecord(852, 46324.1135);
|
||||
res852.insert(46324.1135);
|
||||
EXPECT_EQ(tu4->count(), tu4Size);
|
||||
EXPECT_EQ(tu4->getRecord(852), 213.85);
|
||||
EXPECT_EQ(res852.count(tu4->getRecord(852)), 1);
|
||||
EXPECT_THROW(tu4->changeRecord(852, 46324.1135), LMDBAL::Exist);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user