Kaynağa Gözat

Добавлено чтение из базы

Denis V. Dedkov 2 ay önce
ebeveyn
işleme
c97a487057
6 değiştirilmiş dosya ile 233 ekleme ve 1 silme
  1. 2 1
      .gitignore
  2. 36 0
      CMakeLists.txt
  3. 17 0
      Dockerfile
  4. 58 0
      main.cpp
  5. 93 0
      sqlitedb.cpp
  6. 27 0
      sqlitedb.h

+ 2 - 1
.gitignore

@@ -27,7 +27,8 @@ Makefile*
 *-build-*
 
 # QtCreator
-
+.qtcreator
+/build
 *.autosave
 
 #QtCtreator Qml

+ 36 - 0
CMakeLists.txt

@@ -0,0 +1,36 @@
+cmake_minimum_required(VERSION 3.19)
+
+project(beer_notes_srv LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+add_executable(beer_notes_srv
+  main.cpp
+  sqlitedb.h sqlitedb.cpp
+)
+
+include(FetchContent)
+
+# cpp-httplib
+FetchContent_Declare(
+  httplib
+  GIT_REPOSITORY https://gitea.dended.ru/ded/cpp-httplib.git
+  GIT_TAG master
+)
+FetchContent_MakeAvailable(httplib)
+
+find_package(SQLite3 REQUIRED)
+
+target_link_libraries(beer_notes_srv
+    PRIVATE
+        httplib
+        SQLite::SQLite3
+)
+
+include(GNUInstallDirs)
+
+install(TARGETS beer_notes_srv
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)

+ 17 - 0
Dockerfile

@@ -0,0 +1,17 @@
+FROM docker.dended.ru/cpp-builder:latest AS builder
+LABEL stage=builder
+
+WORKDIR /build
+COPY . .
+
+RUN cmake CMakeLists.txt -DCMAKE_GENERATOR:STRING=Ninja -DCMAKE_BUILD_TYPE:STRING=MinSizeRel -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-20 && cmake --build . --target all
+
+FROM scratch
+
+COPY --from=builder /build/beer_notes_srv /bin/beer_notes_srv
+COPY --from=builder /lib/ld-musl-* /lib/
+COPY --from=builder /usr/lib/libsqlite3.so /usr/lib/libsqlite3.so
+COPY --from=builder /usr/lib/libstdc++.so.6 /usr/lib/libstdc++.so.6
+COPY --from=builder /usr/lib/libgcc_s.so.1 /usr/lib/libgcc_s.so.1
+
+CMD ["/bin/beer_notes_srv"]

+ 58 - 0
main.cpp

@@ -0,0 +1,58 @@
+#include <httplib.h>
+#include <iostream>
+
+#include "sqlitedb.h"
+
+namespace App {
+
+constexpr auto DefaultPort = 8888;
+constexpr auto DefaultHost = "0.0.0.0";
+constexpr auto ContentType = "application/json";
+
+static httplib::Server *srv = nullptr;
+
+} // namespace App
+
+void signalHandler(int signum)
+{
+    std::cout << "\n\nInterrupt signal (" << signum << ") received.\n" << std::endl;
+
+    if (App::srv) {
+        App::srv->stop();
+        delete App::srv;
+    }
+
+    exit(signum);
+}
+
+int main(int argc, char *argv[])
+{
+    std::signal(SIGINT, signalHandler);
+
+    App::srv = new httplib::Server();
+
+    SqliteDb db("beer.db");
+
+    auto read_table = [&db](const httplib::Request& req, httplib::Response& res) {
+        auto table = req.path_params.at("table");
+
+        std::vector< SqliteDb::Param> params;
+        for (const auto& [param, value] : req.params)
+        {
+            params.push_back({ param, value });
+        }
+
+        res.set_content("Table: " + db.readTable( table, params ), "text/plain");
+    };
+
+    App::srv->Get("/table/:table", read_table);
+
+    auto host = argc > 1 ? argv[1] : App::DefaultHost;
+    auto port = argc > 2 ? atoi(argv[2]) : App::DefaultPort;
+
+    std::cout << "Listen on " << host << ":" << port << std::endl;
+
+    App::srv->listen(host, port);
+
+    return 0;
+}

+ 93 - 0
sqlitedb.cpp

@@ -0,0 +1,93 @@
+#include "sqlitedb.h"
+
+#include <iostream>
+#include <sstream>
+#include <sqlite3.h>
+
+SqliteDb::SqliteDb(const std::string& dbPath)
+{
+    open(dbPath);
+}
+
+SqliteDb::~SqliteDb()
+{
+    close();
+}
+
+bool SqliteDb::execute(const std::string &sql)
+{
+    std::ignore = sql;
+    return false;
+}
+
+std::string SqliteDb::readTable(const std::string &table, const std::vector<Param>& params)
+{
+    std::string sql = "SELECT * FROM " + table;
+
+    std::stringstream clause;
+    std::string separator = "";
+    for (const auto& [param, value] : params)
+    {
+        clause << separator << param << "=" << value;
+        separator = " AND ";
+    }
+
+    clause.seekp(-5, std::ios_base::end);
+    if (!params.empty())
+        sql += " WHERE " + clause.str();
+
+    sqlite3_stmt* stmt;
+
+    int rc = sqlite3_prepare_v2(mDb, sql.c_str(), -1, &stmt, nullptr);
+    if (rc != SQLITE_OK) {
+        return std::string("SQL error: ") + sqlite3_errmsg(mDb);
+    }
+
+    int colCount = sqlite3_column_count(stmt);
+
+    std::stringstream res;
+
+    res << "[";
+    while (sqlite3_step(stmt) == SQLITE_ROW) {
+        separator = "";
+        res << "{";
+        for (int i = 0; i < colCount; i++) {
+            const char* colName = sqlite3_column_name(stmt, i);
+            const char* declType = sqlite3_column_decltype(stmt, i);
+            const char* colValue = reinterpret_cast<const char*>(sqlite3_column_text(stmt, i));
+            std::string type( declType );
+            bool needQuote = (type == "TEXT" || type == "DATE" || !colValue);
+
+            res << separator << colName << ":";
+            if(needQuote)
+                res << "\"";
+            res << (colValue ? colValue : "null");
+            if(needQuote)
+                res << "\"";
+
+            separator = ",";
+        }
+        res << "},";
+    }
+    res.seekp(-1, std::ios_base::end);
+    res << "]";
+
+    sqlite3_finalize(stmt);
+
+    return res.str();
+}
+
+void SqliteDb::open(const std::string &dbPath)
+{
+    char *zErrMsg = 0;
+    int rc = sqlite3_open(dbPath.c_str(), &mDb);
+    if (rc) {
+        std::cerr << "Can't open database: " << sqlite3_errmsg(mDb) << std::endl;
+        sqlite3_free(zErrMsg);
+    }
+}
+
+void SqliteDb::close()
+{
+    sqlite3_close(mDb);
+}

+ 27 - 0
sqlitedb.h

@@ -0,0 +1,27 @@
+#ifndef SQLITEDB_H
+#define SQLITEDB_H
+
+#include <string>
+#include <vector>
+
+struct sqlite3;
+
+class SqliteDb
+{
+public:
+    SqliteDb(const std::string& dbPath);
+    ~SqliteDb();
+
+    bool execute(const std::string& sql);
+
+    using Param = std::pair<std::string, std::string>;
+    std::string readTable(const std::string& table, const std::vector<Param>& params = {});
+
+private:
+    void open(const std::string& dbPath);
+    void close();
+
+    sqlite3* mDb;
+};
+
+#endif // SQLITEDB_H