diff --git a/.drone.yml b/.drone.yml index f442cbc..6dc60ae 100644 --- a/.drone.yml +++ b/.drone.yml @@ -25,7 +25,7 @@ steps: - alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get' - apt-get update -q - apt-get install -qy g++-6 cmake pkg-config - - apt-get install -qy libpoco-dev libxdg-basedir-dev libvsqlitepp-dev libboost-system-dev libboost-filesystem-dev asciidoc catch + - apt-get install -qy libpoco-dev libxdg-basedir-dev asciidoc catch - locale-gen en_US.UTF-8 && update-locale LANG=en_US.UTF-8 - rm -rf build && mkdir -p build && cd build - cmake -DCMAKE_INSTALL_PREFIX=/usr -DWITH_TESTS=YES -DWITH_MOZILLA=YES .. @@ -55,7 +55,7 @@ steps: - apt-get update -q - apt-get install -qy -t xenial g++-5 - apt-get install -qy cmake pkg-config - - apt-get install -qy libpoco-dev libxdg-basedir-dev libvsqlitepp-dev libboost-system-dev libboost-filesystem-dev asciidoc catch + - apt-get install -qy libpoco-dev libxdg-basedir-dev asciidoc catch - rm -rf build && mkdir -p build && cd build - cmake -DCMAKE_INSTALL_PREFIX=/usr -DWITH_MOZILLA=YES .. - make VERBOSE=1 @@ -82,7 +82,7 @@ steps: - apt-get update -q - apt-get install -qy -t xenial g++-9 - apt-get install -qy cmake pkg-config - - apt-get install -qy libpoco-dev libxdg-basedir-dev libvsqlitepp-dev libboost-system-dev libboost-filesystem-dev asciidoc catch + - apt-get install -qy libpoco-dev libxdg-basedir-dev asciidoc catch - rm -rf build && mkdir -p build && cd build - cmake -DCMAKE_INSTALL_PREFIX=/usr -DWITH_MOZILLA=YES .. - make VERBOSE=1 @@ -102,7 +102,7 @@ steps: - alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get' - apt-get update -q - apt-get install -qy clang cmake pkg-config - - apt-get install -qy libpoco-dev libxdg-basedir-dev libvsqlitepp-dev libboost-system-dev libboost-filesystem-dev asciidoc catch + - apt-get install -qy libpoco-dev libxdg-basedir-dev asciidoc catch - rm -rf build && mkdir -p build && cd build - cmake -DCMAKE_INSTALL_PREFIX=/usr -DWITH_MOZILLA=YES .. - make VERBOSE=1 @@ -122,7 +122,7 @@ steps: - alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get' - apt-get update -q - apt-get install -qy clang cmake pkg-config - - apt-get install -qy libpoco-dev libxdg-basedir-dev libvsqlitepp-dev libboost-system-dev libboost-filesystem-dev asciidoc catch + - apt-get install -qy libpoco-dev libxdg-basedir-dev asciidoc catch - rm -rf build && mkdir -p build && cd build - cmake -DCMAKE_INSTALL_PREFIX=/usr -DWITH_MOZILLA=YES .. - make VERBOSE=1 @@ -173,7 +173,7 @@ steps: - alias apt-get='rm -f /var/cache/apt/archives/lock && apt-get' - apt-get update -q - apt-get install -qy g++-6 cmake pkg-config - - apt-get install -qy libpoco-dev libxdg-basedir-dev libvsqlitepp-dev libboost-system-dev libboost-filesystem-dev asciidoc catch + - apt-get install -qy libpoco-dev libxdg-basedir-dev asciidoc catch - apt-get install -qy build-essential file - rm -rf build && mkdir -p build && cd build - cmake -DCMAKE_INSTALL_PREFIX=/usr -DWITH_MOZILLA=YES -DMOZILLA_NMH_DIR="lib/mozilla/native-messaging-hosts" -DWITH_DEB=YES .. diff --git a/README.adoc b/README.adoc index 770de23..a4c858c 100644 --- a/README.adoc +++ b/README.adoc @@ -60,7 +60,6 @@ only. * https://pkgconfig.freedesktop.org/wiki/[pkgconfig] (tested: 0.29) * http://repo.or.cz/w/libxdg-basedir.git[libxdg-basedir] (tested: 1.2) * https://pocoproject.org/[POCO] (tested: 1.9 / 1.7) -* http://vsqlite.virtuosic-bytes.com/[vsqlite++] (tested: 0.3) * Optional: ** Manpage: http://asciidoc.org/[asciidoc] (tested: 8.6) ** Tests: https://github.com/catchorg/Catch2[catch] (tested: 2.5 / 1.2) @@ -72,8 +71,7 @@ only. [source,zsh] ---- apt-get update -apt-get install g++-6 cmake pkg-config libpoco-dev libxdg-basedir-dev \ - libvsqlitepp-dev libboost-system-dev libboost-filesystem-dev asciidoc +apt-get install g++-6 cmake pkg-config libpoco-dev libxdg-basedir-dev asciidoc dpkg export CXX="g++-6" ---- ==== diff --git a/cmake/packages.cmake b/cmake/packages.cmake index 2440e47..d845208 100644 --- a/cmake/packages.cmake +++ b/cmake/packages.cmake @@ -45,7 +45,7 @@ if (WITH_RPM) set(CPACK_RPM_PACKAGE_LICENSE "GPL-3") set(CPACK_RPM_PACKAGE_URL "https://schlomp.space/tastytea/${PROJECT_NAME}") set(CPACK_RPM_PACKAGE_REQUIRES - "poco-netssl >= 1.6, libxdg-basedir, vsqlite++ >= 0.3") + "poco-netssl >= 1.6, poco-sqlite >= 1.6, libxdg-basedir") set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-0.${CPACK_PACKAGE_ARCHITECTURE}") set(CPACK_SOURCE_PACKAGE_FILE_NAME diff --git a/cmake/remwhareadConfig.cmake.in b/cmake/remwhareadConfig.cmake.in index b634fc3..2083f00 100644 --- a/cmake/remwhareadConfig.cmake.in +++ b/cmake/remwhareadConfig.cmake.in @@ -1,15 +1,10 @@ include(CMakeFindDependencyMacro) include(GNUInstallDirs) -find_depencency(Poco COMPONENTS Foundation Net NetSSL CONFIG REQUIRED) +find_depencency(Poco + COMPONENTS Foundation Net NetSSL DataSQLite + CONFIG REQUIRED) find_dependency(PkgConfig REQUIRED) pkg_check_modules(libxdg-basedir REQUIRED IMPORTED_TARGET libxdg-basedir) -find_file(vsqlitepp NAMES "sqlite/connection.hpp" - PATHS "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") - -if("${vsqlitepp}" STREQUAL "vsqlitepp-NOTFOUND") - message(FATAL_ERROR "Could not find vsqlite++.") -endif() - include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") diff --git a/include/sqlite.hpp b/include/sqlite.hpp index 1826d81..bd88b32 100644 --- a/include/sqlite.hpp +++ b/include/sqlite.hpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include namespace remwharead { @@ -31,6 +31,7 @@ namespace remwharead using std::vector; using std::chrono::system_clock; using time_point = system_clock::time_point; + using Poco::Data::Session; /*! * @brief Store and retrieve files from/to SQLite. @@ -82,7 +83,7 @@ namespace remwharead private: fs::path _dbpath; - std::unique_ptr _con; + std::unique_ptr _session; bool _connected; }; diff --git a/pkg-config/remwharead.pc.in b/pkg-config/remwharead.pc.in index ccad29d..e1f32d4 100644 --- a/pkg-config/remwharead.pc.in +++ b/pkg-config/remwharead.pc.in @@ -8,6 +8,6 @@ Name: ${name} Description: @PROJECT_DESCRIPTION@ Version: @PROJECT_VERSION@ Cflags: -I${includedir} -Libs: -L${libdir} -l${name} -lvsqlitepp -lstdc++fs +Libs: -L${libdir} -l${name} -lPocoDataSQLite -lstdc++fs Requires.private: libxdg-basedir, icu-uc, icu-i18n Libs.private: -lPocoFoundation -lPocoNet -lPocoNetSSL diff --git a/src/cli/parse_options.cpp b/src/cli/parse_options.cpp index 8ebb785..bc65bd8 100644 --- a/src/cli/parse_options.cpp +++ b/src/cli/parse_options.cpp @@ -113,7 +113,10 @@ void App::handle_options(const std::string &name, const std::string &value) { buffer.erase(buffer.end() - 1); } - _tags.push_back(buffer); + if (!buffer.empty()) + { + _tags.push_back(buffer); + } pos_start = pos_end + 1; } } diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt index 2421889..46bd89a 100644 --- a/src/lib/CMakeLists.txt +++ b/src/lib/CMakeLists.txt @@ -3,7 +3,7 @@ include(GNUInstallDirs) find_package(PkgConfig REQUIRED) pkg_check_modules(libxdg-basedir REQUIRED IMPORTED_TARGET libxdg-basedir) # Some distributions do not contain Poco*Config.cmake recipes. -find_package(Poco COMPONENTS Foundation Net NetSSL CONFIG) +find_package(Poco COMPONENTS Foundation Net NetSSL DataSQLite CONFIG) file(GLOB_RECURSE sources_lib *.cpp) file(GLOB_RECURSE headers_lib ../../include/*.hpp) @@ -23,12 +23,13 @@ target_include_directories(${PROJECT_NAME} target_link_libraries(${PROJECT_NAME} PRIVATE PkgConfig::libxdg-basedir - PUBLIC vsqlitepp stdc++fs) + PUBLIC stdc++fs) # If no Poco*Config.cmake recipes are found, look for headers in standard dirs. if(PocoNetSSL_FOUND) target_link_libraries(${PROJECT_NAME} - PRIVATE Poco::Foundation Poco::Net Poco::NetSSL) + PRIVATE Poco::Foundation Poco::Net Poco::NetSSL + PUBLIC Poco::DataSQLite) else() find_file(Poco_h NAMES "Poco/Poco.h" PATHS "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") @@ -41,7 +42,8 @@ else() "but the files seem to be in the standard directories. " "Let's hope this works.") target_link_libraries(${PROJECT_NAME} - PRIVATE PocoFoundation PocoNet PocoNetSSL) + PRIVATE PocoFoundation PocoNet PocoNetSSL + PUBLIC PocoDataSQLite) endif() endif() diff --git a/src/lib/sqlite.cpp b/src/lib/sqlite.cpp index 2cfb5b4..2e95c3c 100644 --- a/src/lib/sqlite.cpp +++ b/src/lib/sqlite.cpp @@ -18,8 +18,8 @@ #include #include #include -#include -#include +#include +#include #include "time.hpp" #include "sqlite.hpp" @@ -27,6 +27,8 @@ namespace remwharead { using std::cerr; using std::endl; + using namespace Poco::Data::Keywords; + using Poco::Data::Statement; Database::Database() : _connected(false) @@ -44,11 +46,11 @@ namespace remwharead } _dbpath /= "database.sqlite"; - _con = std::make_unique(_dbpath); - sqlite::execute(*_con, "CREATE TABLE IF NOT EXISTS remwharead(" - "uri TEXT, archive_uri TEXT, datetime TEXT, " - "tags TEXT, title TEXT, description TEXT, " - "fulltext TEXT);", true); + Poco::Data::SQLite::Connector::registerConnector(); + _session = std::make_unique("SQLite", _dbpath); + *_session << "CREATE TABLE IF NOT EXISTS remwharead(" + "uri TEXT, archive_uri TEXT, datetime TEXT, " + "tags TEXT, title TEXT, description TEXT, fulltext TEXT);", now; _connected = true; } @@ -72,7 +74,7 @@ namespace remwharead { string oneline = fulltext; size_t pos = 0; - while ((pos = oneline.find('\n', pos)) != std::string::npos) + while ((pos = oneline.find('\n', pos)) != string::npos) { oneline.replace(pos, 1, "\\n"); } @@ -85,6 +87,8 @@ namespace remwharead { const string strdatetime = timepoint_to_string(data.datetime, true); string strtags; + Statement insert(*_session); + for (const string &tag : data.tags) { strtags += tag; @@ -94,11 +98,13 @@ namespace remwharead } } - sqlite::execute ins(*_con, "INSERT INTO remwharead " - "VALUES(?, ?, ?, ?, ?, ?, ?);"); - ins % data.uri % data.archive_uri % strdatetime % strtags - % data.title % data.description % data.fulltext; - ins(); + // useRef() uses the const reference. + insert << "INSERT INTO remwharead " + "VALUES(?, ?, ?, ?, ?, ?, ?);", + useRef(data.uri), useRef(data.archive_uri), + useRef(strdatetime), useRef(strtags), useRef(data.title), + useRef(data.description), useRef(data.fulltext); + insert.execute(); } catch (std::exception &e) { @@ -111,40 +117,46 @@ namespace remwharead { try { - const string query = "SELECT * FROM remwharead WHERE datetime " - "BETWEEN '" + timepoint_to_string(start, true) - + "' AND '" + timepoint_to_string(end, true) - + "' ORDER BY datetime DESC;"; + Database::entry entrybuf; + string datetime, strtags; + Statement select(*_session); + + // bind() copies the value. + select << "SELECT * FROM remwharead WHERE datetime " + "BETWEEN ? AND ? ORDER BY datetime DESC;", + bind(timepoint_to_string(start, true)), + bind(timepoint_to_string(end, true)), + into(entrybuf.uri), into(entrybuf.archive_uri), into(datetime), + into(strtags), into(entrybuf.title), into(entrybuf.description), + into(entrybuf.fulltext), range(0, 1); - sqlite::query q(*_con, query); - sqlite::result_type res = q.get_result(); vector entries; - while(res->next_row()) + while(!select.done()) { + select.execute(); + + entrybuf.datetime = string_to_timepoint(datetime); + vector tags; - const string strtags = res->get_string(3); size_t pos = 0; - while (pos != std::string::npos) + while (pos != string::npos) { const size_t newpos = strtags.find(',', pos); - tags.push_back(strtags.substr(pos, newpos - pos)); + const string tag = strtags.substr(pos, newpos - pos); + if (!tag.empty()) + { + tags.push_back(tag); + } pos = newpos; - if (pos != std::string::npos) + if (pos != string::npos) { ++pos; } } - entries.push_back - ({ - res->get_string(0), - res->get_string(1), - string_to_timepoint(res->get_string(2), true), - tags, - res->get_string(4), - res->get_string(5), - res->get_string(6) - }); + entrybuf.tags = tags; + + entries.push_back(entrybuf); } return entries;