diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 31994d9..f5c4ad8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,6 +13,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Werror -O2") find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Core) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Core) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Sql) set(MAIN_SOURCES main.cpp @@ -37,6 +38,9 @@ set(MAIN_SOURCES view/ui/printer_settings.ui view/ui/updates.ui view/ui/add_preset.ui + + logic/printer_db.cpp + logic/printer_db.h ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) @@ -50,13 +54,20 @@ else() ) endif() -qt_add_resources(Calc3D "app_resources" - PREFIX "/" - FILES - view/resources.qrc -) +# qt_add_resources(Calc3D "app_resources" +# PREFIX "/" +# FILES +# view/resources.qrc +# ) -target_link_libraries(Calc3D PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Core) +target_link_libraries(Calc3D PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Sql) + +# путь к бд в проекте, опционально +# configure_file( +# ${CMAKE_CURRENT_SOURCE_DIR}/printers.db +# ${CMAKE_CURRENT_BINARY_DIR}/printers.db +# COPYONLY +# ) set_target_properties(Calc3D PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com diff --git a/src/controller/controller.h b/src/controller/controller.h deleted file mode 100644 index fb1739c..0000000 --- a/src/controller/controller.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -#include "../model/facade.h" - -class Controller { - public: - Controller(const Controller &other) = delete; - Controller(Controller &&other) = delete; - void operator=(const Controller &other) = delete; - ~Controller() = default; - - static std::shared_ptr GetInstance() { - static auto instance = std::shared_ptr(new Controller); - return instance; - } - - private: - std::shared_ptr facade; - - Controller() { facade_ = s21::Facade::GetInstance(); } -}; \ No newline at end of file diff --git a/src/logic/facade.h b/src/logic/facade.h new file mode 100644 index 0000000..eed60a2 --- /dev/null +++ b/src/logic/facade.h @@ -0,0 +1,48 @@ +#pragma once + +#include + +#include "printer_db.h" + +class Facade { + public: + Facade(const Facade &other) = delete; + Facade(Facade &&other) = delete; + void operator=(const Facade &other) = delete; + ~Facade() = default; + + static std::shared_ptr GetInstance() { + static auto instance = std::shared_ptr(new Facade); + return instance; + } + + bool addPrinter(const QString &name, double power, int age, double cost) { + return db.addPrinter(name, power, age, cost); + } + + QList getPrinterList() { return db.getPrinterList(); } + + bool deletePrinterByName(const QString &name) { + return db.deletePrinterByName(name); + } + + bool Database::updatePrinter(const QString &name, + const QHash &updates) { + return db.updatePrinter(name, updates); + } + + private: + Database db; + + Facade() { + //! TODO create if doesn't exist + QString dbPath = + QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + + "/printers.db"; //! TODO name! + db(dbPath); + if (!db.init()) { + qFatal("Database initialization failed!"); + // TODO make exc + } + } +}; \ No newline at end of file diff --git a/src/logic/printer_db.cpp b/src/logic/printer_db.cpp new file mode 100644 index 0000000..d8a7940 --- /dev/null +++ b/src/logic/printer_db.cpp @@ -0,0 +1,83 @@ +#include "printer_db.h" + +Database::Database(const QString &path) { + db = QSqlDatabase::addDatabase("QSQLITE"); + db.setDatabaseName(path); +} + +bool Database::init() { + if (!db.open()) { + qWarning() << "Error opening database:" << db.lastError(); + // TODO return ERROR + return false; + } + + QSqlQuery query; + return query.exec( + "CREATE TABLE IF NOT EXISTS printers (" + "id INTEGER PRIMARY KEY AUTOINCREMENT," + "name TEXT NOT NULL UNIQUE," + "power REAL NOT NULL," //! int?? + "age INTEGER NOT NULL," + "cost REAL NOT NULL"); +} + +bool Database::addPrinter(const QString &name, double power, int age, + double cost) { + QSqlQuery query; + query.prepare( + "INSERT INTO printers (name, power, age, cost) VALUES (:name, :power, " + ":age, :cost)"); + query.bindValue(":name", name); + query.bindValue(":power", power); + query.bindValue(":age", age); + query.bindValue(":cost", cost); + return query.exec(); +} + +QList Database::getPrinterList() { + QList printers; + QSqlQuery query("SELECT name FROM printers"); + while (query.next()) { + printers.append({query.value(0).toString()}); + } + return printers; +} +bool Database::deletePrinterByName(const QString &name) { + QSqlQuery query; + query.prepare("DELETE FROM printers WHERE name = :name"); + query.bindValue(":name", name); + + if (!query.exec()) { + // TODO exc + qWarning() << "Delete failed:" << query.lastError().text(); + return false; + } + + // была ли удалена хотя бы одна запись? + return query.numRowsAffected() > 0; +} + +bool Database::updatePrinter(const QString &name, + const QHash &updates) { + QStringList setClauses; + QSqlQuery query; + + for (auto it = updates.begin(); it != updates.end(); ++it) { + setClauses << QString("%1 = :%2").arg(it.key(), it.key()); + query.bindValue(":" + it.key(), it.value()); + } + + query.prepare("UPDATE printers SET " + setClauses.join(", ") + + " WHERE name = :name"); + query.bindValue(":name", name); + + return query.exec(); + + //! Как создать новое из фасада: + // !проще забрать сразу все + // QHash updates; + // updates["power"] = 350.0; + // updates["cost"] = 27000.0; + // db->updatePrinterPartial("MyPrinter", updates); +} diff --git a/src/logic/printer_db.h b/src/logic/printer_db.h new file mode 100644 index 0000000..22ad915 --- /dev/null +++ b/src/logic/printer_db.h @@ -0,0 +1,18 @@ +#include +#include +#include +#include + +class Database { + public: + Database(const QString &path); + bool init(); + bool addPrinter(const QString &name, double power, int age, double cost); + bool deletePrinterByName(const QString &name); + QList getPrinterList(); + bool updatePrinter(const QString &name, + const QHash &updates); + + private: + QSqlDatabase db; +}; \ No newline at end of file diff --git a/src/model/facade.h b/src/model/facade.h deleted file mode 100644 index 0354713..0000000 --- a/src/model/facade.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -class Facade { - public: - Facade(const Facade &other) = delete; - Facade(Facade &&other) = delete; - void operator=(const Facade &other) = delete; - ~Facade() = default; - - static std::shared_ptr GetInstance() { - static auto instance = std::shared_ptr(new Facade); - return instance; - } - - private: - Facade() {} -}; \ No newline at end of file