From 5cc25c3a40b81f24914aa5f6e2b64888580040ee Mon Sep 17 00:00:00 2001 From: "Ivan I. Ovchinnikov" Date: Thu, 28 May 2026 22:15:38 +0300 Subject: [PATCH] initial --- .idea/.gitignore | 10 ++ .idea/.name | 1 + .idea/editor.xml | 101 ++++++++++++++++++ .idea/misc.xml | 7 ++ .idea/modules.xml | 8 ++ .idea/untitled.iml | 2 + CMakeLists.txt | 23 ++++ .../iovi_space/sqlite_client/SQLiteClient.h | 29 +++++ src/iovi_space/sqlite_client/SQLiteClient.cpp | 74 +++++++++++++ 9 files changed, 255 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/.name create mode 100644 .idea/editor.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/untitled.iml create mode 100644 CMakeLists.txt create mode 100644 include/iovi_space/sqlite_client/SQLiteClient.h create mode 100644 src/iovi_space/sqlite_client/SQLiteClient.cpp diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..ab1f416 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,10 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..53824c1 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +SQLiteClient \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..ca29dcc --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,101 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..0b76fe5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..aeb7613 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/untitled.iml b/.idea/untitled.iml new file mode 100644 index 0000000..4c94235 --- /dev/null +++ b/.idea/untitled.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f8571ad --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.28) +project(SQLiteClient LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_library(SQLiteClient STATIC src/iovi_space/sqlite_client/SQLiteClient.cpp include/iovi_space/sqlite_client/SQLiteClient.h) + +target_include_directories(SQLiteClient PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +find_package(PkgConfig QUIET) +if(PKG_CONFIG_FOUND) + pkg_check_modules(SQLITE3 REQUIRED sqlite3) + target_include_directories(SQLiteClient SYSTEM PRIVATE ${SQLITE3_INCLUDE_DIRS}) + target_link_libraries(SQLiteClient PRIVATE ${SQLITE3_LIBRARIES}) + target_compile_options(SQLiteClient PRIVATE ${SQLITE3_CFLAGS_OTHER}) +else() + # Fallback для Windows / MSYS2 / ручной сборки + find_path(SQLITE3_INCLUDE_DIR sqlite3.h) + find_library(SQLITE3_LIBRARY sqlite3) + target_include_directories(SQLiteClient SYSTEM PRIVATE ${SQLITE3_INCLUDE_DIR}) + target_link_libraries(SQLiteClient PRIVATE ${SQLITE3_LIBRARY}) +endif() diff --git a/include/iovi_space/sqlite_client/SQLiteClient.h b/include/iovi_space/sqlite_client/SQLiteClient.h new file mode 100644 index 0000000..02507bc --- /dev/null +++ b/include/iovi_space/sqlite_client/SQLiteClient.h @@ -0,0 +1,29 @@ +#ifndef SQLITE_CLIENT_LIBRARY_H +#define SQLITE_CLIENT_LIBRARY_H + +#include +#include +#include +#include + +namespace iovi_space { + + class SqlClient { + public: + // Подключение к БД. Путь по умолчанию совпадает с вашим Java-проектом. + static void connect(const std::string& db_path = "chat-server/chat.db"); + + // Закрытие соединения + static void disconnect(); + + // Поиск никнейма. Возвращает std::nullopt, если пользователь не найден. + static std::optional getNickname(const std::string& login, const std::string& password); + + private: + static sqlite3* connection; + static std::mutex db_mutex; // Замена synchronized из Java + }; + +} // namespace iovi_space + +#endif // SQLITE_CLIENT_LIBRARY_H \ No newline at end of file diff --git a/src/iovi_space/sqlite_client/SQLiteClient.cpp b/src/iovi_space/sqlite_client/SQLiteClient.cpp new file mode 100644 index 0000000..6f1c012 --- /dev/null +++ b/src/iovi_space/sqlite_client/SQLiteClient.cpp @@ -0,0 +1,74 @@ +#include "../../../include/iovi_space/sqlite_client/SQLiteClient.h" + +#include + +namespace iovi_space { + +sqlite3* SqlClient::connection = nullptr; +std::mutex SqlClient::db_mutex; + +void SqlClient::connect(const std::string& db_path) { + std::lock_guard lock(db_mutex); + if (connection) { + throw std::runtime_error("Already connected to database"); + } + + int rc = sqlite3_open(db_path.c_str(), &connection); + if (rc != SQLITE_OK) { + std::string err = sqlite3_errmsg(connection); + sqlite3_close(connection); + connection = nullptr; + throw std::runtime_error("SQLite connection failed: " + err); + } +} + +void SqlClient::disconnect() { + std::lock_guard lock(db_mutex); + if (!connection) return; + + int rc = sqlite3_close(connection); + connection = nullptr; + if (rc != SQLITE_OK) { + throw std::runtime_error("SQLite disconnect failed: " + std::to_string(rc)); + } +} + +std::optional SqlClient::getNickname(const std::string& login, const std::string& password) { + std::lock_guard lock(db_mutex); + if (!connection) { + throw std::runtime_error("Not connected to database"); + } + + sqlite3_stmt* stmt = nullptr; + const char* sql = "SELECT nickname FROM users WHERE login = ? AND password = ?"; + + // Подготовка запроса (защита от SQL-инъекций) + if (sqlite3_prepare_v2(connection, sql, -1, &stmt, nullptr) != SQLITE_OK) { + throw std::runtime_error(std::string("Prepare failed: ") + sqlite3_errmsg(connection)); + } + + // Привязка параметров + if (sqlite3_bind_text(stmt, 1, login.c_str(), static_cast(login.size()), SQLITE_TRANSIENT) != SQLITE_OK || + sqlite3_bind_text(stmt, 2, password.c_str(), static_cast(password.size()), SQLITE_TRANSIENT) != SQLITE_OK) { + sqlite3_finalize(stmt); + throw std::runtime_error("Parameter binding failed"); + } + + std::optional result; + int rc = sqlite3_step(stmt); + + if (rc == SQLITE_ROW) { + const unsigned char* txt = sqlite3_column_text(stmt, 0); + if (txt) { + result = std::string(reinterpret_cast(txt)); + } + } else if (rc != SQLITE_DONE) { + sqlite3_finalize(stmt); + throw std::runtime_error(std::string("Query execution failed: ") + sqlite3_errmsg(connection)); + } + + sqlite3_finalize(stmt); + return result; +} + +} // namespace chat \ No newline at end of file