Loading backends/CMakeLists.txt +34 −0 Original line number Diff line number Diff line Loading @@ -72,3 +72,37 @@ if(SQLITE3_FOUND) endif() endif() find_package(MariaDB) if(MariaDB_FOUND) add_library(mariadb SHARED mariadb/mariadb.cpp) target_include_directories(mariadb PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../include" "${MariaDB_INCLUDE_DIRS}" ) add_definitions(-DMARIADB) target_link_libraries(mariadb PUBLIC dbpp PRIVATE MariaDB::MariaDB) set_target_properties(mariadb PROPERTIES PREFIX "") install(TARGETS mariadb RUNTIME_DEPENDENCY_SET mariadbdep LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/dbpp NAMELINK_SKIP RUNTIME DESTINATION bin ) if(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows") install( RUNTIME_DEPENDENCY_SET mariadbdep DIRECTORIES "$<TARGET_FILE_DIR:MariaDB::MariaDB>" DESTINATION bin PRE_EXCLUDE_REGEXES "((api|ext)-ms-.*|.*azureattest.*|vcruntime.*|ucrtbase.*|msvcrt.*|wpaxholder.*)\\.dll" POST_EXCLUDE_REGEXES [[.*(\\|/)system32(\\|/).*\.dll]] ) endif() endif() backends/mariadb/mariadb.cpp 0 → 100644 +165 −0 Original line number Diff line number Diff line /******************************************************************************* * Copyright (c) 2023, Jan Koester jan.koester@gmx.net * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #include <stdexcept> #include <sstream> #include <map> #include <cstring> #include <mysql/mysql.h> #include "mariadb.h" static std::map<std::string,std::string> parseConnStr(const char *constr){ std::map<std::string,std::string> params; std::istringstream stream(constr); std::string token; while(std::getline(stream,token,' ')){ auto pos = token.find('='); if(pos != std::string::npos){ params[token.substr(0,pos)] = token.substr(pos+1); } } return params; } dbpp::MariaDB::MariaDB(const char *constr) { _dbconn = mysql_init(nullptr); if(_dbconn == nullptr){ throw std::runtime_error("mysql_init failed (out of memory)"); } auto params = parseConnStr(constr); const char *host = nullptr; const char *user = nullptr; const char *password = nullptr; const char *dbname = nullptr; unsigned int port = 0; const char *unix_socket = nullptr; if(params.count("host")) host = params["host"].c_str(); if(params.count("user")) user = params["user"].c_str(); if(params.count("password")) password = params["password"].c_str(); if(params.count("dbname")) dbname = params["dbname"].c_str(); if(params.count("port")) port = static_cast<unsigned int>(std::stoul(params["port"])); if(params.count("unix_socket")) unix_socket = params["unix_socket"].c_str(); if(!mysql_real_connect(_dbconn, host, user, password, dbname, port, unix_socket, 0)){ std::string errmsg = "Connection to database failed: "; errmsg += mysql_error(_dbconn); mysql_close(_dbconn); _dbconn = nullptr; throw std::runtime_error(errmsg); } } dbpp::MariaDB::~MariaDB(){ if(_dbconn) mysql_close(_dbconn); } int dbpp::MariaDB::exec(const SQL &sql,DBResult &res){ const std::lock_guard<std::mutex> lock(_mutex); if(mysql_real_query(_dbconn, sql.c_str(), sql.size())){ throw std::runtime_error(mysql_error(_dbconn)); } res.clear(); MYSQL_RES *mres = mysql_store_result(_dbconn); if(!mres){ if(mysql_field_count(_dbconn) == 0){ return 0; } throw std::runtime_error(mysql_error(_dbconn)); } int rcount = 0; int nfields = mysql_num_fields(mres); DBResult::Data *lastdat = nullptr; MYSQL_ROW row; unsigned long *lengths; while((row = mysql_fetch_row(mres))){ lengths = mysql_fetch_lengths(mres); for(int i = 0; i < nfields; ++i){ const char *val = row[i] ? row[i] : ""; int len = row[i] ? static_cast<int>(lengths[i]) : 0; if(!res.firstRow){ res.firstRow = new DBResult::Data(rcount, i, val, len); lastdat = res.firstRow; }else{ lastdat->nextData = new DBResult::Data(rcount, i, val, len); lastdat = lastdat->nextData; } } ++rcount; } mysql_free_result(mres); return rcount; } const char *dbpp::MariaDB::getDriverName(){ return "mariadb"; } const dbpp::SQL &dbpp::MariaDB::autoincrement(SQL &sql){ return (sql << "AUTO_INCREMENT"); } const dbpp::SQL &dbpp::MariaDB::getUUIDType(SQL &sql){ return (sql << "CHAR(36)"); } bool dbpp::MariaDB::isConnected(){ const std::lock_guard<std::mutex> lock(_mutex); return mysql_ping(_dbconn) == 0; } void dbpp::MariaDB::reset(){ const std::lock_guard<std::mutex> lock(_mutex); mysql_ping(_dbconn); } EXPORT dbpp::MariaDB* create(const char *coninfo) { return new dbpp::MariaDB(coninfo); } EXPORT void destroy(dbpp::MariaDB* p) { delete p; } backends/mariadb/mariadb.h 0 → 100644 +57 −0 Original line number Diff line number Diff line /******************************************************************************* * Copyright (c) 2023, Jan Koester jan.koester@gmx.net * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #include <mutex> #include "database.h" #pragma once typedef struct st_mysql MYSQL; namespace dbpp { class MariaDB : public DatabaseApi{ public: MariaDB(const char *constr); ~MariaDB(); int exec(const SQL &sql,DBResult &res) override; const char *getDriverName() override; const SQL &autoincrement(SQL &sql) override; const SQL &getUUIDType(SQL &sql) override; bool isConnected() override; void reset() override; private: MYSQL *_dbconn; std::mutex _mutex; }; } cmake/FindMariaDB.cmake 0 → 100644 +48 −0 Original line number Diff line number Diff line # FindMariaDB.cmake # Find the MariaDB client library # # This module defines: # MariaDB_FOUND - True if MariaDB was found # MariaDB_INCLUDE_DIRS - Include directories # MariaDB_LIBRARIES - Libraries to link # MariaDB::MariaDB - Imported target find_package(PkgConfig QUIET) if(PKG_CONFIG_FOUND) pkg_check_modules(PC_MARIADB QUIET libmariadb) endif() find_path(MariaDB_INCLUDE_DIR NAMES mysql/mysql.h mysql.h HINTS ${PC_MARIADB_INCLUDEDIR} ${PC_MARIADB_INCLUDE_DIRS} PATH_SUFFIXES mariadb mysql ) find_library(MariaDB_LIBRARY NAMES mariadb mariadbclient mysqlclient HINTS ${PC_MARIADB_LIBDIR} ${PC_MARIADB_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(MariaDB REQUIRED_VARS MariaDB_LIBRARY MariaDB_INCLUDE_DIR ) if(MariaDB_FOUND) set(MariaDB_INCLUDE_DIRS ${MariaDB_INCLUDE_DIR}) set(MariaDB_LIBRARIES ${MariaDB_LIBRARY}) if(NOT TARGET MariaDB::MariaDB) add_library(MariaDB::MariaDB UNKNOWN IMPORTED) set_target_properties(MariaDB::MariaDB PROPERTIES IMPORTED_LOCATION "${MariaDB_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${MariaDB_INCLUDE_DIR}" ) endif() endif() mark_as_advanced(MariaDB_INCLUDE_DIR MariaDB_LIBRARY) debian/control +11 −1 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ Section: libs Priority: optional Maintainer: Jan Koester <jan.koester@tuxist.de> Build-Depends: debhelper-compat (= 13), cmake (>= 3.18), libpq-dev, libsqlite3-dev, pkg-config libpq-dev, libsqlite3-dev, libmariadb-dev, pkg-config Standards-Version: 4.6.2 Rules-Requires-Root: no Loading Loading @@ -39,3 +39,13 @@ Description: SQLite backend for libdbpp architecture for backend drivers. . This package contains the SQLite backend plugin. Package: libdbpp-mariadb Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends} Description: MariaDB backend for libdbpp libdbpp is a C++ database abstraction library with a plugin architecture for backend drivers. . This package contains the MariaDB backend plugin. Loading
backends/CMakeLists.txt +34 −0 Original line number Diff line number Diff line Loading @@ -72,3 +72,37 @@ if(SQLITE3_FOUND) endif() endif() find_package(MariaDB) if(MariaDB_FOUND) add_library(mariadb SHARED mariadb/mariadb.cpp) target_include_directories(mariadb PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../include" "${MariaDB_INCLUDE_DIRS}" ) add_definitions(-DMARIADB) target_link_libraries(mariadb PUBLIC dbpp PRIVATE MariaDB::MariaDB) set_target_properties(mariadb PROPERTIES PREFIX "") install(TARGETS mariadb RUNTIME_DEPENDENCY_SET mariadbdep LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/dbpp NAMELINK_SKIP RUNTIME DESTINATION bin ) if(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows") install( RUNTIME_DEPENDENCY_SET mariadbdep DIRECTORIES "$<TARGET_FILE_DIR:MariaDB::MariaDB>" DESTINATION bin PRE_EXCLUDE_REGEXES "((api|ext)-ms-.*|.*azureattest.*|vcruntime.*|ucrtbase.*|msvcrt.*|wpaxholder.*)\\.dll" POST_EXCLUDE_REGEXES [[.*(\\|/)system32(\\|/).*\.dll]] ) endif() endif()
backends/mariadb/mariadb.cpp 0 → 100644 +165 −0 Original line number Diff line number Diff line /******************************************************************************* * Copyright (c) 2023, Jan Koester jan.koester@gmx.net * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #include <stdexcept> #include <sstream> #include <map> #include <cstring> #include <mysql/mysql.h> #include "mariadb.h" static std::map<std::string,std::string> parseConnStr(const char *constr){ std::map<std::string,std::string> params; std::istringstream stream(constr); std::string token; while(std::getline(stream,token,' ')){ auto pos = token.find('='); if(pos != std::string::npos){ params[token.substr(0,pos)] = token.substr(pos+1); } } return params; } dbpp::MariaDB::MariaDB(const char *constr) { _dbconn = mysql_init(nullptr); if(_dbconn == nullptr){ throw std::runtime_error("mysql_init failed (out of memory)"); } auto params = parseConnStr(constr); const char *host = nullptr; const char *user = nullptr; const char *password = nullptr; const char *dbname = nullptr; unsigned int port = 0; const char *unix_socket = nullptr; if(params.count("host")) host = params["host"].c_str(); if(params.count("user")) user = params["user"].c_str(); if(params.count("password")) password = params["password"].c_str(); if(params.count("dbname")) dbname = params["dbname"].c_str(); if(params.count("port")) port = static_cast<unsigned int>(std::stoul(params["port"])); if(params.count("unix_socket")) unix_socket = params["unix_socket"].c_str(); if(!mysql_real_connect(_dbconn, host, user, password, dbname, port, unix_socket, 0)){ std::string errmsg = "Connection to database failed: "; errmsg += mysql_error(_dbconn); mysql_close(_dbconn); _dbconn = nullptr; throw std::runtime_error(errmsg); } } dbpp::MariaDB::~MariaDB(){ if(_dbconn) mysql_close(_dbconn); } int dbpp::MariaDB::exec(const SQL &sql,DBResult &res){ const std::lock_guard<std::mutex> lock(_mutex); if(mysql_real_query(_dbconn, sql.c_str(), sql.size())){ throw std::runtime_error(mysql_error(_dbconn)); } res.clear(); MYSQL_RES *mres = mysql_store_result(_dbconn); if(!mres){ if(mysql_field_count(_dbconn) == 0){ return 0; } throw std::runtime_error(mysql_error(_dbconn)); } int rcount = 0; int nfields = mysql_num_fields(mres); DBResult::Data *lastdat = nullptr; MYSQL_ROW row; unsigned long *lengths; while((row = mysql_fetch_row(mres))){ lengths = mysql_fetch_lengths(mres); for(int i = 0; i < nfields; ++i){ const char *val = row[i] ? row[i] : ""; int len = row[i] ? static_cast<int>(lengths[i]) : 0; if(!res.firstRow){ res.firstRow = new DBResult::Data(rcount, i, val, len); lastdat = res.firstRow; }else{ lastdat->nextData = new DBResult::Data(rcount, i, val, len); lastdat = lastdat->nextData; } } ++rcount; } mysql_free_result(mres); return rcount; } const char *dbpp::MariaDB::getDriverName(){ return "mariadb"; } const dbpp::SQL &dbpp::MariaDB::autoincrement(SQL &sql){ return (sql << "AUTO_INCREMENT"); } const dbpp::SQL &dbpp::MariaDB::getUUIDType(SQL &sql){ return (sql << "CHAR(36)"); } bool dbpp::MariaDB::isConnected(){ const std::lock_guard<std::mutex> lock(_mutex); return mysql_ping(_dbconn) == 0; } void dbpp::MariaDB::reset(){ const std::lock_guard<std::mutex> lock(_mutex); mysql_ping(_dbconn); } EXPORT dbpp::MariaDB* create(const char *coninfo) { return new dbpp::MariaDB(coninfo); } EXPORT void destroy(dbpp::MariaDB* p) { delete p; }
backends/mariadb/mariadb.h 0 → 100644 +57 −0 Original line number Diff line number Diff line /******************************************************************************* * Copyright (c) 2023, Jan Koester jan.koester@gmx.net * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ #include <mutex> #include "database.h" #pragma once typedef struct st_mysql MYSQL; namespace dbpp { class MariaDB : public DatabaseApi{ public: MariaDB(const char *constr); ~MariaDB(); int exec(const SQL &sql,DBResult &res) override; const char *getDriverName() override; const SQL &autoincrement(SQL &sql) override; const SQL &getUUIDType(SQL &sql) override; bool isConnected() override; void reset() override; private: MYSQL *_dbconn; std::mutex _mutex; }; }
cmake/FindMariaDB.cmake 0 → 100644 +48 −0 Original line number Diff line number Diff line # FindMariaDB.cmake # Find the MariaDB client library # # This module defines: # MariaDB_FOUND - True if MariaDB was found # MariaDB_INCLUDE_DIRS - Include directories # MariaDB_LIBRARIES - Libraries to link # MariaDB::MariaDB - Imported target find_package(PkgConfig QUIET) if(PKG_CONFIG_FOUND) pkg_check_modules(PC_MARIADB QUIET libmariadb) endif() find_path(MariaDB_INCLUDE_DIR NAMES mysql/mysql.h mysql.h HINTS ${PC_MARIADB_INCLUDEDIR} ${PC_MARIADB_INCLUDE_DIRS} PATH_SUFFIXES mariadb mysql ) find_library(MariaDB_LIBRARY NAMES mariadb mariadbclient mysqlclient HINTS ${PC_MARIADB_LIBDIR} ${PC_MARIADB_LIBRARY_DIRS} ) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(MariaDB REQUIRED_VARS MariaDB_LIBRARY MariaDB_INCLUDE_DIR ) if(MariaDB_FOUND) set(MariaDB_INCLUDE_DIRS ${MariaDB_INCLUDE_DIR}) set(MariaDB_LIBRARIES ${MariaDB_LIBRARY}) if(NOT TARGET MariaDB::MariaDB) add_library(MariaDB::MariaDB UNKNOWN IMPORTED) set_target_properties(MariaDB::MariaDB PROPERTIES IMPORTED_LOCATION "${MariaDB_LIBRARY}" INTERFACE_INCLUDE_DIRECTORIES "${MariaDB_INCLUDE_DIR}" ) endif() endif() mark_as_advanced(MariaDB_INCLUDE_DIR MariaDB_LIBRARY)
debian/control +11 −1 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ Section: libs Priority: optional Maintainer: Jan Koester <jan.koester@tuxist.de> Build-Depends: debhelper-compat (= 13), cmake (>= 3.18), libpq-dev, libsqlite3-dev, pkg-config libpq-dev, libsqlite3-dev, libmariadb-dev, pkg-config Standards-Version: 4.6.2 Rules-Requires-Root: no Loading Loading @@ -39,3 +39,13 @@ Description: SQLite backend for libdbpp architecture for backend drivers. . This package contains the SQLite backend plugin. Package: libdbpp-mariadb Architecture: any Multi-Arch: same Depends: ${shlibs:Depends}, ${misc:Depends} Description: MariaDB backend for libdbpp libdbpp is a C++ database abstraction library with a plugin architecture for backend drivers. . This package contains the MariaDB backend plugin.