diff --git a/351004/Lazuta/.gitignore b/351004/Lazuta/.gitignore
index d8e18a7a5..20b86f6e5 100644
--- a/351004/Lazuta/.gitignore
+++ b/351004/Lazuta/.gitignore
@@ -655,4 +655,8 @@ drogon_ctl_*
*.truststore
cert/
certs/
-ssl/
\ No newline at end of file
+ssl/
+
+
+# /config
+/tools
\ No newline at end of file
diff --git a/351004/Lazuta/CMakeLists.txt b/351004/Lazuta/CMakeLists.txt
index a44c8f008..851068141 100644
--- a/351004/Lazuta/CMakeLists.txt
+++ b/351004/Lazuta/CMakeLists.txt
@@ -11,14 +11,15 @@ file(GLOB_RECURSE SOURCE_FILES
)
find_package(Drogon REQUIRED)
+find_package(Jsoncpp REQUIRED)
add_executable(${PROJECT_NAME}
${SOURCE_FILES}
)
-
target_include_directories(${PROJECT_NAME} PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/src"
)
-target_link_libraries(${PROJECT_NAME} Drogon::Drogon)
\ No newline at end of file
+target_link_libraries(${PROJECT_NAME} Drogon::Drogon)
+
diff --git a/351004/Lazuta/README.md b/351004/Lazuta/README.md
new file mode 100644
index 000000000..9e06f5eae
--- /dev/null
+++ b/351004/Lazuta/README.md
@@ -0,0 +1,38 @@
+# Создаем директорию для инструментов
+cd /project-root
+mkdir -p tools/liquibase
+
+# Скачиваем Liquibase
+wget https://github.com/liquibase/liquibase/releases/download/v4.24.0/liquibase-4.24.0.tar.gz
+
+# Распаковываем в tools/liquibase
+tar -xzf liquibase-4.24.0.tar.gz -C tools/liquibase/
+
+# Делаем исполняемый файл доступным
+chmod +x tools/liquibase/liquibase
+
+# Скачиваем JDBC драйвер для PostgreSQL
+wget https://jdbc.postgresql.org/download/postgresql-42.7.1.jar
+mv postgresql-42.7.1.jar tools/liquibase/lib/
+
+# В директории liquibase
+
+# Проверить статус
+./liquibase status
+
+# Применить миграции
+./liquibase update
+
+# Применить только для разработки (с тестовыми данными)
+./liquibase update -Dcontext=dev
+
+# Сгенерировать SQL без выполнения
+./liquibase update-sql > migration.sql
+
+# Откатить последние 2 изменения
+./liquibase rollback-count 2
+
+# Посмотреть историю
+./liquibase history
+
+# Запустите скрипт migrate.sh в папке scripts, предварительно создав БД
\ No newline at end of file
diff --git a/351004/Lazuta/config.json b/351004/Lazuta/config.json
deleted file mode 100644
index 741430e0e..000000000
--- a/351004/Lazuta/config.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "listeners": [
- {
- "address": "0.0.0.0",
- "port": 24110,
- "https": false
- }
- ],
- "app":
- {
- "threads_num": 1,
- "document_root": "/home/dmitry/Distcomp/351004/Lazuta/http",
- "implicit_page": "index.html"
- }
-
-}
\ No newline at end of file
diff --git a/351004/Lazuta/config/app/config.json b/351004/Lazuta/config/app/config.json
new file mode 100644
index 000000000..92879a3ab
--- /dev/null
+++ b/351004/Lazuta/config/app/config.json
@@ -0,0 +1,28 @@
+{
+ "listeners": [
+ {
+ "address": "0.0.0.0",
+ "port": 24110,
+ "https": false
+ }
+ ],
+ "app": {
+ "threads_num": 1,
+ "document_root": "/home/dmitry/Distcomp/351004/Lazuta/http",
+ "implicit_page": "index.html"
+ },
+ "db_clients": [
+ {
+ "name": "default",
+ "rdbms": "postgresql",
+ "host": "127.0.0.1",
+ "port": 5432,
+ "dbname": "distcomp",
+ "user": "postgres",
+ "passwd": "postgres",
+ "is_fast": false,
+ "connection_number": 1,
+ "auto_batch": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/351004/Lazuta/config/database/dev.properties b/351004/Lazuta/config/database/dev.properties
new file mode 100644
index 000000000..69f18e5ff
--- /dev/null
+++ b/351004/Lazuta/config/database/dev.properties
@@ -0,0 +1,5 @@
+DB_HOST=localhost
+DB_PORT=5432
+DB_NAME=distcomp
+DB_USER=postgres
+DB_PASSWORD=postgres
\ No newline at end of file
diff --git a/351004/Lazuta/migrations/changelog/db.changelog-master.xml b/351004/Lazuta/migrations/changelog/db.changelog-master.xml
new file mode 100644
index 000000000..6fc61f02b
--- /dev/null
+++ b/351004/Lazuta/migrations/changelog/db.changelog-master.xml
@@ -0,0 +1,245 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ALTER TABLE tbl_editor
+ ADD CONSTRAINT chk_editor_login_length
+ CHECK (LENGTH(login) BETWEEN 2 AND 64);
+
+ ALTER TABLE tbl_editor
+ ADD CONSTRAINT chk_editor_password_length
+ CHECK (LENGTH(password) BETWEEN 8 AND 128);
+
+ ALTER TABLE tbl_editor
+ ADD CONSTRAINT chk_editor_firstname_length
+ CHECK (LENGTH(firstname) BETWEEN 2 AND 64);
+
+ ALTER TABLE tbl_editor
+ ADD CONSTRAINT chk_editor_lastname_length
+ CHECK (LENGTH(lastname) BETWEEN 2 AND 64);
+
+
+
+ COMMENT ON TABLE tbl_editor IS 'Редакторы/пользователи системы';
+ COMMENT ON COLUMN tbl_editor.id IS 'Уникальный идентификатор';
+ COMMENT ON COLUMN tbl_editor.login IS 'Логин пользователя (2-64 символа)';
+ COMMENT ON COLUMN tbl_editor.password IS 'Пароль (8-128 символов)';
+ COMMENT ON COLUMN tbl_editor.firstname IS 'Имя (2-64 символа)';
+ COMMENT ON COLUMN tbl_editor.lastname IS 'Фамилия (2-64 символа)';
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ALTER TABLE tbl_label
+ ADD CONSTRAINT chk_label_name_length
+ CHECK (LENGTH(name) BETWEEN 2 AND 32);
+
+ COMMENT ON TABLE tbl_label IS 'Метки для категоризации задач';
+ COMMENT ON COLUMN tbl_label.id IS 'Уникальный идентификатор метки';
+ COMMENT ON COLUMN tbl_label.name IS 'Название метки (2-32 символа)';
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ALTER TABLE tbl_issue
+ ADD CONSTRAINT chk_issue_title_length
+ CHECK (LENGTH(title) BETWEEN 2 AND 64);
+
+ ALTER TABLE tbl_issue
+ ADD CONSTRAINT chk_issue_content_length
+ CHECK (LENGTH(content) BETWEEN 4 AND 2048);
+
+ ALTER TABLE tbl_issue
+ ADD CONSTRAINT chk_issue_dates
+ CHECK (modified >= created);
+
+ COMMENT ON TABLE tbl_issue IS 'Задачи/посты системы';
+ COMMENT ON COLUMN tbl_issue.id IS 'Уникальный идентификатор задачи';
+ COMMENT ON COLUMN tbl_issue.editor_id IS 'ID автора задачи';
+ COMMENT ON COLUMN tbl_issue.title IS 'Заголовок задачи (2-64 символа)';
+ COMMENT ON COLUMN tbl_issue.content IS 'Содержание задачи (4-2048 символов)';
+ COMMENT ON COLUMN tbl_issue.created IS 'Дата и время создания';
+ COMMENT ON COLUMN tbl_issue.modified IS 'Дата и время последнего изменения';
+
+
+
+
+
+
+
+ CREATE OR REPLACE FUNCTION update_modified_column()
+ RETURNS TRIGGER AS $function_body$
+ BEGIN
+ NEW.modified = CURRENT_TIMESTAMP;
+ RETURN NEW;
+ END;
+ $function_body$ LANGUAGE plpgsql;
+ --;;
+
+
+
+ DROP FUNCTION IF EXISTS update_modified_column() CASCADE;
+
+
+
+
+
+
+
+
+
+
+ DROP TRIGGER IF EXISTS trigger_update_issue_modified ON tbl_issue;
+
+ CREATE TRIGGER trigger_update_issue_modified
+ BEFORE UPDATE ON tbl_issue
+ FOR EACH ROW
+ EXECUTE FUNCTION update_modified_column();
+
+
+
+ DROP TRIGGER IF EXISTS trigger_update_issue_modified ON tbl_issue;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ALTER TABLE tbl_post
+ ADD CONSTRAINT chk_post_content_length
+ CHECK (LENGTH(content) BETWEEN 2 AND 2048);
+
+ COMMENT ON TABLE tbl_post IS 'Комментарии к задачам';
+ COMMENT ON COLUMN tbl_post.id IS 'Уникальный идентификатор комментария';
+ COMMENT ON COLUMN tbl_post.issue_id IS 'ID задачи, к которой относится комментарий';
+ COMMENT ON COLUMN tbl_post.content IS 'Текст комментария (2-2048 символов)';
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ COMMENT ON TABLE tbl_issue_label IS 'Связь задач с метками';
+ COMMENT ON COLUMN tbl_issue_label.id IS 'Уникальный идентификатор связи';
+ COMMENT ON COLUMN tbl_issue_label.issue_id IS 'ID задачи';
+ COMMENT ON COLUMN tbl_issue_label.label_id IS 'ID метки';
+
+
+
+
\ No newline at end of file
diff --git a/351004/Lazuta/migrations/liquibase.properties b/351004/Lazuta/migrations/liquibase.properties
new file mode 100644
index 000000000..5ebe76f31
--- /dev/null
+++ b/351004/Lazuta/migrations/liquibase.properties
@@ -0,0 +1,6 @@
+changeLogFile=changelog/db.changelog-master.xml
+driver=org.postgresql.Driver
+url=jdbc:postgresql://localhost:5432/distcomp
+username=postgres
+password=postgres
+liquibase.hub.mode=off
\ No newline at end of file
diff --git a/351004/Lazuta/src/api/v1.0/controllers/EditorController.cc b/351004/Lazuta/src/api/v1.0/controllers/EditorController.cc
index 54bb136da..ca8224228 100644
--- a/351004/Lazuta/src/api/v1.0/controllers/EditorController.cc
+++ b/351004/Lazuta/src/api/v1.0/controllers/EditorController.cc
@@ -1,6 +1,9 @@
#include "EditorController.h"
#include
+using namespace myapp;
+using namespace myapp::dto;
+
EditorController::EditorController(std::unique_ptr service)
{
m_service = std::move(service);
@@ -43,18 +46,9 @@ void EditorController::CreateEditor(const HttpRequestPtr& req, std::functionsetStatusCode(HttpStatusCode::k403Forbidden);
httpResponse->setBody(Json::FastWriter().write(errorResponse));
- httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
- httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
- }
- catch(const NotFoundException& e)
- {
- std::cout << "[ERROR] Not found: " << e.what() << std::endl;
- Json::Value errorResponse;
- errorResponse["message"] = e.what();
- httpResponse->setBody(Json::FastWriter().write(errorResponse));
- httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
- httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
}
catch(const DatabaseException& e)
{
diff --git a/351004/Lazuta/src/api/v1.0/controllers/EditorController.h b/351004/Lazuta/src/api/v1.0/controllers/EditorController.h
index 67ffbe344..1ddffcdd1 100644
--- a/351004/Lazuta/src/api/v1.0/controllers/EditorController.h
+++ b/351004/Lazuta/src/api/v1.0/controllers/EditorController.h
@@ -9,6 +9,7 @@
#include
using namespace drogon;
+using namespace myapp;
class EditorController : public drogon::HttpController
{
diff --git a/351004/Lazuta/src/api/v1.0/controllers/IssueController.cc b/351004/Lazuta/src/api/v1.0/controllers/IssueController.cc
index e752fd5aa..28a6a709e 100644
--- a/351004/Lazuta/src/api/v1.0/controllers/IssueController.cc
+++ b/351004/Lazuta/src/api/v1.0/controllers/IssueController.cc
@@ -2,6 +2,9 @@
#include "IssueController.h"
#include
+using namespace myapp;
+using namespace myapp::dto;
+
IssueController::IssueController(std::unique_ptr service)
{
m_service = std::move(service);
@@ -46,7 +49,7 @@ void IssueController::CreateIssue(const HttpRequestPtr& req, std::functionsetBody(Json::FastWriter().write(errorResponse));
httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
- httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ httpResponse->setStatusCode(HttpStatusCode::k403Forbidden);
}
catch(const NotFoundException& e)
{
diff --git a/351004/Lazuta/src/api/v1.0/controllers/IssueController.h b/351004/Lazuta/src/api/v1.0/controllers/IssueController.h
index 70cf4cca4..5d0abf36f 100644
--- a/351004/Lazuta/src/api/v1.0/controllers/IssueController.h
+++ b/351004/Lazuta/src/api/v1.0/controllers/IssueController.h
@@ -9,6 +9,7 @@
#include
using namespace drogon;
+using namespace myapp;
class IssueController : public drogon::HttpController
{
diff --git a/351004/Lazuta/src/api/v1.0/controllers/IssueLabelController.cc b/351004/Lazuta/src/api/v1.0/controllers/IssueLabelController.cc
new file mode 100644
index 000000000..1ed0c7529
--- /dev/null
+++ b/351004/Lazuta/src/api/v1.0/controllers/IssueLabelController.cc
@@ -0,0 +1,608 @@
+#include "IssueLabelController.h"
+#include
+
+using namespace myapp;
+using namespace myapp::dto;
+
+IssueLabelController::IssueLabelController(std::unique_ptr service)
+{
+ m_service = std::move(service);
+ std::cout << "[INFO] IssueLabelController initialized" << std::endl;
+}
+
+void IssueLabelController::CreateIssueLabel(const HttpRequestPtr& req, std::function&& callback)
+{
+ HttpResponsePtr httpResponse = HttpResponse::newHttpResponse();
+ std::cout << "[INFO] CreateIssueLabel called" << std::endl;
+
+ try
+ {
+ auto jsonFromRequest = req->getJsonObject();
+ if (!jsonFromRequest)
+ {
+ std::cout << "[ERROR] Invalid JSON in CreateIssueLabel" << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Invalid JSON format";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ callback(httpResponse);
+ return;
+ }
+
+ IssueLabelResponseTo dto = m_service->Create(IssueLabelRequestTo::fromJson(*jsonFromRequest));
+ Json::Value jsonResponse = dto.toJson();
+
+ std::string responseBody = Json::FastWriter().write(jsonResponse);
+ std::cout << "[RESPONSE] " << responseBody << std::endl;
+
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setBody(responseBody);
+ httpResponse->setStatusCode(HttpStatusCode::k201Created);
+ std::cout << "[INFO] IssueLabel created successfully" << std::endl;
+ }
+ catch(const ValidationException& e)
+ {
+ std::cout << "[ERROR] Validation error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ }
+ catch(const NotFoundException& e)
+ {
+ std::cout << "[ERROR] Not found: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ catch(const DatabaseException& e)
+ {
+ std::cout << "[ERROR] Database error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Database error occurred";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+ catch(const std::exception& e)
+ {
+ std::cout << "[ERROR] Unknown error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Internal server error";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+
+ callback(httpResponse);
+}
+
+void IssueLabelController::ReadIssueLabel(const HttpRequestPtr& req, std::function&& callback, uint64_t id)
+{
+ HttpResponsePtr httpResponse = HttpResponse::newHttpResponse();
+ std::cout << "[INFO] ReadIssueLabel called for id: " << id << std::endl;
+
+ try
+ {
+ IssueLabelResponseTo dto = m_service->Read(id);
+ Json::Value jsonResponse = dto.toJson();
+
+ std::string responseBody = Json::FastWriter().write(jsonResponse);
+ std::cout << "[RESPONSE] " << responseBody << std::endl;
+
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setBody(responseBody);
+ httpResponse->setStatusCode(HttpStatusCode::k200OK);
+ std::cout << "[INFO] IssueLabel retrieved successfully" << std::endl;
+ }
+ catch(const ValidationException& e)
+ {
+ std::cout << "[ERROR] Validation error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ }
+ catch(const NotFoundException& e)
+ {
+ std::cout << "[ERROR] IssueLabel not found: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ catch(const DatabaseException& e)
+ {
+ std::cout << "[ERROR] Database error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Database error occurred";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+ catch(const std::exception& e)
+ {
+ std::cout << "[ERROR] Unknown error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Internal server error";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+
+ callback(httpResponse);
+}
+
+void IssueLabelController::UpdateIssueLabelIdFromRoute(const HttpRequestPtr& req, std::function&& callback, uint64_t id)
+{
+ HttpResponsePtr httpResponse = HttpResponse::newHttpResponse();
+ std::cout << "[INFO] UpdateIssueLabelWithId called for id: " << id << std::endl;
+
+ try
+ {
+ auto jsonFromRequest = req->getJsonObject();
+ if (!jsonFromRequest)
+ {
+ std::cout << "[ERROR] Invalid JSON in UpdateIssueLabelWithId" << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Invalid JSON format";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ callback(httpResponse);
+ return;
+ }
+
+ auto requestDto = IssueLabelRequestTo::fromJson(*jsonFromRequest);
+ IssueLabelResponseTo dto = m_service->Update(requestDto, id);
+
+ Json::Value jsonResponse = dto.toJson();
+ std::string responseBody = Json::FastWriter().write(jsonResponse);
+ std::cout << "[RESPONSE] " << responseBody << std::endl;
+
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setBody(responseBody);
+ httpResponse->setStatusCode(HttpStatusCode::k200OK);
+ std::cout << "[INFO] IssueLabel updated successfully" << std::endl;
+ }
+ catch(const ValidationException& e)
+ {
+ std::cout << "[ERROR] Validation error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ }
+ catch(const NotFoundException& e)
+ {
+ std::cout << "[ERROR] IssueLabel not found for update: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ catch(const DatabaseException& e)
+ {
+ std::cout << "[ERROR] Database error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Database error occurred";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+ catch(const std::exception& e)
+ {
+ std::cout << "[ERROR] Unknown error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Internal server error";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+
+ callback(httpResponse);
+}
+
+void IssueLabelController::UpdateIssueLabelIdFromBody(const HttpRequestPtr& req, std::function&& callback)
+{
+ HttpResponsePtr httpResponse = HttpResponse::newHttpResponse();
+ std::cout << "[INFO] UpdateIssueLabel called (without ID in path)" << std::endl;
+
+ try
+ {
+ auto jsonFromRequest = req->getJsonObject();
+ if (!jsonFromRequest)
+ {
+ std::cout << "[ERROR] Invalid JSON in UpdateIssueLabel" << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Invalid JSON format";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ callback(httpResponse);
+ return;
+ }
+
+ auto requestDto = IssueLabelRequestTo::fromJson(*jsonFromRequest);
+ if (!requestDto.id.has_value())
+ {
+ std::cout << "[ERROR] No ID in JSON" << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "ID is required in request body";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ callback(httpResponse);
+ return;
+ }
+
+ IssueLabelResponseTo dto = m_service->Update(requestDto, requestDto.id.value());
+
+ Json::Value jsonResponse = dto.toJson();
+ std::string responseBody = Json::FastWriter().write(jsonResponse);
+ std::cout << "[RESPONSE] " << responseBody << std::endl;
+
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setBody(responseBody);
+ httpResponse->setStatusCode(HttpStatusCode::k200OK);
+ std::cout << "[INFO] IssueLabel updated successfully" << std::endl;
+ }
+ catch(const ValidationException& e)
+ {
+ std::cout << "[ERROR] Validation error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ }
+ catch(const NotFoundException& e)
+ {
+ std::cout << "[ERROR] IssueLabel not found for update: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ catch(const DatabaseException& e)
+ {
+ std::cout << "[ERROR] Database error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Database error occurred";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+ catch(const std::exception& e)
+ {
+ std::cout << "[ERROR] Unknown error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Internal server error";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+
+ callback(httpResponse);
+}
+
+void IssueLabelController::DeleteIssueLabel(const HttpRequestPtr& req, std::function&& callback, uint64_t id)
+{
+ HttpResponsePtr httpResponse = HttpResponse::newHttpResponse();
+ std::cout << "[INFO] DeleteIssueLabel called for id: " << id << std::endl;
+
+ try
+ {
+ if (m_service->Delete(id))
+ {
+ httpResponse->setStatusCode(HttpStatusCode::k204NoContent);
+ std::cout << "[INFO] IssueLabel deleted successfully" << std::endl;
+ std::cout << "[RESPONSE] No content (204)" << std::endl;
+ }
+ else
+ {
+ std::cout << "[ERROR] IssueLabel not found for deletion" << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "IssueLabel not found";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ }
+ catch(const ValidationException& e)
+ {
+ std::cout << "[ERROR] Validation error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ }
+ catch(const NotFoundException& e)
+ {
+ std::cout << "[ERROR] IssueLabel not found: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ catch(const DatabaseException& e)
+ {
+ std::cout << "[ERROR] Database error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Database error occurred";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+ catch(const std::exception& e)
+ {
+ std::cout << "[ERROR] Unknown error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Internal server error";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+
+ callback(httpResponse);
+}
+
+void IssueLabelController::GetAllIssueLabels(const HttpRequestPtr& req, std::function&& callback)
+{
+ HttpResponsePtr httpResponse = HttpResponse::newHttpResponse();
+ std::cout << "[INFO] GetAllIssueLabels called" << std::endl;
+
+ try
+ {
+ std::vector dtos = m_service->GetAll();
+ Json::Value jsonResponse(Json::arrayValue);
+ for (auto& dto: dtos)
+ {
+ jsonResponse.append(dto.toJson());
+ }
+
+ std::string responseBody = Json::FastWriter().write(jsonResponse);
+ std::cout << "[RESPONSE] " << responseBody << std::endl;
+
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setBody(responseBody);
+ httpResponse->setStatusCode(HttpStatusCode::k200OK);
+ std::cout << "[INFO] Retrieved " << dtos.size() << " issue labels" << std::endl;
+ }
+ catch(const ValidationException& e)
+ {
+ std::cout << "[ERROR] Validation error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ }
+ catch(const NotFoundException& e)
+ {
+ std::cout << "[ERROR] Not found: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ catch(const DatabaseException& e)
+ {
+ std::cout << "[ERROR] Database error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Database error occurred";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+ catch(const std::exception& e)
+ {
+ std::cout << "[ERROR] Unknown error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Internal server error";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+
+ callback(httpResponse);
+}
+
+void IssueLabelController::GetByIssueId(const HttpRequestPtr& req, std::function&& callback, uint64_t issueId)
+{
+ HttpResponsePtr httpResponse = HttpResponse::newHttpResponse();
+ std::cout << "[INFO] GetByIssueId called for issueId: " << issueId << std::endl;
+
+ try
+ {
+ std::vector dtos = m_service->GetByIssueId(issueId);
+ Json::Value jsonResponse(Json::arrayValue);
+ for (auto& dto: dtos)
+ {
+ jsonResponse.append(dto.toJson());
+ }
+
+ std::string responseBody = Json::FastWriter().write(jsonResponse);
+ std::cout << "[RESPONSE] " << responseBody << std::endl;
+
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setBody(responseBody);
+ httpResponse->setStatusCode(HttpStatusCode::k200OK);
+ std::cout << "[INFO] Retrieved " << dtos.size() << " issue labels for issue " << issueId << std::endl;
+ }
+ catch(const ValidationException& e)
+ {
+ std::cout << "[ERROR] Validation error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ }
+ catch(const NotFoundException& e)
+ {
+ std::cout << "[ERROR] Not found: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ catch(const DatabaseException& e)
+ {
+ std::cout << "[ERROR] Database error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Database error occurred";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+ catch(const std::exception& e)
+ {
+ std::cout << "[ERROR] Unknown error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Internal server error";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+
+ callback(httpResponse);
+}
+
+void IssueLabelController::GetByLabelId(const HttpRequestPtr& req, std::function&& callback, uint64_t labelId)
+{
+ HttpResponsePtr httpResponse = HttpResponse::newHttpResponse();
+ std::cout << "[INFO] GetByLabelId called for labelId: " << labelId << std::endl;
+
+ try
+ {
+ std::vector dtos = m_service->GetByLabelId(labelId);
+ Json::Value jsonResponse(Json::arrayValue);
+ for (auto& dto: dtos)
+ {
+ jsonResponse.append(dto.toJson());
+ }
+
+ std::string responseBody = Json::FastWriter().write(jsonResponse);
+ std::cout << "[RESPONSE] " << responseBody << std::endl;
+
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setBody(responseBody);
+ httpResponse->setStatusCode(HttpStatusCode::k200OK);
+ std::cout << "[INFO] Retrieved " << dtos.size() << " issue labels for label " << labelId << std::endl;
+ }
+ catch(const ValidationException& e)
+ {
+ std::cout << "[ERROR] Validation error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ }
+ catch(const NotFoundException& e)
+ {
+ std::cout << "[ERROR] Not found: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ catch(const DatabaseException& e)
+ {
+ std::cout << "[ERROR] Database error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Database error occurred";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+ catch(const std::exception& e)
+ {
+ std::cout << "[ERROR] Unknown error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Internal server error";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+
+ callback(httpResponse);
+}
+
+void IssueLabelController::DeleteByIssueAndLabel(const HttpRequestPtr& req, std::function&& callback, uint64_t issueId, uint64_t labelId)
+{
+ HttpResponsePtr httpResponse = HttpResponse::newHttpResponse();
+ std::cout << "[INFO] DeleteByIssueAndLabel called for issueId: " << issueId << ", labelId: " << labelId << std::endl;
+
+ try
+ {
+ if (m_service->DeleteByIssueAndLabel(issueId, labelId))
+ {
+ httpResponse->setStatusCode(HttpStatusCode::k204NoContent);
+ std::cout << "[INFO] IssueLabel combination deleted successfully" << std::endl;
+ std::cout << "[RESPONSE] No content (204)" << std::endl;
+ }
+ else
+ {
+ std::cout << "[ERROR] IssueLabel combination not found for deletion" << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "IssueLabel combination not found";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ }
+ catch(const ValidationException& e)
+ {
+ std::cout << "[ERROR] Validation error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k400BadRequest);
+ }
+ catch(const NotFoundException& e)
+ {
+ std::cout << "[ERROR] IssueLabel combination not found: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = e.what();
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k404NotFound);
+ }
+ catch(const DatabaseException& e)
+ {
+ std::cout << "[ERROR] Database error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Database error occurred";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+ catch(const std::exception& e)
+ {
+ std::cout << "[ERROR] Unknown error: " << e.what() << std::endl;
+ Json::Value errorResponse;
+ errorResponse["message"] = "Internal server error";
+ httpResponse->setBody(Json::FastWriter().write(errorResponse));
+ httpResponse->setContentTypeCode(ContentType::CT_APPLICATION_JSON);
+ httpResponse->setStatusCode(HttpStatusCode::k500InternalServerError);
+ }
+
+ callback(httpResponse);
+}
\ No newline at end of file
diff --git a/351004/Lazuta/src/api/v1.0/controllers/IssueLabelController.h b/351004/Lazuta/src/api/v1.0/controllers/IssueLabelController.h
new file mode 100644
index 000000000..33f89a879
--- /dev/null
+++ b/351004/Lazuta/src/api/v1.0/controllers/IssueLabelController.h
@@ -0,0 +1,44 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace drogon;
+using namespace myapp;
+
+class IssueLabelController : public drogon::HttpController
+{
+private:
+ std::unique_ptr m_service = nullptr;
+
+public:
+ explicit IssueLabelController(std::unique_ptr service);
+
+ METHOD_LIST_BEGIN
+ ADD_METHOD_TO(IssueLabelController::CreateIssueLabel, "/api/v1.0/issue-labels", drogon::Post);
+ ADD_METHOD_TO(IssueLabelController::ReadIssueLabel, "/api/v1.0/issue-labels/{id}", drogon::Get);
+ ADD_METHOD_TO(IssueLabelController::UpdateIssueLabelIdFromRoute, "/api/v1.0/issue-labels/{id}", drogon::Put);
+ ADD_METHOD_TO(IssueLabelController::UpdateIssueLabelIdFromBody, "/api/v1.0/issue-labels", drogon::Put);
+ ADD_METHOD_TO(IssueLabelController::DeleteIssueLabel, "/api/v1.0/issue-labels/{id}", drogon::Delete);
+ ADD_METHOD_TO(IssueLabelController::GetAllIssueLabels, "/api/v1.0/issue-labels", drogon::Get);
+ ADD_METHOD_TO(IssueLabelController::GetByIssueId, "/api/v1.0/issue-labels/issue/{issueId}", drogon::Get);
+ ADD_METHOD_TO(IssueLabelController::GetByLabelId, "/api/v1.0/issue-labels/label/{labelId}", drogon::Get);
+ ADD_METHOD_TO(IssueLabelController::DeleteByIssueAndLabel, "/api/v1.0/issue-labels/issue/{issueId}/label/{labelId}", drogon::Delete);
+ METHOD_LIST_END
+
+private:
+ void CreateIssueLabel(const HttpRequestPtr& req, std::function&& callback);
+ void ReadIssueLabel(const HttpRequestPtr& req, std::function&& callback, uint64_t id);
+ void UpdateIssueLabelIdFromRoute(const HttpRequestPtr& req, std::function&& callback, uint64_t id);
+ void UpdateIssueLabelIdFromBody(const HttpRequestPtr& req, std::function&& callback);
+ void DeleteIssueLabel(const HttpRequestPtr& req, std::function&& callback, uint64_t id);
+ void GetAllIssueLabels(const HttpRequestPtr& req, std::function&& callback);
+ void GetByIssueId(const HttpRequestPtr& req, std::function&& callback, uint64_t issueId);
+ void GetByLabelId(const HttpRequestPtr& req, std::function&& callback, uint64_t labelId);
+ void DeleteByIssueAndLabel(const HttpRequestPtr& req, std::function&& callback, uint64_t issueId, uint64_t labelId);
+};
\ No newline at end of file
diff --git a/351004/Lazuta/src/api/v1.0/controllers/LabelController.cc b/351004/Lazuta/src/api/v1.0/controllers/LabelController.cc
index 2524d9f1c..3d82dac9c 100644
--- a/351004/Lazuta/src/api/v1.0/controllers/LabelController.cc
+++ b/351004/Lazuta/src/api/v1.0/controllers/LabelController.cc
@@ -2,6 +2,9 @@
#include "LabelController.h"
#include
+using namespace myapp;
+using namespace myapp::dto;
+
LabelController::LabelController(std::unique_ptr service)
{
m_service = std::move(service);
diff --git a/351004/Lazuta/src/api/v1.0/controllers/LabelController.h b/351004/Lazuta/src/api/v1.0/controllers/LabelController.h
index 24a73310d..d620fdaad 100644
--- a/351004/Lazuta/src/api/v1.0/controllers/LabelController.h
+++ b/351004/Lazuta/src/api/v1.0/controllers/LabelController.h
@@ -9,6 +9,7 @@
#include
using namespace drogon;
+using namespace myapp;
class LabelController : public drogon::HttpController
{
diff --git a/351004/Lazuta/src/api/v1.0/controllers/PostController.cc b/351004/Lazuta/src/api/v1.0/controllers/PostController.cc
index 919f8cb5b..5a0fdfc73 100644
--- a/351004/Lazuta/src/api/v1.0/controllers/PostController.cc
+++ b/351004/Lazuta/src/api/v1.0/controllers/PostController.cc
@@ -2,6 +2,9 @@
#include "PostController.h"
#include
+using namespace myapp;
+using namespace myapp::dto;
+
PostController::PostController(std::unique_ptr service)
{
m_service = std::move(service);
diff --git a/351004/Lazuta/src/api/v1.0/controllers/PostController.h b/351004/Lazuta/src/api/v1.0/controllers/PostController.h
index d19194b9e..cfd3131e4 100644
--- a/351004/Lazuta/src/api/v1.0/controllers/PostController.h
+++ b/351004/Lazuta/src/api/v1.0/controllers/PostController.h
@@ -9,6 +9,7 @@
#include
using namespace drogon;
+using namespace myapp;
class PostController : public drogon::HttpController
{
diff --git a/351004/Lazuta/src/dao/DAO.h b/351004/Lazuta/src/dao/DAO.h
index df914f456..a847a150f 100644
--- a/351004/Lazuta/src/dao/DAO.h
+++ b/351004/Lazuta/src/dao/DAO.h
@@ -3,20 +3,20 @@
#include
#include
#include
+#include
#include
+#include
-template
+template
class DAO
{
public:
virtual ~DAO() = default;
- virtual K Create(const T& entity) = 0;
- virtual std::optional GetByID(K id) = 0;
- virtual bool Update(K id, const T& entity) = 0;
- virtual bool Delete(K id) = 0;
- virtual std::vector ReadAll() = 0;
-
- virtual std::vector FindBy(std::function predicate) = 0;
- virtual bool Exists(K id) = 0;
+ virtual std::variant Create(const T& entity) = 0;
+ virtual std::variant GetByID(K id) = 0;
+ virtual std::variant Update(K id, const T& entity) = 0;
+ virtual std::variant Delete(K id) = 0;
+ virtual std::variant, E> ReadAll() = 0;
+ virtual std::variant Exists(K id) = 0;
};
\ No newline at end of file
diff --git a/351004/Lazuta/src/dao/EditorDAO.h b/351004/Lazuta/src/dao/EditorDAO.h
deleted file mode 100644
index 86bfb2f1a..000000000
--- a/351004/Lazuta/src/dao/EditorDAO.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include "DAO.h"
-#include
-
-class EditorDAO : public DAO
-{
-public:
- virtual ~EditorDAO() = default;
-
- virtual std::optional FindByLogin(const std::string& login) = 0;
- virtual bool ExistsByLogin(const std::string& login) = 0;
-};
\ No newline at end of file
diff --git a/351004/Lazuta/src/dao/IssueDAO.h b/351004/Lazuta/src/dao/IssueDAO.h
deleted file mode 100644
index 98069900d..000000000
--- a/351004/Lazuta/src/dao/IssueDAO.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#include "DAO.h"
-#include
-#include
-#include
-
-class IssueDAO : public DAO
-{
-public:
- virtual ~IssueDAO() = default;
-
- virtual std::vector FindByEditorId(uint64_t editorId) = 0;
-
- virtual std::vector FindByLabelId(uint64_t labelId) = 0;
- virtual void AddLabelToIssue(uint64_t issueId, uint64_t labelId) = 0;
- virtual void RemoveLabelFromIssue(uint64_t issueId, uint64_t labelId) = 0;
- virtual std::vector GetLabelIdsForIssue(uint64_t issueId) = 0;
-
- virtual std::vector FindByPostId(uint64_t postId) = 0;
-
- virtual std::vector FindByCriteria
- (
- std::optional title,
- std::optional content,
- std::optional editorLogin,
- std::optional> labelIds,
- std::optional> labelNames
- ) = 0;
-};
\ No newline at end of file
diff --git a/351004/Lazuta/src/dao/LabelDAO.h b/351004/Lazuta/src/dao/LabelDAO.h
deleted file mode 100644
index 7a45b4e82..000000000
--- a/351004/Lazuta/src/dao/LabelDAO.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#pragma once
-
-#include "DAO.h"
-#include
-
-class LabelDAO : public DAO