From 27dea3ffab203bd8591358f7465621ac9ca8f566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Hellstr=C3=B6mer?= Date: Sun, 20 Sep 2026 20:49:02 +0200 Subject: [PATCH] refactor: use VACUUM INTO for database export Remove the native SQLite backup API and direct SQLite library dependency. --- .github/workflows/linux-build.yml | 2 +- .github/workflows/windows-build.yml | 11 +---- CMakeLists.txt | 12 ----- INSTALL.md | 28 +++-------- build-aux/snap/snapcraft.yaml | 3 +- cmake/paths_compilation_installation.cmake | 2 + packaging_script_AppImage_aarch64.sh | 2 +- sources/dataBase/projectdatabase.cpp | 55 ++++++---------------- sources/dataBase/projectdatabase.h | 1 - 9 files changed, 28 insertions(+), 88 deletions(-) diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml index 496970357..18fa60f54 100644 --- a/.github/workflows/linux-build.yml +++ b/.github/workflows/linux-build.yml @@ -28,7 +28,7 @@ jobs: DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ ca-certificates build-essential cmake ninja-build git pkg-config \ qt6-base-dev qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \ - libqt6svg6-dev libqt6sql6-sqlite libsqlite3-dev libcups2-dev \ + libqt6svg6-dev libqt6sql6-sqlite libcups2-dev \ libxkbcommon-x11-0 \ xvfb openbox xdotool x11-utils # extra-cmake-modules and the KF6 libraries are installed rather than diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml index 3b5f37d67..4cc90c82a 100644 --- a/.github/workflows/windows-build.yml +++ b/.github/workflows/windows-build.yml @@ -49,7 +49,6 @@ jobs: mingw-w64-ucrt-x86_64-qt6-tools mingw-w64-ucrt-x86_64-qt6-translations mingw-w64-ucrt-x86_64-qt6-pdf - mingw-w64-ucrt-x86_64-sqlite3 mingw-w64-ucrt-x86_64-pkg-config mingw-w64-ucrt-x86_64-kwidgetsaddons mingw-w64-ucrt-x86_64-kcoreaddons @@ -122,8 +121,7 @@ jobs: -DQET_EXPORT_PROJECT_DB=ON \ -DCMAKE_C_COMPILER_LAUNCHER=/ucrt64/bin/ccache \ -DCMAKE_CXX_COMPILER_LAUNCHER=/ucrt64/bin/ccache \ - -DSQLite3_INCLUDE_DIR=/ucrt64/include \ - -DSQLite3_LIBRARY=/ucrt64/lib/libsqlite3.dll.a \ + .. ninja -j"$NPROC" @@ -196,13 +194,6 @@ jobs: cp /ucrt64/bin/libgcc_s_seh-1.dll "$BIN/" cp /ucrt64/bin/libstdc++-6.dll "$BIN/" cp /ucrt64/bin/libwinpthread-1.dll "$BIN/" - SQLITE=$(find /ucrt64/bin -name "libsqlite3*.dll" | head -1) - if [ -n "$SQLITE" ]; then - cp "$SQLITE" "$BIN/" - echo "SQLite3 copied: $(basename $SQLITE)" - else - echo "WARNING: libsqlite3 not found in /ucrt64/bin/" - fi cp "$GITHUB_WORKSPACE/build-aux/windows/QET64.nsi" "$NSIS_ROOT/" cp "$GITHUB_WORKSPACE/build-aux/windows/lang_extra.nsh" "$NSIS_ROOT/" diff --git a/CMakeLists.txt b/CMakeLists.txt index 12f279ffc..e8371d124 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,17 +118,6 @@ else() "without a backtrace") endif() -find_package(SQLite3 REQUIRED) - -# CMake < 4.3 only creates the SQLite::SQLite3 target (no SQLite3::SQLite3 -# alias yet), while CMake >= 4.3's bundled FindSQLite3 creates SQLite3::SQLite3 -# and deprecates the old name. Add the missing alias ourselves so we can use -# the modern target name everywhere regardless of the CMake version in use -# (this project must keep building on CMake versions below 4.3, e.g. on most -# current Linux distros). -if(NOT TARGET SQLite3::SQLite3 AND TARGET SQLite::SQLite3) - add_library(SQLite3::SQLite3 ALIAS SQLite::SQLite3) -endif() set(CMAKE_AUTOUIC_SEARCH_PATHS ${QET_DIR}/sources/ui) @@ -284,7 +273,6 @@ target_link_libraries( PRIVATE pugixml::pugixml SingleApplication::SingleApplication - SQLite3::SQLite3 ${KF_PRIVATE_LIBRARIES} ${QET_PRIVATE_LIBRARIES} ) diff --git a/INSTALL.md b/INSTALL.md index eeb14e741..ef4eaef78 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -27,18 +27,12 @@ git submodule update --init --recursive | C++17 compiler | required | GCC or Clang on Unix-like platforms; MSVC or MinGW-w64 g++ on Windows — see [Choosing a compiler](#3-choosing-a-compiler-unix) / [Building on Windows](#6-building-on-windows-msvc--mingw) | | Qt6 base + widgets | required | | | Qt6 **GuiPrivate** headers | required | needed for clickable PDF hyperlinks; **hard build failure** at CMake generate time if missing, see below | -| SQLite3 | required | used by the nomenclature/summary database | | Qt Linguist tools (`lrelease`) | required | compiles the tracked `.ts` files into `.qm` as part of every normal build | | pugixml | handled automatically | fetched and built via CMake FetchContent if not already present on the system — see [pugixml](#8-pugixml) below | | Qt Test module | required if building tests | `PACKAGE_TESTS` is `ON` by default; QtTest ships as part of the base Qt6 dev packages listed below on every platform, no extra package needed | | KDE Frameworks (KF6) | optional | see [Building without KDE Frameworks](#9-building-without-kde-frameworks) | | QtPdf module | optional | see [PDF page import](#7-pdf-page-import-qtpdf) | -A note on CMake versions: the project declares a minimum of 3.5 but is -routinely built with much newer releases; if your CMake is older than 4.3 it -simply won't have the newer `SQLite3::SQLite3` target name, which the build -script compensates for automatically. There is nothing you need to do either -way. ## 3. Building (out-of-source build) @@ -106,7 +100,7 @@ the closest match. sudo apt install \ build-essential cmake ninja-build git \ qt6-base-dev qt6-base-private-dev qt6-tools-dev qt6-tools-dev-tools \ - libsqlite3-dev \ + libkf6coreaddons-dev libkf6widgetsaddons-dev ``` @@ -138,7 +132,6 @@ sudo apt install libpugixml-dev sudo dnf install \ cmake gcc-c++ git \ qt6-qtbase-devel qt6-qtbase-private-devel qt6-qttools-devel \ - sqlite-devel \ kf6-kcoreaddons-devel kf6-kwidgetsaddons-devel ``` @@ -155,11 +148,10 @@ Optional, for a system pugixml: `sudo dnf install pugixml-devel`. pkg install \ cmake git \ qt6-base qt6-tools \ - sqlite3 \ kf6-kcoreaddons kf6-kwidgetsaddons ``` -(from ports: `devel/qt6-base`, `devel/qt6-tools`, `databases/sqlite3`, +(from ports: `devel/qt6-base`, `devel/qt6-tools`, `devel/kf6-kcoreaddons`, `x11-toolkits/kf6-kwidgetsaddons`.) Qt6's `GuiPrivate` headers ship as part of `qt6-base` on FreeBSD, no separate package is needed. `QtPdf` is not packaged on FreeBSD at the time of writing @@ -175,7 +167,7 @@ Optional, for a system pugixml: `pkg install pugixml` (`devel/pugixml`). Using [Homebrew](https://brew.sh): ```sh -brew install cmake qt sqlite ninja +brew install cmake qt ninja ``` Homebrew's `qt` formula is Qt6 and includes the private headers, so no @@ -193,7 +185,7 @@ Optional, for a system pugixml: `brew install pugixml`. See [Building on Windows](#6-building-on-windows-msvc--mingw) below — the package sources differ enough from the Unix-like platforms above (no system -package manager, SQLite3 and Qt aren't provided the same way) that it gets +package manager and Qt aren't provided the same way) that it gets its own section. ## 5. pugixml @@ -215,7 +207,7 @@ on Debian/Ubuntu, `pugixml-devel` on Fedora). Both toolchains QET's CMake build targets on Windows are covered here: **MSVC** (Visual Studio 2019/2022) and **MinGW-w64** (gcc). Unlike the Unix-like platforms above, there's no single system package manager, so -Qt, SQLite3 and (optionally) KDE Frameworks each need to be sourced +Qt and (optionally) KDE Frameworks each need to be sourced separately per toolchain. One piece of good news either way: unlike Debian/Fedora, the official Qt @@ -236,11 +228,7 @@ normally use `-DBUILD_WITH_KF=OFF` (see the 1. Install Visual Studio with the "Desktop development with C++" workload, and install Qt6 for MSVC (e.g. the `msvc2019_64` or `msvc2022_64` kit) via the [Qt Online Installer](https://www.qt.io/download-qt-installer). -2. Get SQLite3 — the simplest route is [vcpkg](https://vcpkg.io): - ```bat - vcpkg install sqlite3:x64-windows - ``` -3. Configure and build from an "x64 Native Tools Command Prompt for VS": +2. Configure and build from an "x64 Native Tools Command Prompt for VS": ```bat mkdir build && cd build cmake .. -G "Visual Studio 17 2022" -A x64 ^ @@ -293,9 +281,7 @@ Using the Qt Online Installer's bundled MinGW kit instead: point `CMAKE_PREFIX_PATH` at that kit (e.g. `C:\Qt\6.x.x\mingw_64`) and make sure its bundled `g++.exe` comes first on `PATH`, or pass `-DCMAKE_C_COMPILER`/`-DCMAKE_CXX_COMPILER` explicitly so CMake doesn't pick -up a different MinGW installation. SQLite3 still has to come from elsewhere -in this path — vcpkg with a `mingw`-flavoured triplet, or MSYS2's package as -above. +up a different MinGW installation. ## 7. Qt6 private headers (mandatory) diff --git a/build-aux/snap/snapcraft.yaml b/build-aux/snap/snapcraft.yaml index 9f27a510c..07a5e8955 100644 --- a/build-aux/snap/snapcraft.yaml +++ b/build-aux/snap/snapcraft.yaml @@ -71,7 +71,6 @@ parts: source: . stage-packages: - git - - sqlite3 - xdg-user-dirs - libqt6qml6 # libxcb-cursor0 workaround was needed against the Qt5/KF5 core22 content @@ -82,7 +81,7 @@ parts: - git - cmake - ninja-build - - libsqlite3-dev + - qt6-tools-dev - qt6-base-private-dev - qt6-declarative-dev diff --git a/cmake/paths_compilation_installation.cmake b/cmake/paths_compilation_installation.cmake index 2776b6153..c151ada30 100644 --- a/cmake/paths_compilation_installation.cmake +++ b/cmake/paths_compilation_installation.cmake @@ -62,7 +62,9 @@ if(WIN32) # puts the .qm files (see build-aux/windows/QElectroTech.wxs and the # windows-build workflow), and what the shortcuts pass as --lang-dir. set(QET_LANG_PATH "lang/") + set(QET_EXAMPLES_PATH "examples/") set(QET_LICENSE_PATH "./") + set(QET_ICONS_PATH "icons/hicolor/") # Liste des ressources Windows #RC_FILE = qelectrotech.rc endif() diff --git a/packaging_script_AppImage_aarch64.sh b/packaging_script_AppImage_aarch64.sh index fb4a0e032..1e6498c4c 100644 --- a/packaging_script_AppImage_aarch64.sh +++ b/packaging_script_AppImage_aarch64.sh @@ -1,7 +1,7 @@ #!/bin/bash #Based on raspberry pi 5 8 Gb Trixie -#sudo apt install git ssh rsync libqt5svg5-dev qt5-qmake qtbase5-dev libkf5widgetsaddons-dev libkf5coreaddons-dev libsqlite3-dev pkgconf libqt5waylandclient5-dev libqt5waylandcompositor5-dev g++ make +#sudo apt install git ssh rsync libqt5svg5-dev qt5-qmake qtbase5-dev libkf5widgetsaddons-dev libkf5coreaddons-dev pkgconf libqt5waylandclient5-dev libqt5waylandcompositor5-dev g++ make #mkdir -p AppImage/0.100.0/aarch64 # Get GIT sources #git clone --recursive https://github.com/qelectrotech/qelectrotech-source-mirror.git diff --git a/sources/dataBase/projectdatabase.cpp b/sources/dataBase/projectdatabase.cpp index 20d2c150d..2d3f0ab12 100644 --- a/sources/dataBase/projectdatabase.cpp +++ b/sources/dataBase/projectdatabase.cpp @@ -28,11 +28,11 @@ #include "../qetproject.h" #include +#include #include #include -#include -#include + /** @@ -1246,23 +1246,6 @@ void projectDataBase::bindDiagramInfoValues(QSqlQuery &query, Diagram *diagram) } #ifdef QET_EXPORT_PROJECT_DB -/** - @brief projectDataBase::sqliteHandle - @param db - @return the sqlite3 handler class used internally by db -*/ -sqlite3 *projectDataBase::sqliteHandle(QSqlDatabase *db) -{ - sqlite3 *handle = nullptr; - - QVariant v = db->driver()->handle(); - if (v.isValid() && qstrcmp(v.typeName(), "sqlite3*") == 0) { - handle = *static_cast(v.data()); - } - - return handle; -} - /** * @brief projectDataBase::exportDb @@ -1298,27 +1281,19 @@ void projectDataBase::exportDb(projectDataBase *db, return; } - QString connection_name("export_project_db_" % db->project()->uuid().toString()); - - if (true) //Enter in a scope only to nicely use QSqlDatabase::removeDatabase just after the end of the scope - { - auto file_db = QSqlDatabase::addDatabase("QSQLITE", connection_name); - file_db.setDatabaseName(path_); - if (!file_db.open()) { - return; - } - - auto memory_db_handle = sqliteHandle(&db->m_data_base); - auto file_db_handle = sqliteHandle(&file_db); - - auto sqlite_backup = sqlite3_backup_init(file_db_handle, "main", memory_db_handle, "main"); - if (sqlite_backup) - { - sqlite3_backup_step(sqlite_backup, -1); - sqlite3_backup_finish(sqlite_backup); - } - file_db.close(); + // VACUUM INTO requires the destination not to exist. QFileDialog may ask + // about overwriting, but it does not remove the existing file for us. + if (QFile::exists(path_) && !QFile::remove(path_)) { + qWarning() << "Unable to replace project database export:" << path_; + return; + } + + // VACUUM INTO creates a standalone copy of the current database without + // requiring access to the SQLite driver's native connection handle. + const auto escaped_path = path_.replace("'", "''"); + QSqlQuery query(db->m_data_base); + if (!query.exec("VACUUM INTO '" % escaped_path % "'")) { + qWarning() << "Unable to export project database:" << query.lastError().text(); } - QSqlDatabase::removeDatabase(connection_name); } #endif diff --git a/sources/dataBase/projectdatabase.h b/sources/dataBase/projectdatabase.h index abd5e966c..d73a449a6 100644 --- a/sources/dataBase/projectdatabase.h +++ b/sources/dataBase/projectdatabase.h @@ -137,7 +137,6 @@ class projectDataBase : public QObject #ifdef QET_EXPORT_PROJECT_DB public: - static sqlite3 *sqliteHandle(QSqlDatabase *db); static void exportDb(projectDataBase *db, QWidget *parent = nullptr, const QString &caption = QString(),