diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index d6663680c25..576c626aaea 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -29,6 +29,7 @@ endif() add_subdirectory(processlauncher) if (WITH_QMLDESIGNER) add_subdirectory(qml2puppet) + add_subdirectory(sqlitetester) endif() add_subdirectory(qtcdebugger) ## windows only # add_subdirectory(qtcrashhandler) diff --git a/src/tools/sqlitetester/CMakeLists.txt b/src/tools/sqlitetester/CMakeLists.txt new file mode 100644 index 00000000000..d259383c545 --- /dev/null +++ b/src/tools/sqlitetester/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.16) + +# standalone build +if (NOT QT_CREATOR_API_DEFINED) + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake") + + project(sqlitetester) + + set(CMAKE_AUTOMOC ON) + set(CMAKE_AUTORCC ON) + set(CMAKE_AUTOUIC ON) + set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + set(CMAKE_CXX_EXTENSIONS OFF) + + set(DESTINATION DESTINATION .) + include(QtCreatorIDEBranding) + include(QtCreatorAPI) + qtc_handle_compiler_cache_support() + + find_package(Qt6 + COMPONENTS Core Gui Widgets + REQUIRED + ) +endif() + +add_qtc_executable(sqlitetester + ${DESTINATION} + CONDITION WINDOWS AND BUILD_DESIGNSTUDIO + DEPENDS + Sqlite + Qt::Core Qt::Widgets + INCLUDES + ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} + SOURCES + main.cpp +) diff --git a/src/tools/sqlitetester/main.cpp b/src/tools/sqlitetester/main.cpp new file mode 100644 index 00000000000..1f514baed60 --- /dev/null +++ b/src/tools/sqlitetester/main.cpp @@ -0,0 +1,137 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class DatabaseApp : public QWidget { + Q_OBJECT + +public: + DatabaseApp(QWidget *parent = nullptr); + +private slots: + void onSetDirectoryClicked(); + void createDatabase(const QString &dirPath); + +private: + void deleteFileIfExist(const QString &filePath); + void logMessage(const QString &message); + void logDetailedWindowsError(); + + QLineEdit *directoryLineEdit; + QTextBrowser *logBrowser; + QString databaseDirectory; +}; + +DatabaseApp::DatabaseApp(QWidget *parent) : QWidget(parent) { + QVBoxLayout *layout = new QVBoxLayout(this); + + directoryLineEdit = new QLineEdit(this); + directoryLineEdit->setPlaceholderText("Enter database directory path"); + layout->addWidget(directoryLineEdit); + + QPushButton *setDirectoryButton = new QPushButton("Set Directory and Create Database", this); + layout->addWidget(setDirectoryButton); + + logBrowser = new QTextBrowser(this); + layout->addWidget(logBrowser); + + connect(setDirectoryButton, &QPushButton::clicked, this, &DatabaseApp::onSetDirectoryClicked); +} + +void DatabaseApp::onSetDirectoryClicked() { + QString dirPath = directoryLineEdit->text(); + if (dirPath.isEmpty()) { + logMessage("Directory path is empty."); + return; + } + + QDir dir(dirPath); + if (!dir.exists()) { + logMessage("Directory does not exist."); + return; + } + + QTemporaryFile tempFile(dirPath + "/tempfileXXXXXX"); + if (!tempFile.open()) { + logMessage("Cannot create temporary file in the directory: " + tempFile.errorString()); + logDetailedWindowsError(); + return; + } + tempFile.close(); + + createDatabase(dirPath); +} + +void DatabaseApp::deleteFileIfExist(const QString &filePath) { + if (QFile::exists(filePath)) { + if (!QFile::remove(filePath)) { + logMessage(QString("Failed to delete existing file %1 before creating database").arg(filePath)); + logDetailedWindowsError(); + return; + } + } +} + +void DatabaseApp::createDatabase(const QString &dirPath) { + databaseDirectory = dirPath; + QString dbPath = dirPath + "/mysqlitetester.db"; + dbPath.replace("\\", "/"); + deleteFileIfExist(dbPath); + + try { + Sqlite::Database database{Utils::PathString{dbPath}}; + } catch (const Sqlite::Exception &e) { + logMessage(QString("Cannot create %1: %2").arg(dbPath, QString::fromUtf8(e.what()))); + logDetailedWindowsError(); + } + deleteFileIfExist(dbPath); + logMessage(QString("Test with %1 was successful.").arg(dbPath)); +} + +void DatabaseApp::logMessage(const QString &message) { + logBrowser->append(message); +} + +void DatabaseApp::logDetailedWindowsError() { + DWORD errorCode = GetLastError(); + if (errorCode != 0) { + LPVOID errorMsg; + DWORD size = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&errorMsg, 0, NULL); + + if (size) { + QString detailedMessage = QString::fromWCharArray((LPWSTR)errorMsg, size); + logMessage("Windows error: " + detailedMessage); + LocalFree(errorMsg); + } + } +} + +int main(int argc, char *argv[]) { + Sqlite::LibraryInitializer::initialize(); + + + QApplication app(argc, argv); + DatabaseApp window; + window.setWindowTitle("SQLite Write Database Tester"); + window.resize(400, 300); + window.show(); + return app.exec(); +} + +#include "main.moc"