diff --git a/.gitmodules b/.gitmodules index 20cc13f..4254dc4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "redkbuild"] path = redkbuild url = git@gitea.redkit-lab.work:redkit-lab/redkbuild.git +[submodule "redkitty"] + path = redkitty + url = git@gitea.redkit-lab.work:redkit-lab/redkitty.git diff --git a/prerequisites/qbs/imports/SQLiteArtifactsExport.qbs b/prerequisites/qbs/imports/SQLiteArtifactsExport.qbs new file mode 100644 index 0000000..1869fe2 --- /dev/null +++ b/prerequisites/qbs/imports/SQLiteArtifactsExport.qbs @@ -0,0 +1,8 @@ +import qbs + +Export { + Depends { name: "cpp" } + Depends { name: "rsc.sqlite.settings" } + + rsc.sqlite.settings.includeRegexValues: exportingProduct.includeRegexValue +} diff --git a/prerequisites/qbs/modules/karchive/karchive.qbs b/prerequisites/qbs/modules/karchive/karchive.qbs new file mode 100644 index 0000000..fae3d7e --- /dev/null +++ b/prerequisites/qbs/modules/karchive/karchive.qbs @@ -0,0 +1,53 @@ +import qbs + +Module { + id: karchive + + readonly property string karchive_path: project.sourceDirectory + "/external_libs/karchive" + readonly property string libKF5ArchivePath: karchive.karchive_path + "/lib" + + (qbs.buildVariant == "release" ? "/Release" : "/Debug") + property bool installFiles: true + + Depends { name: "glob" } + Depends { name: "cpp" } + Depends { name: "zlib" } + + Properties + { + condition: qbs.targetOS.contains("linux") || qbs.targetOS.contains("astra") + cpp.includePaths: [ karchive.karchive_path + "/include/lin" ] + cpp.libraryPaths: [ karchive.libKF5ArchivePath + "/lin" ] + cpp.dynamicLibraries: "KF5Archive" + } + + Properties { + condition: qbs.targetOS.contains("windows") + cpp.includePaths: [ karchive.karchive_path + "/include/win" ] + cpp.libraryPaths: [ karchive.libKF5ArchivePath + "/win" ] + cpp.dynamicLibraries: "KF5Archive" + } + + InstallGroup { + name: "karchive_lin" + condition: qbs.targetOS.contains("linux") || qbs.targetOS.contains("astra") + files: [ + karchive.libKF5ArchivePath + "/lin/libKF5Archive.so", + karchive.libKF5ArchivePath + "/lin/libKF5Archive.so.5", + karchive.libKF5ArchivePath + "/lin/libKF5Archive.so.5.108.0" + ] + qbs.install: karchive.installFiles + qbs.installDir: glob.binInstallPrefix + } + + InstallGroup { + name: "karchive_win" + condition: qbs.targetOS.contains("windows") + files: [ + karchive.libKF5ArchivePath + "/win/KF5Archive.dll", + karchive.libKF5ArchivePath + "/win/KF5Archive.lib" + ] + qbs.install: karchive.installFiles + qbs.installDir: glob.binInstallPrefix + } + zlib.installFiles: true +} diff --git a/project.qbs b/project.qbs index f857caf..d717770 100644 --- a/project.qbs +++ b/project.qbs @@ -3,16 +3,18 @@ import qbs Project { name: "opds++" qbsSearchPaths: [ - "redkbuild" + "redkitty/qbs", + "redkbuild", + "redkitty/lib/redkit-gen-integration/qbs", + "prerequisites/qbs", ] references: [ + "redkitty/lib/rsc/libs_impl/rdbaseimpl/rdbaseimpl.qbs", + "redkitty/lib/rcore/rcore.qbs", + "src/cpp-opds.qbs", "src/database/database.qbs", "src/restapi/restapi.qbs", - "src/model/model.qbs", - "src/repositories/repositories.qbs", - "src/services/services.qbs", - "src/sql_builder/sql_builder.qbs", ] } diff --git a/redkbuild b/redkbuild index 9f3a81c..3adf92a 160000 --- a/redkbuild +++ b/redkbuild @@ -1 +1 @@ -Subproject commit 9f3a81cc2386d6f8653b29f1f17bc0c5e03dad62 +Subproject commit 3adf92aad6bfaeb119d5bc86d4e264dfc2c04c04 diff --git a/redkitty b/redkitty new file mode 160000 index 0000000..2316dde --- /dev/null +++ b/redkitty @@ -0,0 +1 @@ +Subproject commit 2316ddea7250c3d828a7c4a45f49ea8bc100448b diff --git a/src/cpp-opds.qbs b/src/cpp-opds.qbs index a5e1f25..ae24c6d 100644 --- a/src/cpp-opds.qbs +++ b/src/cpp-opds.qbs @@ -1,27 +1,42 @@ /*! \qmltype cpp-opds - \inherits Application + \inherits Project \brief Описание */ PSApplication { - cpp.defines: [ - // You can make your code fail to compile if it uses deprecated APIs. - // In order to do so, uncomment the following line. - //"QT_DISABLE_DEPRECATED_BEFORE=0x060000" // disables all the APIs deprecated before Qt 6.0.0 - "DATABASE_SQLITE"] - consoleApplication: true - - // Depends { name: "Qt"; submodules: [ "core", "sql", "network" ] } - Depends { name: "Qt"; submodules: ["core", "sql", "network"] } - Depends { name: "cpp" } - Depends { name: "database" } - Depends { name: "services" } - Depends { name: "restapi" } - - Group { - name: "cpp" - files: [ - "main.cpp", + // CppApplication { + cpp.defines: [ + // You can make your code fail to compile if it uses deprecated APIs. + // In order to do so, uncomment the following line. + //"QT_DISABLE_DEPRECATED_BEFORE=0x060000" // disables all the APIs deprecated before Qt 6.0.0 + "DATABASE_SQLITE" ] - } -} // Application + consoleApplication: true + + Depends { name: "Qt"; submodules: [ "core", "sql", "network" ] } + Depends { name: "cpp" } + Depends { name: "database" } + Depends { name: "odb.gen" } + Depends { name: "sqlite3" } + Depends { name: "restapi" } + Depends { name: "redkit_gen" } + Depends { name: "rdbase" } + + cpp.cxxLanguageVersion: "c++20" + + Group { + name: "cpp" + files: [ + "main.cpp", + ] + } + + cpp.dynamicLibraries: [ + "odb-sqlite", + "odb-qt", + "odb", + "sqlite3" + ] + + // } +} // Project diff --git a/src/database/author_s.h b/src/database/author_s.h new file mode 100644 index 0000000..5451fba --- /dev/null +++ b/src/database/author_s.h @@ -0,0 +1,64 @@ +// file : hello/person.hxx +// copyright : not copyrighted - public domain + +#ifndef AUTHOR_S_H +#define AUTHOR_S_H + +#include "database_global.h" + +#include + +#include +#include +#include + +#pragma db object +class DATABASE_EXPORT Author_S +{ +public: + Author_S() = default; + + Author_S(const QString& firstN, + const QString& lastN, + const unsigned short age) : + m_firstName(firstN), + m_lastName(lastN), + m_age(age) + { + } + + unsigned long long id() const { return m_id; } + QString firstName() const { return m_firstName; } + QString lastName() const { return m_lastName; } + unsigned short age() const { return m_age; } + + QString full_name() const { return m_firstName + " " + m_lastName; } + + void age(unsigned short age) { m_age = age; } + +private: + friend class odb::access; + +private: +#pragma db id auto + quint64 m_id; + + QString m_firstName; + QString m_lastName; + quint8 m_age; +}; + +#pragma db view object(Author_S) +struct person_stat +{ +#pragma db column("count(" + Author_S::m_id + ")") + std::size_t count; + +#pragma db column("min(" + Author_S::m_age + ")") + unsigned short min_age; + +#pragma db column("max(" + Author_S::m_age + ")") + unsigned short max_age; +}; + +#endif // AUTHOR_S_H diff --git a/src/database/book_s.h b/src/database/book_s.h new file mode 100644 index 0000000..d516b51 --- /dev/null +++ b/src/database/book_s.h @@ -0,0 +1,64 @@ +// file : hello/person.hxx +// copyright : not copyrighted - public domain + +#ifndef BOOK_S_H +#define BOOK_S_H + +#include "database_global.h" + +#include +#include +#include +#include + +#include "author_s.h" + +#pragma db object +class DATABASE_EXPORT Book_S +{ +public: + Book_S() = default; + + Book_S(const QString& name, + const SH& author, + const int year) + { + m_author = author; + m_name = name; + m_year = year; + }; + + unsigned long long id() const { return m_id; } + SH author() const { return m_author; } + QString name() const { return m_name; } + int year() const { return m_year; } + +private: + friend class odb::access; + +private: +#pragma db id auto + quint64 m_id; + + SH m_author; + QString m_name; + quint8 m_year; +}; + +// #pragma db view object(Book_S) object(Author_S = author:Book_S::m_author) +// struct BookByAuthorView +// { +// #pragma db column(Book_S::m_id) +// quint64 book_id; + +// #pragma db column(Book_S::m_name) +// QString book_name; + +// #pragma db column(Book_S::m_year) +// qint8 year; + +// #pragma db column(Author_S::m_first + " " + Author_S::m_last) +// QString author_full_name; +// }; + +#endif // BOOK_S_H diff --git a/src/database/database.hxx b/src/database/database.hxx new file mode 100644 index 0000000..a33e812 --- /dev/null +++ b/src/database/database.hxx @@ -0,0 +1,183 @@ +// file : hello/database.hxx +// copyright : not copyrighted - public domain + +// +// Create concrete database instance based on the DATABASE_* macros. +// + +#ifndef DATABASE_HXX +#define DATABASE_HXX + +#include // std::exit +#include +#include // std::unique_ptr +#include + +#include + +#if defined(DATABASE_MYSQL) +#include +#elif defined(DATABASE_SQLITE) +#include +#include +#include +#include +#elif defined(DATABASE_PGSQL) +#include +#elif defined(DATABASE_ORACLE) +#include +#elif defined(DATABASE_MSSQL) +#include +#else +#error unknown database; did you forget to define the DATABASE_* macros? +#endif + +#include +#include +#include + +using oDBase = odb::sqlite::database; +using uDBase = U; + +struct testData +{ + QString first; + QString last; + int age; +}; + +// Функция для генерации случайной строки (имени или фамилии) +QString generate_random_string(const QVector& pool) +{ + static std::random_device rd; + static std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(0, pool.size() - 1); + return pool[dis(gen)]; +} + +// Функция для генерации случайного года +int generate_random_year(int min_year = 1900, int max_year = 2020) +{ + static std::random_device rd; + static std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(min_year, max_year); + return dis(gen); +} + +QVector fillDB() +{ + QVector first_names = { + "John", "Jane", "Alex", "Chris", "Robert", "Emily", "James", "Linda", "David", "Sarah", + "Michael", "Elizabeth", "Daniel", "Samantha", "William", "Olivia", "Ethan", "Sophia", "Joshua", "Charlotte", + "Daniel", "Grace", "Benjamin", "Isabella", "Matthew", "Victoria", "Henry", "Abigail", "Samuel", "Megan", + "Lucas", "Lily", "Andrew", "Madison", "Jackson", "Chloe", "Aiden", "Amelia", "Thomas", "Natalie", + "Ryan", "Zoe", "Jack", "Harper", "Elijah", "Ava", "Isaac", "Mia", "Caleb", "Ella" + }; + QVector last_names = { + "Doe", "Smith", "Johnson", "Williams", "Jones", "Brown", "Davis", "Miller", "Wilson", "Moore", + "Taylor", "Anderson", "Thomas", "Jackson", "White", "Harris", "Martin", "Thompson", "Garcia", "Martinez", + "Roberts", "Clark", "Lewis", "Walker", "Young", "Allen", "King", "Wright", "Scott", "Adams", + "Baker", "Gonzalez", "Nelson", "Carter", "Mitchell", "Perez", "Robinson", "Hughes", "Flores", "Cook", + "Rogers", "Gutierrez", "Ramirez", "Diaz", "Perez", "Ross", "Sanders", "Price", "Howard", "Cooper" + }; + + QVector vecTest; + + for (int i = 0; i < 50; ++i) + { + QString first_name = generate_random_string(first_names); + QString last_name = generate_random_string(last_names); + int birth_year = generate_random_year(1900, 2000); + + vecTest.push_back({ first_name, last_name, birth_year }); + } + + return vecTest; +} + +inline uDBase openDB(const std::string path_db) +{ + // Открыть БД, если она существует + auto db_ptr = new oDBase(path_db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE); + + if (std::filesystem::is_regular_file(path_db)) + return uDBase(db_ptr); + + // И создать новую, если не существует + uDBase db(db_ptr); + + odb::connection_ptr connect_ptr(db->connection()); + + connect_ptr->execute("PRAGMA foreign_keys=OFF"); + + odb::transaction tans(db->begin()); + odb::schema_catalog::create_schema(*db); + tans.commit(); + + connect_ptr->execute("PRAGMA foreign_keys=ON"); + + return db; +} + +inline std::unique_ptr create_database(int& argc, char* argv[]) +{ + using namespace std; + using namespace odb::core; + + if (argc > 1 && argv[1] == string("--help")) + { + cout << "Usage: " << argv[0] << " [options]" << endl + << "Options:" << endl; + +#if defined(DATABASE_MYSQL) + odb::mysql::database::print_usage(cout); +#elif defined(DATABASE_SQLITE) + odb::sqlite::database::print_usage(cout); +#elif defined(DATABASE_PGSQL) + odb::pgsql::database::print_usage(cout); +#elif defined(DATABASE_ORACLE) + odb::oracle::database::print_usage(cout); +#elif defined(DATABASE_MSSQL) + odb::mssql::database::print_usage(cout); +#endif + + exit(0); + } + +#if defined(DATABASE_MYSQL) + unique_ptr db(new odb::mysql::database(argc, argv)); +#elif defined(DATABASE_SQLITE) + + unique_ptr db(new odb::sqlite::database(argc, + argv, + false, + SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)); + + // Create the database schema. Due to bugs in SQLite foreign key + // support for DDL statements, we need to temporarily disable + // foreign keys. + // + { + connection_ptr connect_ptr(db->connection()); + + connect_ptr->execute("PRAGMA foreign_keys=OFF"); + + transaction tans(connect_ptr->begin()); + schema_catalog::create_schema(*db); + tans.commit(); + + connect_ptr->execute("PRAGMA foreign_keys=ON"); + } +#elif defined(DATABASE_PGSQL) + unique_ptr db(new odb::pgsql::database(argc, argv)); +#elif defined(DATABASE_ORACLE) + unique_ptr db(new odb::oracle::database(argc, argv)); +#elif defined(DATABASE_MSSQL) + unique_ptr db( + new odb::mssql::database(argc, argv, false, "TrustServerCertificate=yes")); +#endif + + return db; +} + +#endif // DATABASE_HXX diff --git a/src/database/database.qbs b/src/database/database.qbs index 3fe9dce..349b198 100644 --- a/src/database/database.qbs +++ b/src/database/database.qbs @@ -1,16 +1,55 @@ -import qbs - +/*! + \qmltype cpp-opds + \inherits Project + \brief Описание +*/ PSLibrary { - Depends { name: "Qt"; submodules: "sql"} + cpp.defines: [ + // You can make your code fail to compile if it uses deprecated APIs. + // In order to do so, uncomment the following line. + //"QT_DISABLE_DEPRECATED_BEFORE=0x060000" // disables all the APIs deprecated before Qt 6.0.0 + "DATABASE_SQLITE", + "DATABASE_LIBRARY" + ] + consoleApplication: true - Depends { name: "model" } - Depends { name: "sql_builder" } + Depends { name: "Qt"; submodules: [ "core", "sql", "network" ] } + Depends { name: "cpp" } + + Depends { name: "odb.gen" } + Depends { name: "rdbase" } + + Depends { name: "redkit_gen" } + redkit_gen.includeModules: ["JsonSerializer"] + + odb.gen.databases: "sqlite" + cpp.cxxLanguageVersion: "c++17" Group { name: "cpp" files: [ - "**/*.h", - "**/*.cpp" + "databasemanager.*", + "*.cpp", + "*.h", + "*.hxx", ] + excludeFiles: odbs.files } + + Group { + id: odbs + name: "odb" + files: [ + "author_s.h", + "book_s.h", + ] + fileTags: ["hpp", "odbxx"] + } + + cpp.dynamicLibraries: [ + "odb-sqlite", + "odb-qt", + "odb", + "sqlite3" + ] } diff --git a/src/database/database_global.h b/src/database/database_global.h new file mode 100644 index 0000000..35e570f --- /dev/null +++ b/src/database/database_global.h @@ -0,0 +1,12 @@ +#ifndef DATABASE_GLOBAL_H +#define DATABASE_GLOBAL_H + +#include + +#if defined(DATABASE_LIBRARY) +#define DATABASE_EXPORT Q_DECL_EXPORT +#else +#define DATABASE_EXPORT Q_DECL_IMPORT +#endif + +#endif // DATABASE_GLOBAL_H diff --git a/src/database/databasemanager.cpp b/src/database/databasemanager.cpp deleted file mode 100644 index 21bd43d..0000000 --- a/src/database/databasemanager.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "databasemanager.h" - -#include -#include - -DatabaseManager::DatabaseManager() {} - -DatabaseManager::~DatabaseManager() -{ - if (db.isOpen()) - db.close(); -} - -DatabaseManager& DatabaseManager::instance() -{ - static DatabaseManager instance; - return instance; -} - -bool DatabaseManager::connect(const QString& dbPath) -{ - db = QSqlDatabase::addDatabase("QSQLITE"); - db.setDatabaseName(dbPath); - return db.open(); -} - -QSqlDatabase& DatabaseManager::database() -{ - return db; -} - -void DatabaseManager::initializeDatabase() -{ - QSqlQuery query; - - query.exec(model::createTableBook()); - query.exec(model::createTableAuthor()); -} diff --git a/src/database/databasemanager.h b/src/database/databasemanager.h deleted file mode 100644 index 00ca359..0000000 --- a/src/database/databasemanager.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef DATABASEMANAGER_H -#define DATABASEMANAGER_H - -#include -#include - -class Q_DECL_EXPORT DatabaseManager -{ -public: - static DatabaseManager& instance(); - bool connect(const QString& dbPath); - QSqlDatabase& database(); - void initializeDatabase(); - -private: - DatabaseManager(); - ~DatabaseManager(); - QSqlDatabase db; -}; - -#endif // DATABASEMANAGER_H diff --git a/src/main.cpp b/src/main.cpp index 7c88e83..604f2cd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,53 +1,137 @@ #include +#include +#include +#include +#include + #include -#include +/* Опыты с odb */ +#include // Должен быть здесь +#include +#include // Должен быть здесь +#include +#include // create_database +#include -#include -#include +#include -#include +void fillBooksBD(uDBase& db) +{ + try + { + QVector> authors = { + SH::create("George", "Orwell", 142), + SH::create("J.K.", "Rowling", 56), + SH::create("J.R.R.", "Tolkien", 81), + SH::create("Leo", "Tolstoy", 189), + SH::create("Fyodor", "Dostoevsky", 174), + SH::create("Mark", "Twain", 183), + SH::create("Charles", "Dickens", 208), + SH::create("Virginia", "Woolf", 134), + SH::create("Ernest", "Hemingway", 122), + SH::create("Gabriel", "García Márquez", 98), + SH::create("Franz", "Kafka", 100), + SH::create("Harper", "Lee", 64), + SH::create("William", "Shakespeare", 459), + SH::create("Oscar", "Wilde", 155), + SH::create("Aldous", "Huxley", 123), + SH::create("Jane", "Austen", 210), + SH::create("John", "Steinbeck", 116), + SH::create("Agatha", "Christie", 124), + SH::create("Isaac", "Asimov", 105) + }; + + // Список книг + QVector books = { + Book_S("1984", authors[0], 1949), + Book_S("Harry Potter and the Philosopher's Stone", authors[1], 1997), + Book_S("The Hobbit", authors[2], 1937), + Book_S("War and Peace", authors[3], 1869), + Book_S("Crime and Punishment", authors[4], 1866), + Book_S("Adventures of Huckleberry Finn", authors[5], 1884), + Book_S("A Tale of Two Cities", authors[6], 1859), + Book_S("Mrs. Dalloway", authors[7], 1925), + Book_S("The Old Man and the Sea", authors[8], 1952), + Book_S("One Hundred Years of Solitude", authors[9], 1967), + Book_S("The Trial", authors[10], 1925), + Book_S("To Kill a Mockingbird", authors[11], 1960), + Book_S("Macbeth", authors[12], 1606), + Book_S("The Picture of Dorian Gray", authors[13], 1890), + Book_S("Brave New World", authors[14], 1932), + Book_S("Pride and Prejudice", authors[15], 1813), + Book_S("The Brothers Karamazov", authors[4], 1880), + Book_S("The Grapes of Wrath", authors[16], 1939), + Book_S("Murder on the Orient Express", authors[17], 1934), + Book_S("I, Robot", authors[18], 1950), + Book_S("Animal Farm", authors[0], 1945), + Book_S("Harry Potter and the Chamber of Secrets", authors[1], 1998), + Book_S("The Lord of the Rings: The Fellowship of the Ring", authors[2], 1954), + Book_S("Anna Karenina", authors[3], 1878), + Book_S("The Idiot", authors[4], 1869), + Book_S("The Adventures of Tom Sawyer", authors[5], 1876), + Book_S("Oliver Twist", authors[6], 1837), + Book_S("To the Lighthouse", authors[7], 1927), + Book_S("For Whom the Bell Tolls", authors[8], 1940), + Book_S("Love in the Time of Cholera", authors[9], 1985), + Book_S("The Metamorphosis", authors[10], 1915), + Book_S("Go Set a Watchman", authors[11], 2015), + Book_S("King Lear", authors[12], 1605), + Book_S("The Importance of Being Earnest", authors[13], 1895), + Book_S("Brave New World Revisited", authors[14], 1958), + Book_S("Emma", authors[15], 1815), + Book_S("The Double", authors[4], 1846), + Book_S("Of Mice and Men", authors[16], 1937), + Book_S("And Then There Were None", authors[17], 1939), + Book_S("The Foundation Trilogy", authors[18], 1951), + Book_S("Down and Out in Paris and London", authors[0], 1933), + Book_S("Harry Potter and the Prisoner of Azkaban", authors[1], 1999), + Book_S("The Lord of the Rings: The Two Towers", authors[2], 1954), + Book_S("War and Peace", authors[3], 1869), + Book_S("The Brothers Karamazov", authors[4], 1880), + Book_S("The Prince and the Pauper", authors[5], 1881), + Book_S("David Copperfield", authors[6], 1850), + Book_S("The Waves", authors[7], 1931), + Book_S("A Farewell to Arms", authors[8], 1929), + Book_S("Chronicle of a Death Foretold", authors[9], 1981) + }; + + // Сохранение авторов в базу данных + { + odb::core::transaction t(db->begin()); + for (auto& author : authors) + db->persist(author); // Используем get() для получения сырого указателя + t.commit(); + } + + // Сохранение книг в базу данных + { + odb::core::transaction t(db->begin()); + for (auto& book : books) + db->persist(book); + t.commit(); + } + + std::cout << "Test data added successfully." << std::endl; + } + catch (const odb::exception& e) + { + std::cerr << "Error adding test data: " << e.what() << std::endl; + } +} int main(int argc, char* argv[]) { QCoreApplication a(argc, argv); - if (!DatabaseManager::instance().connect("library.db")) - { - qCritical() << "Ошибка: не удалось подключиться к базе данных!"; - return -1; - } + const std::string dbPath = "test_db.sqlite"; + uDBase db(openDB(dbPath)); - DatabaseManager::instance().initializeDatabase(); + // TODO Как-то нужно выполнять лишь раз + // fillBooksBD(db); - if (BookService::add({ .title = "Война и мир", - .author = { .name = "Лев Толстой" }, - .filePath = "/books/war_and_peace.epub" })) - { - qDebug() << "Книга успешно добавлена!"; - } - else - { - qCritical() << "Ошибка при добавлении книги!"; - } - - QVector books = BookService::fetchAll(); - - for (const model::Book& book : books) - { - qDebug() << "ID:" << book.id << "Название:" << book.title - << "Автор:" << book.author.name << "Файл:" << book.filePath; - } - - QVector authors = AuthorService::fetchAll(); - - for (const model::Author& author : authors) - { - qDebug() << "ID:" << author.id << "Имя:" << author.name; - } - - RestApiServer server; + RestApiServer server(*db); server.start(8080); // Set up code that uses the Qt event loop here. diff --git a/src/model/author.h b/src/model/author.h deleted file mode 100644 index dd5713f..0000000 --- a/src/model/author.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef AUTHOR_H -#define AUTHOR_H - -#include - -#include - -namespace model -{ - -namespace authorconst -{ - -const QString TABLE = "authors"; - -const QString ID = "id"; -const QString NAME = "name"; - -// const QString M_AUTHOR_ID = "id"; -// const QString M_AUTHOR_FIRST_NAME = "first_name"; -// const QString M_AUTHOR_LAST_NAME = "last_name"; -// const QString M_AUTHOR_YEAR = "year"; - -} - -struct Author -{ - int id = 0; - QString name; - // QString firstName; - // QString lastName; - // QString birthdayYear; -}; - -static inline QString createTableAuthor() -{ - // query.exec("CREATE TABLE IF NOT EXISTS authors (" - // "id INTEGER PRIMARY KEY AUTOINCREMENT," - // "name TEXT UNIQUE NOT NULL" - // ")"); - - Builder::TableSchema tBuilder(model::authorconst::TABLE); - tBuilder.addColumn({ .name = model::authorconst::ID, - .type = "INTEGER", - .primaryKey = true }); - - tBuilder.addColumn({ .name = model::authorconst::NAME, - .type = "TEXT", - .notNull = true, - .unique = true }); - return tBuilder.get(); -} - -} // namespace model - -#endif // AUTHOR_H diff --git a/src/model/book.h b/src/model/book.h deleted file mode 100644 index 49a7435..0000000 --- a/src/model/book.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef BOOK_H -#define BOOK_H - -#include - -#include - -#include - -namespace model -{ - -namespace bookconst -{ - -const QString TABLE = "books"; - -const QString ID = "id"; -const QString TITLE = "title"; -const QString AUTHOR_ID = "author_id"; -const QString FILEPATH = "file_path"; - -} - -struct Book -{ - int id = 0; - QString title; - Author author; - QString filePath; -}; - -static inline QString createTableBook() -{ - // query.exec("CREATE TABLE IF NOT EXISTS books (" - // "id INTEGER PRIMARY KEY AUTOINCREMENT," - // "title TEXT NOT NULL," - // "file_path TEXT NOT NULL," - // "author_id INTEGER NOT NULL," - // "FOREIGN KEY (author_id) REFERENCES authors(id) ON DELETE CASCADE" - // ");"); - - Builder::TableSchema tBuilder(model::bookconst::TABLE); - tBuilder.addColumn({ .name = model::bookconst::ID, - .type = "INTEGER", - .primaryKey = true }); - - tBuilder.addColumn({ .name = model::bookconst::TITLE, - .type = "TEXT", - .notNull = true }); - - tBuilder.addColumn({ .name = model::bookconst::FILEPATH, - .type = "TEXT", - .notNull = true }); - - tBuilder.addColumn({ .name = model::bookconst::AUTHOR_ID, - .type = "INTEGER", - .notNull = true, - .foreignKeyTable = model::authorconst::TABLE, - .foreignKeyColumn = model::authorconst::ID }); - return tBuilder.get(); -} - -} // namespace model -#endif // BOOK_H diff --git a/src/model/model.qbs b/src/model/model.qbs deleted file mode 100644 index 37ec88a..0000000 --- a/src/model/model.qbs +++ /dev/null @@ -1,15 +0,0 @@ -import qbs - -PSLibrary { - Depends { name: "Qt"; submodules: "core", "sql"} - - Depends { name: "sql_builder" } - - Group { - name: "cpp" - files: [ - "*.h", - "*.cpp" - ] - } -} diff --git a/src/repositories/author_repository.cpp b/src/repositories/author_repository.cpp deleted file mode 100644 index 6c54d7c..0000000 --- a/src/repositories/author_repository.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// #define BUILD_REPOSITORIES -#include "author_repository.h" - -#include -#include - -#include - -QVector AuthorRepository::getAll() -{ - QVector authors; - - Builder::Select sBuilder({ .tableName = model::authorconst::TABLE, .rows = { model::authorconst::ID, model::authorconst::NAME } }); - QSqlQuery query(sBuilder.get()); - - qDebug() << query.lastError().text(); - - while (query.next()) - { - authors.append({ query.value(0).toInt(), - query.value(1).toString() }); - } - - return authors; -} - -std::optional AuthorRepository::getByName(const QString& name) -{ - Q_UNUSED(name); - Builder::Select sBuilder({ .tableName = model::authorconst::TABLE, .rows = { model::authorconst::ID, model::authorconst::NAME } }); - QString qResult = sBuilder.get() + QString(" WHERE %1 = \"%2\"").arg(model::authorconst::NAME).arg(name); - - QSqlQuery query(qResult); - - if (query.next()) - { - model::Author author({ .id = query.value(0).toInt(), - .name = query.value(1).toString() }); - return { author }; - } - - return std::nullopt; -} - -bool AuthorRepository::insert(const model::Author& author) -{ - QSqlQuery query(DatabaseManager::instance().database()); - Builder::Insert iBuild({ model::authorconst::TABLE, - { model::authorconst::NAME }, - true }); - - query.prepare(iBuild.get()); - query.bindValue(":name", author.name); - int authorId = 0; - Q_UNUSED(authorId); - - if (!query.exec()) - { - qDebug() << query.lastError().text(); - if (query.lastError().nativeErrorCode() == 19) - { - // Автор уже есть, ищем его ID - QSqlQuery findQuery(DatabaseManager::instance().database()); - findQuery.prepare("SELECT id FROM authors WHERE name = :name"); - findQuery.bindValue(":name", author.name); - if (findQuery.exec() && findQuery.next()) - { - authorId = findQuery.value(0).toInt(); - return true; - } - } - qCritical() << "Ошибка добавления автора:" << query.lastError().text(); - return false; - } - - authorId = query.lastInsertId().toInt(); - return true; -} diff --git a/src/repositories/author_repository.h b/src/repositories/author_repository.h deleted file mode 100644 index 4cfaa75..0000000 --- a/src/repositories/author_repository.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef BUILD_REPOSITORIES -#define REPOSITORIES_EXPORT Q_DECL_EXPORT -#else -#define REPOSITORIES_EXPORT Q_DECL_IMPORT -#endif - -class REPOSITORIES_EXPORT AuthorRepository -{ -public: - static QVector getAll(); - static std::optional getByName(const QString& name); - static bool insert(const model::Author& author); - - // TODO Возвращать не bool - а номер id записи -}; diff --git a/src/repositories/book_repository.cpp b/src/repositories/book_repository.cpp deleted file mode 100644 index 9c621dd..0000000 --- a/src/repositories/book_repository.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// #define BUILD_REPOSITORIES -#include "book_repository.h" - -#include -#include - -#include -#include - -QVector BookRepository::getAll() -{ - QVector books; - Builder::Select qBuilder { - model::bookconst::TABLE, - { model::bookconst::ID, - model::bookconst::TITLE, - model::bookconst::AUTHOR_ID, - model::bookconst::FILEPATH } - }; - - QSqlQuery query(qBuilder.get()); - - qDebug() << query.lastError().text(); - - while (query.next()) - { - books.append({ query.value(0).toInt(), - query.value(1).toString(), - { query.value(2).toInt() }, - query.value(3).toString() }); - } - - // TODO получить так же авторов как строку - - return books; -} - -bool BookRepository::insert(const model::Book& book) -{ - QSqlQuery query(DatabaseManager::instance().database()); - - Builder::Insert iBuilder { - model::bookconst::TABLE, - { model::bookconst::TITLE, - model::bookconst::FILEPATH, - model::bookconst::AUTHOR_ID } - }; - - query.prepare(iBuilder.get()); - query.bindValue(":" + model::bookconst::TITLE, book.title); - query.bindValue(":" + model::bookconst::FILEPATH, book.filePath); - query.bindValue(":" + model::bookconst::AUTHOR_ID, book.author.id); - - bool res = query.exec(); - if (!res) - qDebug() << query.lastError().text(); - - return res; -} diff --git a/src/repositories/book_repository.h b/src/repositories/book_repository.h deleted file mode 100644 index 2454a5f..0000000 --- a/src/repositories/book_repository.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -#include - -#include -#include -#include - -#ifdef BUILD_REPOSITORIES -#define REPOSITORIES_EXPORT Q_DECL_EXPORT -#else -#define REPOSITORIES_EXPORT Q_DECL_IMPORT -#endif - -class REPOSITORIES_EXPORT BookRepository -{ -public: - static QVector getAll(); - static bool insert(const model::Book& book); -}; diff --git a/src/repositories/repositories.qbs b/src/repositories/repositories.qbs deleted file mode 100644 index 877e100..0000000 --- a/src/repositories/repositories.qbs +++ /dev/null @@ -1,21 +0,0 @@ -import qbs - -PSLibrary { - Depends { name: "Qt"; submodules: "core", "sql"} - - Depends { name: "database" } - Depends { name: "sql_builder" } - - Group { - name: "cpp" - files: [ - "*.h", - "*.cpp" - ] - } - - Properties { - condition: qbs.buildVariant === "debug" - cpp.defines: ["BUILD_REPOSITORIES"] - } -} diff --git a/src/restapi/restapi.qbs b/src/restapi/restapi.qbs index d7efb54..cdce2c0 100644 --- a/src/restapi/restapi.qbs +++ b/src/restapi/restapi.qbs @@ -1,15 +1,38 @@ -import qbs +/*! + \qmltype cpp-opds + \inherits Project + \brief Описание +*/ +WPSLibrary { + cpp.defines: [ + // You can make your code fail to compile if it uses deprecated APIs. + // In order to do so, uncomment the following line. + //"QT_DISABLE_DEPRECATED_BEFORE=0x060000" // disables all the APIs deprecated before Qt 6.0.0 + "DATABASE_SQLITE" + ] + consoleApplication: true -PSLibrary { - Depends { name: "Qt"; submodules: ["core", "sql", "network"] } + Depends { name: "Qt"; submodules: [ "core", "sql", "network" ] } + Depends { name: "cpp" } + Depends { name: "database" } + Depends { name: "odb.gen" } + Depends { name: "redkit_gen" } + Depends { name: "rdbase" } - Depends { name: "services" } + cpp.cxxLanguageVersion: "c++20" Group { name: "cpp" files: [ - "*.h", - "*.cpp" + "restapiserver.*", ] } -} + + cpp.dynamicLibraries: [ + "odb-sqlite", + "odb-qt", + "odb", + "sqlite3" + ] + +} // Project diff --git a/src/restapi/restapiserver.cpp b/src/restapi/restapiserver.cpp index 7124518..3f7ff75 100644 --- a/src/restapi/restapiserver.cpp +++ b/src/restapi/restapiserver.cpp @@ -1,15 +1,23 @@ #include "restapiserver.h" -#include -#include - #include #include #include #include -RestApiServer::RestApiServer(QObject* parent) : - QTcpServer(parent) {} +#include // Должен быть здесь +#include +#include // Должен быть здесь +#include + +#include +#include +#include + +#include + +RestApiServer::RestApiServer(odb::database& db, QObject* parent) : + QTcpServer(parent), m_db(db) {} void RestApiServer::start(quint16 port) { @@ -19,7 +27,7 @@ void RestApiServer::start(quint16 port) } else { - qDebug() << "REST API сервер запущен на порту:" << port; + qDebug() << "REST API сервер запущен по адресу:"; qDebug() << QString("http://127.0.0.1:%1").arg(port); } } @@ -31,6 +39,8 @@ void RestApiServer::incomingConnection(qintptr socketDescriptor) connect(socket, &QTcpSocket::readyRead, this, &RestApiServer::handleRequest); connect(socket, &QTcpSocket::disconnected, socket, &QTcpSocket::deleteLater); + + qWarning() << "Есть входящее подключение" << socket->socketDescriptor(); } void RestApiServer::handleRequest() @@ -49,70 +59,80 @@ void RestApiServer::handleRequest() QByteArray RestApiServer::processRequest(const QString& request) { + // qWarning() << request << "\n\n"; + if (request.startsWith("GET /books/author/")) { QString author = request.section(' ', 1, 1).section('/', 3, 3).replace("%20", " "); + quint64 ageReq = author.toInt(); - // Books books; - // QList results = books.getBooksByAuthor(author); + QStringList nameParts = author.split(' '); + QString firstName = nameParts.size() > 0 ? nameParts[0] : ""; + QString lastName = nameParts.size() > 1 ? nameParts[1] : ""; - QByteArray jsonResponse = "{ \"books\": ["; - // for (const BookRecord& book : results) - // { - // jsonResponse += QString("{ \"id\": %1, \"title\": \"%2\", \"author\": \"%3\", \"year\": %4 },") - // .arg(book.id) - // .arg(book.title) - // .arg(book.author) - // .arg(book.year) - // .toUtf8(); - // } - // if (results.size() > 0) - // jsonResponse.chop(1); // Убираем последнюю запятую - // jsonResponse += "] }"; + odb::transaction t(m_db.begin()); - return "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n" + jsonResponse; + auto books = m_db.query(odb::query::author->id == ageReq); + + QJsonArray jArray; + for (const auto& book : books) + { + QJsonObject j; + j["id"] = QString::number(book.id()); + j["name"] = book.name(); + j["author"] = book.author()->full_name(); + j["year"] = book.year(); + jArray.push_back(j); + } + auto jDoc = QJsonDocument(jArray); + + t.commit(); + + return "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n" + jDoc.toJson(QJsonDocument::Indented); } if (request.startsWith("GET /books")) { - auto books = BookService::fetchAll(); + odb::transaction t(m_db.begin()); + odb::result res(m_db.query()); QJsonArray jArray; - - for (auto it = books.begin(); it != books.end(); ++it) + for (auto it = res.begin(); it != res.end(); ++it) { const auto& book = *it; QJsonObject j; - j["id"] = QString::number(book.id); - j["title"] = QString(book.title); - j["author"] = QString(book.author.name); - j["local_path"] = book.filePath; + j["id"] = QString::number(book.id()); + j["title"] = book.name(); + j["author"] = book.author()->full_name(); + j["year"] = book.year(); jArray.push_back(j); } auto jDoc = QJsonDocument(jArray); + t.commit(); return "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n" + jDoc.toJson(QJsonDocument::Indented); } if (request.startsWith("GET /author")) { - // auto books = BookService::fetchAll(); - auto authors = AuthorService::fetchAll(); + odb::transaction t(m_db.begin()); + odb::result res(m_db.query()); QJsonArray jArray; - for (auto it = authors.begin(); it != authors.end(); ++it) + for (auto it = res.begin(); it != res.end(); ++it) { const auto& author = *it; QJsonObject j; - j["id"] = QString::number(author.id); - j["name"] = QString(author.name); - // j["last"] = QString::fromStdString(author.last()); - // j["age"] = author.age(); + j["id"] = QString::number(author.id()); + j["first"] = author.firstName(); + j["last"] = author.lastName(); + j["age"] = author.age(); jArray.push_back(j); } auto jDoc = QJsonDocument(jArray); + t.commit(); return "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n" + jDoc.toJson(QJsonDocument::Indented); } diff --git a/src/restapi/restapiserver.h b/src/restapi/restapiserver.h index 5f8998b..a742100 100644 --- a/src/restapi/restapiserver.h +++ b/src/restapi/restapiserver.h @@ -1,6 +1,9 @@ #ifndef RESTAPISERVER_H #define RESTAPISERVER_H +#include + +#include #include #include @@ -8,7 +11,7 @@ class Q_DECL_EXPORT RestApiServer : public QTcpServer { Q_OBJECT public: - explicit RestApiServer(QObject* parent = nullptr); + explicit RestApiServer(odb::core::database& db, QObject* parent = nullptr); void start(quint16 port = 8080); protected: @@ -19,6 +22,8 @@ private slots: private: QByteArray processRequest(const QString& request); + + odb::core::database& m_db; }; #endif // RESTAPISERVER_H diff --git a/src/services/author_service.cpp b/src/services/author_service.cpp deleted file mode 100644 index 39a2c01..0000000 --- a/src/services/author_service.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// #define BUILD_SERVICES -#include "author_service.h" - -QVector AuthorService::fetchAll() -{ - return AuthorRepository::getAll(); -} - -bool AuthorService::add(const model::Author& author) -{ - return AuthorRepository::insert(author); -} diff --git a/src/services/author_service.h b/src/services/author_service.h deleted file mode 100644 index 97288ed..0000000 --- a/src/services/author_service.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -#include - -#include - -#ifdef BUILD_SERVICES -#define SERVICES_EXPORT Q_DECL_EXPORT -#else -#define SERVICES_EXPORT Q_DECL_IMPORT -#endif - -class SERVICES_EXPORT AuthorService -{ -public: - static QVector fetchAll(); - static bool add(const model::Author& name); -}; diff --git a/src/services/book_service.cpp b/src/services/book_service.cpp deleted file mode 100644 index ca32b3b..0000000 --- a/src/services/book_service.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// #define BUILD_SERVICES -#include "book_service.h" -#include "author_service.h" - -QVector BookService::fetchAll() -{ - return BookRepository::getAll(); -} - -bool BookService::add(const model::Book& book) -{ - auto res = AuthorRepository::getByName(book.author.name); - - if (!res.has_value()) - { - if (!AuthorService::add(book.author)) - { - qCritical() << "Ошибка добавления автора!"; - return false; - } - - res = AuthorRepository::getByName(book.author.name); - } - - model::Book BookAuthor = book; - BookAuthor.author = res.value(); - return BookRepository::insert(BookAuthor); -} diff --git a/src/services/book_service.h b/src/services/book_service.h deleted file mode 100644 index cddc97b..0000000 --- a/src/services/book_service.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -#include - -#include - -#ifdef BUILD_SERVICES -#define SERVICES_EXPORT Q_DECL_EXPORT -#else -#define SERVICES_EXPORT Q_DECL_IMPORT -#endif - -class SERVICES_EXPORT BookService -{ -public: - static QVector fetchAll(); - static bool add(const model::Book& book); -}; diff --git a/src/services/services.qbs b/src/services/services.qbs deleted file mode 100644 index 60fecf4..0000000 --- a/src/services/services.qbs +++ /dev/null @@ -1,22 +0,0 @@ -import qbs - -PSLibrary { - Depends { name: "Qt"; submodules: "core", "sql"} - - Depends { name: "repositories" } - - Group { - name: "cpp" - files: [ - "*.h", - "*.cpp" - ] - } - - - - Properties { - condition: qbs.buildVariant === "debug" - cpp.defines: ["BUILD_SERVICES"] - } -} diff --git a/src/sql_builder/create_table.cpp b/src/sql_builder/create_table.cpp deleted file mode 100644 index 82c5884..0000000 --- a/src/sql_builder/create_table.cpp +++ /dev/null @@ -1,45 +0,0 @@ -#include "create_table.h" - -#include - -namespace Builder -{ - -QString Column::toSQL() const -{ - QString columnDef = name + " " + type; - if (primaryKey) - columnDef += " PRIMARY KEY"; - if (notNull) - columnDef += " NOT NULL"; - if (unique) - columnDef += " UNIQUE"; - if (defaultValue) - columnDef += " DEFAULT " + *defaultValue; - if (foreignKeyTable && foreignKeyColumn) - { - columnDef += " REFERENCES " + *foreignKeyTable + "(" + *foreignKeyColumn + ")"; - } - return columnDef; -} - -TableSchema& TableSchema::addColumn(const Column& column) -{ - columns.push_back(column); - return *this; -} - -QString TableSchema::get() const -{ - QStringList columnDefs; - for (const auto& col : columns) - { - columnDefs.append(col.toSQL()); - } - - QString result = "CREATE TABLE IF NOT EXISTS " + name + " ( " + columnDefs.join(", ") + " );"; - // qDebug() << result; - return result; -} - -} // namespace Builder diff --git a/src/sql_builder/create_table.h b/src/sql_builder/create_table.h deleted file mode 100644 index 239c40c..0000000 --- a/src/sql_builder/create_table.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -namespace Builder -{ - -struct Column -{ - QString name; // Имя колонки - QString type; // Тип колонки - bool primaryKey = false; // Является ли колонка первичным ключом? - bool notNull = false; // Колонка не должна быть пуста - bool unique = false; // Значение в колонке должны быть уникальны - std::optional defaultValue; - std::optional foreignKeyTable; - std::optional foreignKeyColumn; - - /*! - * \brief Сформировать SQL код для колонки - */ - QString toSQL() const; -}; - -class Q_DECL_EXPORT TableSchema -{ -public: - TableSchema(QString tableName) : - name(std::move(tableName)) {} - - /*! - * \brief Добавить колонку - */ - TableSchema& addColumn(const Column& column); - - /*! - * \brief Сформировать SQL код для создания таблицы - */ - QString get() const; - -private: - QString name; // Имя таблицы - QVector columns; // Список колонок таблицы -}; - -} // namespace Builder diff --git a/src/sql_builder/insert.cpp b/src/sql_builder/insert.cpp deleted file mode 100644 index 80384b3..0000000 --- a/src/sql_builder/insert.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "insert.h" - -#include - -namespace Builder -{ - -namespace -{ - -const QString INSERT = QStringLiteral("INSERT"); -const QString INTO = QStringLiteral("INTO"); -const QString VALUES = QStringLiteral("VALUES"); -const QString IGNORE = QStringLiteral("IGNORE"); - -} - -QString Insert::get() const -{ - QString resultString = QString("%1 ").arg(INSERT); - if (orIgnore) - resultString += QString("OR %1 ").arg(IGNORE); - resultString += QString("%1 %2 ").arg(INTO).arg(tableName); - - resultString += QString("( %1 ) ").arg(rows.join(", ")); - - // TODO как будто бы проще сразу это заполнить значениями - QStringList allValue; - for (const auto& row : rows) - allValue.push_back(QString(":%1").arg(row)); - - resultString += QString("%1 ( %2 )").arg(VALUES).arg(allValue.join(", ")); - - resultString += ';'; - // qDebug() << resultString; - return resultString; -} - -} // namespace Builder diff --git a/src/sql_builder/insert.h b/src/sql_builder/insert.h deleted file mode 100644 index b53cec1..0000000 --- a/src/sql_builder/insert.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include -#include - -namespace Builder -{ - -struct Q_DECL_EXPORT Insert -{ - QString tableName; // Имя таблицы - QStringList rows; // Именования колонок - // QStringList params; - bool orIgnore = false; - - /*! - * \brief Сформировать SQL код для выполнения - */ - QString get() const; -}; - -} // namespace Builder diff --git a/src/sql_builder/select.cpp b/src/sql_builder/select.cpp deleted file mode 100644 index 880609e..0000000 --- a/src/sql_builder/select.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include "select.h" - -#include - -namespace Builder -{ - -namespace -{ - -const QString SELECT = QStringLiteral("SELECT"); -const QString FROM = QStringLiteral("FROM"); -const QString WHERE = QStringLiteral("WHERE"); - -} - -QString Select::get() const -{ - QString allRows = rows.join(", "); - - QString resultString = QString("%1 %2").arg(SELECT).arg(allRows); - - resultString += QString(" %1 %2").arg(FROM).arg(tableName); - - if (!where.isEmpty()) - resultString += QString(" %1 %2").arg(WHERE).arg(where); - - // resultString += ';'; - return resultString; -} - -} // namespace Builder diff --git a/src/sql_builder/select.h b/src/sql_builder/select.h deleted file mode 100644 index a3fe574..0000000 --- a/src/sql_builder/select.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include -#include - -namespace Builder -{ - -struct Q_DECL_EXPORT Select -{ - QString tableName; // Имя таблицы - QStringList rows = { "*" }; // Колонки - QString where = {}; // Условие поиска - - /*! - * \brief Сформировать SQL код для выполнения - */ - QString get() const; -}; - -} // namespace Builder diff --git a/src/sql_builder/sql_builder.qbs b/src/sql_builder/sql_builder.qbs deleted file mode 100644 index d03417d..0000000 --- a/src/sql_builder/sql_builder.qbs +++ /dev/null @@ -1,14 +0,0 @@ -import qbs - -PSLibrary { - Depends { name: "Qt"; submodules: "sql"} - - - Group { - name: "cpp" - files: [ - "**/*.h", - "**/*.cpp" - ] - } -}