diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..cc5a562 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "redkbuild"] + path = redkbuild + url = ssh://git@gitea.redkit-lab.work:57322/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 11f7f19..d717770 100644 --- a/project.qbs +++ b/project.qbs @@ -3,17 +3,18 @@ import qbs Project { name: "opds++" qbsSearchPaths: [ - "qbs", - // "redkitty/qbs", - // // "guiness/qbs", - // // "prerequisites/qbs", - // // "report/qbs", - // "redkbuild", - // // "ext_libs/openssl/qbs", - // "redkitty/lib/redkit-gen-integration/qbs", + "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", ] } diff --git a/qbs/modules/odbModule/odbModule.qbs b/qbs/modules/odbModule/odbModule.qbs deleted file mode 100644 index 0cd4980..0000000 --- a/qbs/modules/odbModule/odbModule.qbs +++ /dev/null @@ -1,48 +0,0 @@ -import qbs -import qbs.FileInfo - -Module { - Depends { name: "cpp" } - Depends { name: "Qt.core" } - - FileTagger { - patterns: "*.hxx" - fileTags: ["odb"] - } - - Rule { - inputs: ["odb"] - Artifact { - // filePath: FileInfo.baseName(input.fileName)+ "-odb.hxx" - filePath: FileInfo.cleanPath(input.filePath + "/../" ) + "/" + FileInfo.baseName(input.fileName) + "-odb.hxx" - fileTags: ["hpp"] - } - Artifact { - // filePath: FileInfo.baseName(input.fileName) + "-odb.cxx" - filePath: { - // console.error("THIS ART "+FileInfo.cleanPath(input.filePath + "/../") + "/" + FileInfo.baseName(input.fileName) + "-odb.cxx") - return FileInfo.cleanPath(input.filePath + "/../") + "/" + FileInfo.baseName(input.fileName) + "-odb.cxx"} - fileTags: ["cpp"] - } - - prepare: { - var cmd = new Command("odb", [ - "--std", "c++11", - "-d", "sqlite", - "--generate-query", - "--generate-schema", - "--generate-prepared", - // "--include-prefix", FileInfo.cleanPath(input.filePath + "/../"), - // "--output-dir", product.Qt.core.qmDir, - "--output-dir", FileInfo.cleanPath(input.filePath + "/../"), - input.filePath, - ]); - cmd.description = "Generating ODB files for " + input.fileName; - - console.error(cmd.arguments) - - return [cmd]; - } - } - cpp.includePaths: [ project.sourceDirectory, product.Qt.core.qmDir ] -} diff --git a/redkbuild b/redkbuild new file mode 160000 index 0000000..3adf92a --- /dev/null +++ b/redkbuild @@ -0,0 +1 @@ +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/book_s.h b/src/book_s.h deleted file mode 100644 index bb34c7b..0000000 --- a/src/book_s.h +++ /dev/null @@ -1,46 +0,0 @@ -// file : hello/person.hxx -// copyright : not copyrighted - public domain - -#ifndef BOOK_S_H -#define BOOK_S_H - -#include -#include - -#include - -#include "author_s.h" - -#pragma db object -class Book_S -{ -public: - Book_S() = default; - - Book_S(const std::string& name, - const std::shared_ptr& author, - const int year) - { - m_author = author; - m_name = name; - m_year = year; - }; - - unsigned long long id() const { return m_id; } - std::shared_ptr author() const { return m_author; } - std::string name() const { return m_name; } - int year() const { return m_year; } - -private: - friend class odb::access; - -private: -#pragma db id auto - unsigned long long m_id; - - std::shared_ptr m_author; - std::string m_name; - int m_year; -}; - -#endif // BOOK_S_H diff --git a/src/cpp-opds.qbs b/src/cpp-opds.qbs index bea1d78..ae24c6d 100644 --- a/src/cpp-opds.qbs +++ b/src/cpp-opds.qbs @@ -3,7 +3,7 @@ \inherits Project \brief Описание */ -Application { +PSApplication { // CppApplication { cpp.defines: [ // You can make your code fail to compile if it uses deprecated APIs. @@ -15,44 +15,28 @@ Application { Depends { name: "Qt"; submodules: [ "core", "sql", "network" ] } Depends { name: "cpp" } - Depends { name: "odbModule"} - - // Depends { name: "redkit_gen" } + 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: [ - "books.*", - "databasemanager.*", "main.cpp", - "restapiserver.*", ] } - Group { - name: "odb" - files: [ - "author_s.h", - "book_s.h", - ] - fileTags: ["odb"] - } - - cpp.includePaths: [ - "/usr/include", // Общие заголовки - "/usr/include/odb" // Заголовки ODB - ] - - // Подключаем библиотеки ODB - cpp.libraryPaths: [ - "/usr/lib" // Путь к библиотекам - ] - cpp.dynamicLibraries: [ + "odb-sqlite", + "odb-qt", "odb", - "odb-sqlite" + "sqlite3" ] + // } } // Project diff --git a/src/author_s.h b/src/database/author_s.h similarity index 64% rename from src/author_s.h rename to src/database/author_s.h index 0dc1949..5451fba 100644 --- a/src/author_s.h +++ b/src/database/author_s.h @@ -4,47 +4,48 @@ #ifndef AUTHOR_S_H #define AUTHOR_S_H -#include // std::size_t -#include -#include +#include "database_global.h" + +#include #include #include #include #pragma db object -class Author_S +class DATABASE_EXPORT Author_S { public: Author_S() = default; - Author_S(const std::string& first, - const std::string& last, + Author_S(const QString& firstN, + const QString& lastN, const unsigned short age) : - m_first(first), - m_last(last), + m_firstName(firstN), + m_lastName(lastN), m_age(age) { } unsigned long long id() const { return m_id; } - std::string first() const { return m_first; } - std::string last() const { return m_last; } + QString firstName() const { return m_firstName; } + QString lastName() const { return m_lastName; } unsigned short age() const { return m_age; } - std::string full_name() const { return m_first + " " + m_last; } + 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 - unsigned long long m_id; + quint64 m_id; - std::string m_first; - std::string m_last; - unsigned short m_age; + QString m_firstName; + QString m_lastName; + quint8 m_age; }; #pragma db view object(Author_S) 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.hxx b/src/database/database.hxx similarity index 85% rename from src/database.hxx rename to src/database/database.hxx index 8961f54..a33e812 100644 --- a/src/database.hxx +++ b/src/database/database.hxx @@ -34,16 +34,20 @@ #include #include +#include + +using oDBase = odb::sqlite::database; +using uDBase = U; struct testData { - std::string first; - std::string last; + QString first; + QString last; int age; }; // Функция для генерации случайной строки (имени или фамилии) -std::string generate_random_string(const std::vector& pool) +QString generate_random_string(const QVector& pool) { static std::random_device rd; static std::mt19937 gen(rd()); @@ -60,16 +64,16 @@ int generate_random_year(int min_year = 1900, int max_year = 2020) return dis(gen); } -std::vector fillDB() +QVector fillDB() { - std::vector first_names = { + 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" }; - std::vector last_names = { + 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", @@ -77,12 +81,12 @@ std::vector fillDB() "Rogers", "Gutierrez", "Ramirez", "Diaz", "Perez", "Ross", "Sanders", "Price", "Howard", "Cooper" }; - std::vector vecTest; + QVector vecTest; for (int i = 0; i < 50; ++i) { - std::string first_name = generate_random_string(first_names); - std::string last_name = generate_random_string(last_names); + 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 }); @@ -91,21 +95,23 @@ std::vector fillDB() return vecTest; } -inline std::unique_ptr openDB(std::string path_db) +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 std::unique_ptr(new odb::sqlite::database(path_db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)); + return uDBase(db_ptr); // И создать новую, если не существует - std::unique_ptr db(new odb::sqlite::database(path_db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE)); + uDBase db(db_ptr); - odb::core::connection_ptr connect_ptr(db->connection()); + odb::connection_ptr connect_ptr(db->connection()); connect_ptr->execute("PRAGMA foreign_keys=OFF"); - odb::core::transaction tans(db->begin()); - odb::core::schema_catalog::create_schema(*db); + odb::transaction tans(db->begin()); + odb::schema_catalog::create_schema(*db); tans.commit(); connect_ptr->execute("PRAGMA foreign_keys=ON"); diff --git a/src/database/database.qbs b/src/database/database.qbs new file mode 100644 index 0000000..349b198 --- /dev/null +++ b/src/database/database.qbs @@ -0,0 +1,55 @@ +/*! + \qmltype cpp-opds + \inherits Project + \brief Описание +*/ +PSLibrary { + 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: "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: [ + "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/databasemanager.cpp b/src/database/databasemanager.cpp similarity index 100% rename from src/databasemanager.cpp rename to src/database/databasemanager.cpp diff --git a/src/databasemanager.h b/src/database/databasemanager.h similarity index 94% rename from src/databasemanager.h rename to src/database/databasemanager.h index f7be5ad..9e7530e 100644 --- a/src/databasemanager.h +++ b/src/database/databasemanager.h @@ -1,6 +1,8 @@ #ifndef DATABASEMANAGER_H #define DATABASEMANAGER_H +#include "database_global.h" + #include #include @@ -35,7 +37,7 @@ struct SelectBuilder } }; -class DatabaseManager +class DATABASE_EXPORT DatabaseManager { public: static DatabaseManager& instance(); // Singleton diff --git a/src/main.cpp b/src/main.cpp index 7d8945b..64d7771 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,48 +1,50 @@ #include -#include "restapiserver.h" +#include +#include +#include +#include + +#include /* Опыты с odb */ -#include "author_s-odb.hxx" // Должен быть здесь -#include "author_s.h" - -#include "book_s-odb.hxx" // Должен быть здесь -#include "book_s.h" - +#include // Должен быть здесь +#include +#include // Должен быть здесь +#include +#include // create_database #include -#include "database.hxx" // create_database +#include -using unidb = std::unique_ptr; - -void fillBooksBD(unidb& db) +void fillBooksBD(uDBase& db) { try { - std::vector> authors = { - std::make_shared("George", "Orwell", 142), - std::make_shared("J.K.", "Rowling", 56), - std::make_shared("J.R.R.", "Tolkien", 81), - std::make_shared("Leo", "Tolstoy", 189), - std::make_shared("Fyodor", "Dostoevsky", 174), - std::make_shared("Mark", "Twain", 183), - std::make_shared("Charles", "Dickens", 208), - std::make_shared("Virginia", "Woolf", 134), - std::make_shared("Ernest", "Hemingway", 122), - std::make_shared("Gabriel", "García Márquez", 98), - std::make_shared("Franz", "Kafka", 100), - std::make_shared("Harper", "Lee", 64), - std::make_shared("William", "Shakespeare", 459), - std::make_shared("Oscar", "Wilde", 155), - std::make_shared("Aldous", "Huxley", 123), - std::make_shared("Jane", "Austen", 210), - std::make_shared("John", "Steinbeck", 116), - std::make_shared("Agatha", "Christie", 124), - std::make_shared("Isaac", "Asimov", 105) + 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) }; // Список книг - std::vector books = { + 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), @@ -99,7 +101,7 @@ void fillBooksBD(unidb& db) { odb::core::transaction t(db->begin()); for (auto& author : authors) - db->persist(author.get()); // Используем get() для получения сырого указателя + db->persist(author); // Используем get() для получения сырого указателя t.commit(); } @@ -124,8 +126,9 @@ int main(int argc, char* argv[]) QCoreApplication a(argc, argv); const std::string dbPath = "test_db.sqlite"; - std::unique_ptr db(openDB(dbPath)); + uDBase db(openDB(dbPath)); + // TODO Как-то нужно выполнять лишь раз // fillBooksBD(db); RestApiServer server(*db); diff --git a/src/restapi/restapi.qbs b/src/restapi/restapi.qbs new file mode 100644 index 0000000..cdce2c0 --- /dev/null +++ b/src/restapi/restapi.qbs @@ -0,0 +1,38 @@ +/*! + \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 + + Depends { name: "Qt"; submodules: [ "core", "sql", "network" ] } + Depends { name: "cpp" } + Depends { name: "database" } + Depends { name: "odb.gen" } + Depends { name: "redkit_gen" } + Depends { name: "rdbase" } + + cpp.cxxLanguageVersion: "c++20" + + Group { + name: "cpp" + files: [ + "restapiserver.*", + ] + } + + cpp.dynamicLibraries: [ + "odb-sqlite", + "odb-qt", + "odb", + "sqlite3" + ] + +} // Project diff --git a/src/restapiserver.cpp b/src/restapi/restapiserver.cpp similarity index 61% rename from src/restapiserver.cpp rename to src/restapi/restapiserver.cpp index bdde6dd..22ee409 100644 --- a/src/restapiserver.cpp +++ b/src/restapi/restapiserver.cpp @@ -5,15 +5,19 @@ #include #include -#include "book_s-odb.hxx" -#include "book_s.h" +#include // Должен быть здесь +#include +#include // Должен быть здесь +#include #include #include #include +#include + RestApiServer::RestApiServer(odb::database& db, QObject* parent) : - m_db(db), QTcpServer(parent) {} + QTcpServer(parent), m_db(db) {} void RestApiServer::start(quint16 port) { @@ -23,7 +27,8 @@ void RestApiServer::start(quint16 port) } else { - qDebug() << "REST API сервер запущен на порту:" << port; + QString addrs = "http://127.0.0.1:" + QString::number(this->serverPort()); + qDebug() << "REST API сервер запущен по адресу:" << addrs; } } @@ -34,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() @@ -52,28 +59,41 @@ 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 += "] }"; + qWarning() + << "author:" << author << "\n" + << "firstName:" << firstName << "\n" + << "lastName:" << lastName << "\n"; - return "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n" + jsonResponse; + odb::transaction t(m_db.begin()); + + 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")) @@ -89,8 +109,8 @@ QByteArray RestApiServer::processRequest(const QString& request) QJsonObject j; j["id"] = QString::number(book.id()); - j["title"] = QString::fromStdString(book.name()); - j["author"] = QString::fromStdString(book.author()->full_name()); + j["title"] = book.name(); + j["author"] = book.author()->full_name(); j["year"] = book.year(); jArray.push_back(j); } @@ -114,8 +134,8 @@ QByteArray RestApiServer::processRequest(const QString& request) QJsonObject j; j["id"] = QString::number(author.id()); - j["first"] = QString::fromStdString(author.first()); - j["last"] = QString::fromStdString(author.last()); + j["first"] = author.firstName(); + j["last"] = author.lastName(); j["age"] = author.age(); jArray.push_back(j); } diff --git a/src/restapiserver.h b/src/restapi/restapiserver.h similarity index 87% rename from src/restapiserver.h rename to src/restapi/restapiserver.h index 33232d9..a742100 100644 --- a/src/restapiserver.h +++ b/src/restapi/restapiserver.h @@ -3,10 +3,11 @@ #include +#include #include #include -class RestApiServer : public QTcpServer +class Q_DECL_EXPORT RestApiServer : public QTcpServer { Q_OBJECT public: