From e96adfdd9af64e08bde9413121fc61367c118fe8 Mon Sep 17 00:00:00 2001 From: sabudilovskiy Date: Fri, 19 May 2023 16:48:43 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=B0=20=D0=B8=20=D0=BF=D0=BE=D0=BA=D1=80=D1=8B=D1=82?= =?UTF-8?q?=D0=B0=20=D1=82=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8=20/register?= =?UTF-8?q?:=20=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=20=D0=BF=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B4=D0=B0=D1=82=D1=8C=20=D0=B6=D0=B5=D0=BB=D0=B0=D0=B5=D0=BC?= =?UTF-8?q?=D1=8B=D0=B9=20=D1=83=D1=80=D0=BE=D0=B2=D0=B5=D0=BD=D1=8C=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=D0=B2=D0=B8=D0=BB=D0=BB=D0=B5=D0=B3=D0=B8?= =?UTF-8?q?=D0=B9=20(#15)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1) Расширена и покрыта тестами /register: можно передать желаемый уровень привиллегий 2) В очередной раз изменены настройки форматтера 3) Контроллеры переведены на транзакции 4) Некоторый фикс postgres_helper: теперь не привязан к рефлективным типам --- .clang-format | 5 +- .gen/objs.txt | 2 + api/views/register/RequestV1.yaml | 7 +- benchs/hello_benchmark.cpp | 6 +- postgresql/data/initial_data_auth_admin.sql | 4 +- .../data/initial_data_auth_admin_token.sql | 2 +- postgresql/data/initial_data_auth_root.sql | 2 +- .../data/initial_data_auth_root_token.sql | 2 +- postgresql/data/initial_data_auth_teacher.sql | 10 +- .../data/initial_data_auth_teacher_token.sql | 2 +- postgresql/data/initial_data_auth_user.sql | 2 +- .../data/initial_data_auth_user_token.sql | 2 +- postgresql/data/initial_data_timetable1.sql | 18 +- postgresql/data/initial_data_timetable2.sql | 18 +- postgresql/data/timetable_random.sql | 38 ++-- postgresql/schemas/db_1/000_init.sql | 164 +++++++++--------- .../schemas/db_1/002_add_lesson_filter.sql | 14 +- postgresql/schemas/db_1/003_add_user.sql | 14 +- .../db_1/004_cascade_delete_on_token.sql | 4 +- .../schemas/db_1/005_add_admin_account.sql | 4 +- .../schemas/db_1/006_unique_login_user.sql | 4 +- .../schemas/db_1/007_add_admin_filter.sql | 4 +- .../schemas/db_1/008_add_teacher_filter.sql | 4 +- .../009_lesson_filter_change_uuid_to_text.sql | 14 +- .../010_admin_filter_change_uuid_to_text.sql | 4 +- .../schemas/db_1/011_create_requests.sql | 33 ++++ service/main.cpp | 3 +- .../controllers/postgres/admin/controller.cpp | 33 ++-- .../controllers/postgres/admin/controller.hpp | 14 +- .../controllers/postgres/admin/fwd.cpp | 6 +- .../controllers/postgres/admin/fwd.hpp | 6 +- .../postgres/admin/sql_queries.hpp | 15 +- .../postgres/lesson/controller.cpp | 13 +- .../postgres/lesson/controller.hpp | 9 +- .../controllers/postgres/lesson/fwd.cpp | 6 +- .../controllers/postgres/lesson/fwd.hpp | 6 +- .../postgres/lesson/sql_queries.hpp | 22 +-- .../postgres/teacher/controller.cpp | 19 +- .../postgres/teacher/controller.hpp | 11 +- .../controllers/postgres/teacher/fwd.cpp | 7 +- .../controllers/postgres/teacher/fwd.hpp | 6 +- .../postgres/teacher/sql_queries.hpp | 10 +- .../controllers/postgres/token/controller.cpp | 40 +++-- .../controllers/postgres/token/controller.hpp | 19 +- .../controllers/postgres/token/fwd.cpp | 6 +- .../controllers/postgres/token/fwd.hpp | 6 +- .../postgres/token/sql_queries.hpp | 9 +- .../postgres/user/config_schema.hpp | 4 +- .../controllers/postgres/user/controller.cpp | 125 +++++++++---- .../controllers/postgres/user/controller.hpp | 43 ++++- .../controllers/postgres/user/fwd.cpp | 6 +- .../controllers/postgres/user/fwd.hpp | 6 +- .../controllers/postgres/user/sql_queries.hpp | 39 +++-- src/http/ErrorV1.hpp | 6 +- src/http/handler_parsed.hpp | 35 ++-- src/http/legacy_handler_parsed.hpp | 32 ++-- src/models/admin_account/postgre.hpp | 12 +- src/models/admin_account/type.hpp | 6 +- src/models/admin_filter/fwd.hpp | 3 +- src/models/admin_filter/postgre.hpp | 12 +- src/models/admin_filter/type.hpp | 6 +- src/models/auth_token/serialize.hpp | 6 +- src/models/auth_token/type.hpp | 6 +- src/models/day/parse.cpp | 38 ++-- src/models/day/parse.hpp | 3 +- src/models/day/postgre.hpp | 8 +- src/models/day/serialize.cpp | 12 +- src/models/day/serialize.hpp | 3 +- src/models/day/type.hpp | 6 +- src/models/education_type/parse.cpp | 30 +++- src/models/education_type/parse.hpp | 3 +- src/models/education_type/postgre.hpp | 8 +- src/models/education_type/serialize.cpp | 12 +- src/models/education_type/serialize.hpp | 3 +- src/models/education_type/type.hpp | 6 +- src/models/lesson_filter/fwd.hpp | 3 +- src/models/lesson_filter/postgre.hpp | 12 +- src/models/lesson_filter/type.hpp | 6 +- src/models/lesson_type/parse.cpp | 27 ++- src/models/lesson_type/parse.hpp | 3 +- src/models/lesson_type/postgre.hpp | 8 +- src/models/lesson_type/serialize.cpp | 12 +- src/models/lesson_type/serialize.hpp | 3 +- src/models/lesson_type/type.hpp | 10 +- src/models/lesson_v1/postgre.hpp | 3 +- src/models/lesson_v1/type.hpp | 6 +- src/models/lesson_week_type/parse.cpp | 26 ++- src/models/lesson_week_type/parse.hpp | 3 +- src/models/lesson_week_type/postgre.hpp | 8 +- src/models/lesson_week_type/serialize.cpp | 12 +- src/models/lesson_week_type/serialize.hpp | 3 +- src/models/lesson_week_type/type.hpp | 10 +- src/models/register_request/fwd.hpp | 5 + src/models/register_request/type.hpp | 22 +++ src/models/subgroup/parse.cpp | 26 ++- src/models/subgroup/parse.hpp | 3 +- src/models/subgroup/postgre.hpp | 8 +- src/models/subgroup/serialize.cpp | 12 +- src/models/subgroup/serialize.hpp | 3 +- src/models/subgroup/type.hpp | 10 +- src/models/substring/fwd.hpp | 3 +- src/models/substring/parse.cpp | 15 +- src/models/substring/parse.hpp | 3 +- src/models/substring/postgre.hpp | 7 +- src/models/substring/serialize.cpp | 9 +- src/models/substring/serialize.hpp | 3 +- src/models/substring/type.hpp | 3 +- src/models/teacher/postgre.hpp | 12 +- src/models/teacher/type.hpp | 6 +- src/models/teacher_filter/fwd.hpp | 3 +- src/models/teacher_filter/postgre.hpp | 12 +- src/models/teacher_filter/type.hpp | 6 +- src/models/timestring/fwd.hpp | 3 +- src/models/timestring/parse.cpp | 12 +- src/models/timestring/parse.hpp | 3 +- src/models/timestring/postgre.hpp | 6 +- src/models/timestring/serialize.cpp | 9 +- src/models/timestring/serialize.hpp | 3 +- src/models/timestring/type.hpp | 3 +- src/models/user/postgre.hpp | 12 +- src/models/user/type.hpp | 6 +- src/models/user_credentials/fwd.hpp | 3 +- src/models/user_credentials/postgre.hpp | 12 +- src/models/user_credentials/type.hpp | 6 +- src/models/user_type/parse.cpp | 30 +++- src/models/user_type/parse.hpp | 3 +- src/models/user_type/postgre.hpp | 8 +- src/models/user_type/serialize.cpp | 12 +- src/models/user_type/serialize.hpp | 3 +- src/models/user_type/type.hpp | 11 +- src/utils/component_list_fwd.hpp | 3 +- src/utils/constexpr_string.hpp | 25 ++- src/utils/convert/additional_properties.hpp | 22 ++- src/utils/convert/base.hpp | 36 ++-- .../drop_properties/const_dropper_to_ref.hpp | 73 +++++--- .../drop_properties/mut_dropper_to_ref.hpp | 73 +++++--- .../detail/parse/converter_http_request.hpp | 111 ++++++++---- .../convert/detail/parse/converter_json.hpp | 38 ++-- .../serialize/converter_http_response.hpp | 62 ++++--- .../detail/serialize/converter_json.hpp | 21 ++- src/utils/convert/drop_properties_ref.hpp | 24 ++- src/utils/convert/http_request_parse.hpp | 11 +- src/utils/convert/http_response_base.hpp | 22 ++- src/utils/convert/http_response_serialize.hpp | 6 +- src/utils/convert/json_parse.hpp | 13 +- src/utils/convert/json_serialize.hpp | 13 +- src/utils/json_type.cpp | 44 +++-- src/utils/json_type.hpp | 3 +- src/utils/meta.hpp | 3 +- src/utils/parse/uuid/string.cpp | 6 +- src/utils/parse/uuid/string.hpp | 3 +- src/utils/postgres_helper.hpp | 132 ++++++++------ src/utils/shared_transaction.hpp | 37 ++-- src/utils/type_holder.hpp | 3 +- src/views/admin/create/Request.hpp | 8 +- src/views/admin/create/Responses.hpp | 11 +- src/views/admin/create/view.cpp | 37 ++-- src/views/admin/create/view.hpp | 4 +- src/views/admin/list/Request.hpp | 8 +- src/views/admin/list/Responses.hpp | 11 +- src/views/admin/list/view.cpp | 34 ++-- src/views/admin/list/view.hpp | 4 +- src/views/hello/view.cpp | 35 ++-- src/views/hello/view.hpp | 10 +- src/views/login/Request.hpp | 3 +- src/views/login/Responses.hpp | 9 +- src/views/login/view.cpp | 30 ++-- src/views/login/view.hpp | 4 +- src/views/register/Request.hpp | 7 +- src/views/register/Responses.hpp | 9 +- src/views/register/view.cpp | 79 +++++++-- src/views/register/view.hpp | 4 +- src/views/teacher/list/Request.hpp | 8 +- src/views/teacher/list/Responses.hpp | 8 +- src/views/teacher/list/view.cpp | 19 +- src/views/teacher/list/view.hpp | 4 +- src/views/timetable/get/Request.hpp | 6 +- src/views/timetable/get/Responses.hpp | 6 +- src/views/timetable/get/view.cpp | 27 +-- src/views/timetable/get/view.hpp | 4 +- tests/login/conftest.py | 21 --- tests/register/conftest.py | 57 ++++++ tests/register/test_register.py | 62 +++++++ united_api.yaml | 10 +- utests/convert_test.cpp | 9 +- utests/dropper.cpp | 21 ++- utests/dropper_additional.cpp | 15 +- utests/hello_test.cpp | 3 +- vsu_timetable.code-workspace | 2 +- 189 files changed, 1956 insertions(+), 1016 deletions(-) create mode 100644 postgresql/schemas/db_1/011_create_requests.sql create mode 100644 src/models/register_request/fwd.hpp create mode 100644 src/models/register_request/type.hpp delete mode 100644 tests/login/conftest.py create mode 100644 tests/register/conftest.py create mode 100644 tests/register/test_register.py diff --git a/.clang-format b/.clang-format index e9e7cd76..bbad35b3 100644 --- a/.clang-format +++ b/.clang-format @@ -4,7 +4,7 @@ BasedOnStyle: Google IndentWidth: 4 TabWidth: 4 UseTab: Never -BreakBeforeBraces: Attach +BreakBeforeBraces: Allman AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AllowShortFunctionsOnASingleLine: false @@ -14,3 +14,6 @@ SpaceAfterCStyleCast: true DerivePointerAlignment: false AlignTrailingComments: true SortIncludes: true +BraceWrapping: + AfterClass: true + AfterFunction: true \ No newline at end of file diff --git a/.gen/objs.txt b/.gen/objs.txt index 940e03ef..fefd7ebc 100644 --- a/.gen/objs.txt +++ b/.gen/objs.txt @@ -91,6 +91,8 @@ src/models/subgroup/postgre.hpp src/models/subgroup/parse.hpp src/models/subgroup/parse.cpp src/models/subgroup/all.hpp +src/models/register_request/type.hpp +src/models/register_request/fwd.hpp src/models/lesson_week_type/type.hpp src/models/lesson_week_type/serialize.hpp src/models/lesson_week_type/serialize.cpp diff --git a/api/views/register/RequestV1.yaml b/api/views/register/RequestV1.yaml index d905e885..b9aa72c9 100644 --- a/api/views/register/RequestV1.yaml +++ b/api/views/register/RequestV1.yaml @@ -1,5 +1,10 @@ properties: user_credential: $ref: '../../types/UserCredentialV1.yaml' - user_type: + desired_type: $ref: '../../types/UserTypeV1.yaml' + description: + type: string + description: Дополнительная информация для администраторов при регистрации (в рамках запроса привиллегий преподавателя или администратора) +required: + - user_credential diff --git a/benchs/hello_benchmark.cpp b/benchs/hello_benchmark.cpp index 1d684066..7e4ddaf2 100644 --- a/benchs/hello_benchmark.cpp +++ b/benchs/hello_benchmark.cpp @@ -7,12 +7,14 @@ #include "views/hello/view.hpp" -void HelloBenchmark(benchmark::State& state) { +void HelloBenchmark(benchmark::State& state) +{ userver::engine::RunStandalone([&] { constexpr std::string_view kNames[] = {"userver", "is", "awesome", "!"}; std::uint64_t i = 0; - for (auto _ : state) { + for (auto _ : state) + { const auto name = kNames[i++ % std::size(kNames)]; auto result = service_template::SayHelloTo( name, service_template::UserType::kKnown); diff --git a/postgresql/data/initial_data_auth_admin.sql b/postgresql/data/initial_data_auth_admin.sql index 021d3960..fe7207e1 100644 --- a/postgresql/data/initial_data_auth_admin.sql +++ b/postgresql/data/initial_data_auth_admin.sql @@ -1,6 +1,6 @@ -INSERT INTO vsu_timetable.user(login, password, id) +INSERT INTO timetable_vsu.user(login, password, id) VALUES('some_admin', 'admin_password', '333111c7-9654-4814-b36b-7d39c1ddded2'); -INSERT INTO vsu_timetable."admin" +INSERT INTO timetable_vsu."admin" (id, id_user) VALUES('000111c7-9654-4814-b36b-7d39c1ddded2', '333111c7-9654-4814-b36b-7d39c1ddded2'); diff --git a/postgresql/data/initial_data_auth_admin_token.sql b/postgresql/data/initial_data_auth_admin_token.sql index 3e42b7f8..86ac4162 100644 --- a/postgresql/data/initial_data_auth_admin_token.sql +++ b/postgresql/data/initial_data_auth_admin_token.sql @@ -1,3 +1,3 @@ -INSERT INTO vsu_timetable.token +INSERT INTO timetable_vsu.token (id, id_user) VALUES('333111c7-9654-4814-b36b-7d39c1ddded2', '333111c7-9654-4814-b36b-7d39c1ddded2'); diff --git a/postgresql/data/initial_data_auth_root.sql b/postgresql/data/initial_data_auth_root.sql index f06db5a4..4760aefc 100644 --- a/postgresql/data/initial_data_auth_root.sql +++ b/postgresql/data/initial_data_auth_root.sql @@ -1,2 +1,2 @@ -INSERT INTO vsu_timetable.user(login, password, id) +INSERT INTO timetable_vsu.user(login, password, id) VALUES('root', 'secret-password', 'dddddddd-dddd-dddd-dddd-dddddddddddd'); diff --git a/postgresql/data/initial_data_auth_root_token.sql b/postgresql/data/initial_data_auth_root_token.sql index 025cd6e1..f3b83286 100644 --- a/postgresql/data/initial_data_auth_root_token.sql +++ b/postgresql/data/initial_data_auth_root_token.sql @@ -1,3 +1,3 @@ -INSERT INTO vsu_timetable.token +INSERT INTO timetable_vsu.token (id, id_user) VALUES('dddddddd-dddd-dddd-dddd-dddddddddddd', 'dddddddd-dddd-dddd-dddd-dddddddddddd'); diff --git a/postgresql/data/initial_data_auth_teacher.sql b/postgresql/data/initial_data_auth_teacher.sql index 2a460bc8..f88bbebb 100644 --- a/postgresql/data/initial_data_auth_teacher.sql +++ b/postgresql/data/initial_data_auth_teacher.sql @@ -1,18 +1,18 @@ -INSERT INTO vsu_timetable.faculty +INSERT INTO timetable_vsu.faculty (id, "name") VALUES('999111c7-9654-4814-bbbb-7d39c1ddded2', ''); -INSERT INTO vsu_timetable.department +INSERT INTO timetable_vsu.department (id, "name", id_faculty) VALUES('555111c7-9654-4814-cccc-7d39c1ddded2', '', '999111c7-9654-4814-bbbb-7d39c1ddded2'); -INSERT INTO vsu_timetable.teacher +INSERT INTO timetable_vsu.teacher (id, fio, bio, id_department) VALUES('222111c7-9654-4814-dddd-7d39c1ddded2', '', '', '555111c7-9654-4814-cccc-7d39c1ddded2'); -INSERT INTO vsu_timetable.user(login, password, id) +INSERT INTO timetable_vsu.user(login, password, id) VALUES('some_teacher', 'teacher_password', '222111c7-9654-4814-b36b-7d39c1ddded2'); -INSERT INTO vsu_timetable.teacher_link +INSERT INTO timetable_vsu.teacher_link (id, id_user, id_teacher) VALUES('666111c7-9654-4814-b36b-7d39c1ddded2', '222111c7-9654-4814-b36b-7d39c1ddded2', '222111c7-9654-4814-dddd-7d39c1ddded2'); diff --git a/postgresql/data/initial_data_auth_teacher_token.sql b/postgresql/data/initial_data_auth_teacher_token.sql index 63d41bbd..20140161 100644 --- a/postgresql/data/initial_data_auth_teacher_token.sql +++ b/postgresql/data/initial_data_auth_teacher_token.sql @@ -1,3 +1,3 @@ -INSERT INTO vsu_timetable.token +INSERT INTO timetable_vsu.token (id, id_user) VALUES('222111c7-9654-4814-b36b-7d39c1ddded2', '222111c7-9654-4814-b36b-7d39c1ddded2'); diff --git a/postgresql/data/initial_data_auth_user.sql b/postgresql/data/initial_data_auth_user.sql index 5c39c20d..8a338dcc 100644 --- a/postgresql/data/initial_data_auth_user.sql +++ b/postgresql/data/initial_data_auth_user.sql @@ -1,2 +1,2 @@ -INSERT INTO vsu_timetable.user(login, password, id) +INSERT INTO timetable_vsu.user(login, password, id) VALUES('some_user', 'user_password', '111111c7-9654-4814-b36b-7d39c1ddded2'); diff --git a/postgresql/data/initial_data_auth_user_token.sql b/postgresql/data/initial_data_auth_user_token.sql index 7a58b6fc..a7ca3d28 100644 --- a/postgresql/data/initial_data_auth_user_token.sql +++ b/postgresql/data/initial_data_auth_user_token.sql @@ -1,3 +1,3 @@ -INSERT INTO vsu_timetable.token +INSERT INTO timetable_vsu.token (id, id_user) VALUES('111111c7-9654-4814-b36b-7d39c1ddded2', '111111c7-9654-4814-b36b-7d39c1ddded2'); diff --git a/postgresql/data/initial_data_timetable1.sql b/postgresql/data/initial_data_timetable1.sql index c7367bdd..c76dfc48 100644 --- a/postgresql/data/initial_data_timetable1.sql +++ b/postgresql/data/initial_data_timetable1.sql @@ -1,37 +1,37 @@ -- Insert test data into the faculty table -INSERT INTO vsu_timetable.faculty (id, name) +INSERT INTO timetable_vsu.faculty (id, name) VALUES ('bbc6312c-f25e-4db3-b2a0-3f5dc6717a8d', 'Faculty of Mathematics and Mechanics'); -- Insert test data into the department table -INSERT INTO vsu_timetable.department (id, name, id_faculty) +INSERT INTO timetable_vsu.department (id, name, id_faculty) VALUES ('1f93ceb4-d931-4b66-a0e5-7323d6b60f3b', 'Department of Applied Mathematics', 'bbc6312c-f25e-4db3-b2a0-3f5dc6717a8d'); -- Insert test data into the teacher table -INSERT INTO vsu_timetable.teacher (id, fio, bio, id_department) +INSERT INTO timetable_vsu.teacher (id, fio, bio, id_department) VALUES ('241416c7-9654-4814-b36b-7d39c1ddded2', 'John Doe', 'Professor of Mathematics', '1f93ceb4-d931-4b66-a0e5-7323d6b60f3b'); -- Insert test data into the group table -INSERT INTO vsu_timetable.group (id, name, type) +INSERT INTO timetable_vsu.group (id, name, type) VALUES ('c1fb3eac-de6d-44ef-bf35-18bebe832e1d', 'MM-21', 'magistracy'); -- Insert test data into the group_stage table -INSERT INTO vsu_timetable.group_stage (id, begin, "end", course, id_group) +INSERT INTO timetable_vsu.group_stage (id, begin, "end", course, id_group) VALUES ('4148147a-740b-48f9-aba1-47eb17432855', '2023-09-01 00:00:00', '2024-06-30 00:00:00', 1, 'c1fb3eac-de6d-44ef-bf35-18bebe832e1d'); -- Insert test data into the room table -INSERT INTO vsu_timetable.room (id, name) +INSERT INTO timetable_vsu.room (id, name) VALUES ('f245127f-a730-4d13-a15d-7648deb1d4d2', '101'); -- Insert test data into the subject table -INSERT INTO vsu_timetable.subject (id, name) +INSERT INTO timetable_vsu.subject (id, name) VALUES ('053222c5-315a-4301-abfe-586d2409fcd3', 'Mathematics'); -- Insert test data into the shedule table -INSERT INTO vsu_timetable.shedule (id, id_teacher, id_subject, id_group_stage) +INSERT INTO timetable_vsu.shedule (id, id_teacher, id_subject, id_group_stage) VALUES ('ab5f0559-d2ee-4030-919e-5962f1ff2235', '241416c7-9654-4814-b36b-7d39c1ddded2', '053222c5-315a-4301-abfe-586d2409fcd3', '4148147a-740b-48f9-aba1-47eb17432855'); -- Insert test data into the lesson table -INSERT INTO vsu_timetable.lesson (id, begin, "end", number_lesson, type_lesson, type_week, subgroup, day, id_room, id_shedule) +INSERT INTO timetable_vsu.lesson (id, begin, "end", number_lesson, type_lesson, type_week, subgroup, day, id_room, id_shedule) VALUES ('3d04fc36-ab71-42db-9e38-efd792afa7ba', '2023-04-01 08:30:00', '2023-05-01 10:05:00', 1, 'lection', 'all', 'all', 'monday', 'f245127f-a730-4d13-a15d-7648deb1d4d2', 'ab5f0559-d2ee-4030-919e-5962f1ff2235'); diff --git a/postgresql/data/initial_data_timetable2.sql b/postgresql/data/initial_data_timetable2.sql index 6d7e239b..c5df505a 100644 --- a/postgresql/data/initial_data_timetable2.sql +++ b/postgresql/data/initial_data_timetable2.sql @@ -1,37 +1,37 @@ -- Insert test data into the faculty table -INSERT INTO vsu_timetable.faculty (id, name) +INSERT INTO timetable_vsu.faculty (id, name) VALUES ('af8f26b8-afc7-483d-b6cc-ffaec29d4bc7', 'ПММ'); -- Insert test data into the department table -INSERT INTO vsu_timetable.department (id, name, id_faculty) +INSERT INTO timetable_vsu.department (id, name, id_faculty) VALUES ('3ec37598-6c49-4a02-8134-d9dbffafa8c4', 'МОЭВМ', 'af8f26b8-afc7-483d-b6cc-ffaec29d4bc7'); -- Insert test data into the teacher table -INSERT INTO vsu_timetable.teacher (id, fio, bio, id_department) +INSERT INTO timetable_vsu.teacher (id, fio, bio, id_department) VALUES ('dc5bad6f-fcf6-4869-b0e5-5c36aed85cc1', 'УСКОВА О.Ф.', 'ЛУЧШИЙ ПРЕПОД МИРА', '3ec37598-6c49-4a02-8134-d9dbffafa8c4'); -- Insert test data into the group table -INSERT INTO vsu_timetable.group (id, name, type) +INSERT INTO timetable_vsu.group (id, name, type) VALUES ('c8a34f05-f081-4d78-b971-30d562fd9f1c', '62', 'undergraduate'); -- Insert test data into the group_stage table -INSERT INTO vsu_timetable.group_stage (id, begin, "end", course, id_group) +INSERT INTO timetable_vsu.group_stage (id, begin, "end", course, id_group) VALUES ('4f9c8f36-c007-4d1a-9255-4a4ce8d45a96', '2023-09-01 00:00:00', '2024-06-30 00:00:00', 1, 'c8a34f05-f081-4d78-b971-30d562fd9f1c'); -- Insert test data into the room table -INSERT INTO vsu_timetable.room (id, name) +INSERT INTO timetable_vsu.room (id, name) VALUES ('b5a90d34-307f-4ab1-9caf-8b6749189de8', '101'); -- Insert test data into the subject table -INSERT INTO vsu_timetable.subject (id, name) +INSERT INTO timetable_vsu.subject (id, name) VALUES ('6990a617-405e-492a-990f-621ab0411623', 'Mathematics'); -- Insert test data into the shedule table -INSERT INTO vsu_timetable.shedule (id, id_teacher, id_subject, id_group_stage) +INSERT INTO timetable_vsu.shedule (id, id_teacher, id_subject, id_group_stage) VALUES ('75021a69-9ceb-4eec-8151-34f93c0af429', 'dc5bad6f-fcf6-4869-b0e5-5c36aed85cc1', '6990a617-405e-492a-990f-621ab0411623', '4f9c8f36-c007-4d1a-9255-4a4ce8d45a96'); -- Insert test data into the lesson table -INSERT INTO vsu_timetable.lesson (id, begin, "end", number_lesson, type_lesson, type_week, subgroup, day, id_room, id_shedule) +INSERT INTO timetable_vsu.lesson (id, begin, "end", number_lesson, type_lesson, type_week, subgroup, day, id_room, id_shedule) VALUES ('6e3092e3-ac10-47a8-b52b-a15682ecc40c', '2021-09-01 08:30:00', '2021-10-01 10:05:00', 1, 'practice', 'even', 'first', 'monday', 'b5a90d34-307f-4ab1-9caf-8b6749189de8', '75021a69-9ceb-4eec-8151-34f93c0af429'); diff --git a/postgresql/data/timetable_random.sql b/postgresql/data/timetable_random.sql index bc6b743b..d0ca6c7c 100644 --- a/postgresql/data/timetable_random.sql +++ b/postgresql/data/timetable_random.sql @@ -1,47 +1,47 @@ -- Insert test data into the user table -INSERT INTO vsu_timetable.user (login, password) +INSERT INTO timetable_vsu.user (login, password) VALUES ('user1', 'password1'); -- Insert test data into the token table -INSERT INTO vsu_timetable.token (expire_time, id_user) -VALUES ('2023-04-18 12:00:00', (SELECT id FROM vsu_timetable.user ORDER BY random() LIMIT 1)); +INSERT INTO timetable_vsu.token (expire_time, id_user) +VALUES ('2023-04-18 12:00:00', (SELECT id FROM timetable_vsu.user ORDER BY random() LIMIT 1)); -- Insert test data into the admin table -INSERT INTO vsu_timetable.admin (id_user) -VALUES ((SELECT id FROM vsu_timetable.user ORDER BY random() LIMIT 1)); +INSERT INTO timetable_vsu.admin (id_user) +VALUES ((SELECT id FROM timetable_vsu.user ORDER BY random() LIMIT 1)); -- Insert test data into the faculty table -INSERT INTO vsu_timetable.faculty (name) +INSERT INTO timetable_vsu.faculty (name) VALUES ('Faculty of Mathematics and Mechanics'); -- Insert test data into the department table -INSERT INTO vsu_timetable.department (name, id_faculty) -VALUES ('Department of Applied Mathematics', (SELECT id FROM vsu_timetable.faculty ORDER BY random() LIMIT 1)); +INSERT INTO timetable_vsu.department (name, id_faculty) +VALUES ('Department of Applied Mathematics', (SELECT id FROM timetable_vsu.faculty ORDER BY random() LIMIT 1)); -- Insert test data into the teacher table -INSERT INTO vsu_timetable.teacher (fio, bio, id_department) -VALUES ('John Doe', 'Professor of Mathematics', (SELECT id FROM vsu_timetable.department ORDER BY random() LIMIT 1)); +INSERT INTO timetable_vsu.teacher (fio, bio, id_department) +VALUES ('John Doe', 'Professor of Mathematics', (SELECT id FROM timetable_vsu.department ORDER BY random() LIMIT 1)); -- Insert test data into the group table -INSERT INTO vsu_timetable."group" (name, type) +INSERT INTO timetable_vsu."group" (name, type) VALUES ('MM-21', 'magistracy'); -- Insert test data into the group_stage table -INSERT INTO vsu_timetable.group_stage (begin, "end", course, id_group) -VALUES ('2023-09-01 00:00:00', '2024-06-30 00:00:00', 1, (SELECT id FROM vsu_timetable."group" ORDER BY random() LIMIT 1)); +INSERT INTO timetable_vsu.group_stage (begin, "end", course, id_group) +VALUES ('2023-09-01 00:00:00', '2024-06-30 00:00:00', 1, (SELECT id FROM timetable_vsu."group" ORDER BY random() LIMIT 1)); -- Insert test data into the room table -INSERT INTO vsu_timetable.room (name) +INSERT INTO timetable_vsu.room (name) VALUES ('Room 101'); -- Insert test data into the subject table -INSERT INTO vsu_timetable.subject (name) +INSERT INTO timetable_vsu.subject (name) VALUES ('Mathematics'); -- Insert test data into the shedule table -INSERT INTO vsu_timetable.shedule (id_teacher, id_subject, id_group_stage) -VALUES ((SELECT id FROM vsu_timetable.teacher ORDER BY random() LIMIT 1), (SELECT id FROM vsu_timetable.subject ORDER BY random() LIMIT 1), (SELECT id FROM vsu_timetable.group_stage ORDER BY random() LIMIT 1)); +INSERT INTO timetable_vsu.shedule (id_teacher, id_subject, id_group_stage) +VALUES ((SELECT id FROM timetable_vsu.teacher ORDER BY random() LIMIT 1), (SELECT id FROM timetable_vsu.subject ORDER BY random() LIMIT 1), (SELECT id FROM timetable_vsu.group_stage ORDER BY random() LIMIT 1)); -- Insert test data into the lesson table -INSERT INTO vsu_timetable.lesson (begin, "end", number_lesson, type_lesson, type_week, subgroup, day, id_room, id_shedule) -VALUES ('2023-09-01 08:30:00', '2023-09-01 10:05:00', 1, 'lection', 'all', 'all', 'monday', (SELECT id FROM vsu_timetable.room ORDER BY random() LIMIT 1), (SELECT id FROM vsu_timetable.shedule ORDER BY random() LIMIT 1)); +INSERT INTO timetable_vsu.lesson (begin, "end", number_lesson, type_lesson, type_week, subgroup, day, id_room, id_shedule) +VALUES ('2023-09-01 08:30:00', '2023-09-01 10:05:00', 1, 'lection', 'all', 'all', 'monday', (SELECT id FROM timetable_vsu.room ORDER BY random() LIMIT 1), (SELECT id FROM timetable_vsu.shedule ORDER BY random() LIMIT 1)); diff --git a/postgresql/schemas/db_1/000_init.sql b/postgresql/schemas/db_1/000_init.sql index b0d49e7a..8343009f 100755 --- a/postgresql/schemas/db_1/000_init.sql +++ b/postgresql/schemas/db_1/000_init.sql @@ -1,21 +1,21 @@ BEGIN; CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -DROP SCHEMA IF EXISTS vsu_timetable CASCADE; +DROP SCHEMA IF EXISTS timetable_vsu CASCADE; -CREATE SCHEMA vsu_timetable; +CREATE SCHEMA timetable_vsu; -DROP TABLE IF EXISTS vsu_timetable."user" CASCADE; -CREATE TABLE vsu_timetable."user" ( +DROP TABLE IF EXISTS timetable_vsu."user" CASCADE; +CREATE TABLE timetable_vsu."user" ( id uuid NOT NULL DEFAULT uuid_generate_v4(), login text, password text, CONSTRAINT user_pk PRIMARY KEY (id) ); -DROP TABLE IF EXISTS vsu_timetable.token CASCADE; -CREATE TABLE vsu_timetable.token ( +DROP TABLE IF EXISTS timetable_vsu.token CASCADE; +CREATE TABLE timetable_vsu.token ( id uuid NOT NULL DEFAULT uuid_generate_v4(), expire_time timestamptz, id_user uuid NOT NULL, @@ -23,24 +23,24 @@ CREATE TABLE vsu_timetable.token ( ); -ALTER TABLE vsu_timetable.token DROP CONSTRAINT IF EXISTS user_fk CASCADE; -ALTER TABLE vsu_timetable.token ADD CONSTRAINT user_fk FOREIGN KEY (id_user) REFERENCES vsu_timetable."user" (id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE timetable_vsu.token DROP CONSTRAINT IF EXISTS user_fk CASCADE; +ALTER TABLE timetable_vsu.token ADD CONSTRAINT user_fk FOREIGN KEY (id_user) REFERENCES timetable_vsu."user" (id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE; -DROP TABLE IF EXISTS vsu_timetable.admin CASCADE; -CREATE TABLE vsu_timetable.admin ( +DROP TABLE IF EXISTS timetable_vsu.admin CASCADE; +CREATE TABLE timetable_vsu.admin ( id uuid NOT NULL DEFAULT uuid_generate_v4(), id_user uuid NOT NULL, CONSTRAINT admin_pk PRIMARY KEY (id) ); -ALTER TABLE vsu_timetable.admin DROP CONSTRAINT IF EXISTS user_fk CASCADE; -ALTER TABLE vsu_timetable.admin ADD CONSTRAINT user_fk FOREIGN KEY (id_user) REFERENCES vsu_timetable."user" (id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE; -ALTER TABLE vsu_timetable.admin DROP CONSTRAINT IF EXISTS admin_user_unique CASCADE; -ALTER TABLE vsu_timetable.admin ADD CONSTRAINT admin_user_unique UNIQUE(id_user); +ALTER TABLE timetable_vsu.admin DROP CONSTRAINT IF EXISTS user_fk CASCADE; +ALTER TABLE timetable_vsu.admin ADD CONSTRAINT user_fk FOREIGN KEY (id_user) REFERENCES timetable_vsu."user" (id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE; +ALTER TABLE timetable_vsu.admin DROP CONSTRAINT IF EXISTS admin_user_unique CASCADE; +ALTER TABLE timetable_vsu.admin ADD CONSTRAINT admin_user_unique UNIQUE(id_user); -DROP TABLE IF EXISTS vsu_timetable.faculty CASCADE; -CREATE TABLE vsu_timetable.faculty ( +DROP TABLE IF EXISTS timetable_vsu.faculty CASCADE; +CREATE TABLE timetable_vsu.faculty ( id uuid NOT NULL DEFAULT uuid_generate_v4(), name text, CONSTRAINT faculty_pk PRIMARY KEY (id) @@ -48,8 +48,8 @@ CREATE TABLE vsu_timetable.faculty ( -DROP TABLE IF EXISTS vsu_timetable.department CASCADE; -CREATE TABLE vsu_timetable.department ( +DROP TABLE IF EXISTS timetable_vsu.department CASCADE; +CREATE TABLE timetable_vsu.department ( id uuid NOT NULL DEFAULT uuid_generate_v4(), name text, id_faculty uuid, @@ -58,14 +58,14 @@ CREATE TABLE vsu_timetable.department ( -ALTER TABLE vsu_timetable.department DROP CONSTRAINT IF EXISTS faculty_fk CASCADE; -ALTER TABLE vsu_timetable.department ADD CONSTRAINT faculty_fk FOREIGN KEY (id_faculty) -REFERENCES vsu_timetable.faculty (id) MATCH FULL +ALTER TABLE timetable_vsu.department DROP CONSTRAINT IF EXISTS faculty_fk CASCADE; +ALTER TABLE timetable_vsu.department ADD CONSTRAINT faculty_fk FOREIGN KEY (id_faculty) +REFERENCES timetable_vsu.faculty (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -CREATE TABLE vsu_timetable.teacher ( +CREATE TABLE timetable_vsu.teacher ( id uuid NOT NULL DEFAULT uuid_generate_v4(), fio text, bio text, @@ -75,31 +75,31 @@ CREATE TABLE vsu_timetable.teacher ( -ALTER TABLE vsu_timetable.teacher DROP CONSTRAINT IF EXISTS department_fk CASCADE; -ALTER TABLE vsu_timetable.teacher ADD CONSTRAINT department_fk FOREIGN KEY (id_department) -REFERENCES vsu_timetable.department (id) MATCH FULL +ALTER TABLE timetable_vsu.teacher DROP CONSTRAINT IF EXISTS department_fk CASCADE; +ALTER TABLE timetable_vsu.teacher ADD CONSTRAINT department_fk FOREIGN KEY (id_department) +REFERENCES timetable_vsu.department (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -DROP TYPE IF EXISTS vsu_timetable.grouptype CASCADE; -CREATE TYPE vsu_timetable.grouptype AS +DROP TYPE IF EXISTS timetable_vsu.grouptype CASCADE; +CREATE TYPE timetable_vsu.grouptype AS ENUM ('undergraduate','magistracy','postgraduate','specialty'); -DROP TABLE IF EXISTS vsu_timetable."group" CASCADE; -CREATE TABLE vsu_timetable."group" ( +DROP TABLE IF EXISTS timetable_vsu."group" CASCADE; +CREATE TABLE timetable_vsu."group" ( id uuid NOT NULL DEFAULT uuid_generate_v4(), name text, - type vsu_timetable.grouptype, + type timetable_vsu.grouptype, CONSTRAINT group_pk PRIMARY KEY (id) ); -DROP TABLE IF EXISTS vsu_timetable.group_stage CASCADE; -CREATE TABLE vsu_timetable.group_stage ( +DROP TABLE IF EXISTS timetable_vsu.group_stage CASCADE; +CREATE TABLE timetable_vsu.group_stage ( id uuid NOT NULL DEFAULT uuid_generate_v4(), begin timestamptz, "end" timestamptz, @@ -110,15 +110,15 @@ CREATE TABLE vsu_timetable.group_stage ( -ALTER TABLE vsu_timetable.group_stage DROP CONSTRAINT IF EXISTS group_fk CASCADE; -ALTER TABLE vsu_timetable.group_stage ADD CONSTRAINT group_fk FOREIGN KEY (id_group) -REFERENCES vsu_timetable."group" (id) MATCH FULL +ALTER TABLE timetable_vsu.group_stage DROP CONSTRAINT IF EXISTS group_fk CASCADE; +ALTER TABLE timetable_vsu.group_stage ADD CONSTRAINT group_fk FOREIGN KEY (id_group) +REFERENCES timetable_vsu."group" (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -DROP TABLE IF EXISTS vsu_timetable.room CASCADE; -CREATE TABLE vsu_timetable.room ( +DROP TABLE IF EXISTS timetable_vsu.room CASCADE; +CREATE TABLE timetable_vsu.room ( id uuid NOT NULL DEFAULT uuid_generate_v4(), name text, CONSTRAINT room_pk PRIMARY KEY (id) @@ -126,39 +126,39 @@ CREATE TABLE vsu_timetable.room ( -DROP TYPE IF EXISTS vsu_timetable.type_lesson CASCADE; -CREATE TYPE vsu_timetable.type_lesson AS +DROP TYPE IF EXISTS timetable_vsu.type_lesson CASCADE; +CREATE TYPE timetable_vsu.type_lesson AS ENUM ('labaratory','lection','practice'); -DROP TYPE IF EXISTS vsu_timetable.type_of_week CASCADE; -CREATE TYPE vsu_timetable.type_of_week AS +DROP TYPE IF EXISTS timetable_vsu.type_of_week CASCADE; +CREATE TYPE timetable_vsu.type_of_week AS ENUM ('all','even','odd'); -DROP TYPE IF EXISTS vsu_timetable.subgroup CASCADE; -CREATE TYPE vsu_timetable.subgroup AS +DROP TYPE IF EXISTS timetable_vsu.subgroup CASCADE; +CREATE TYPE timetable_vsu.subgroup AS ENUM ('all','first','second'); -DROP TYPE IF EXISTS vsu_timetable.day CASCADE; -CREATE TYPE vsu_timetable.day AS +DROP TYPE IF EXISTS timetable_vsu.day CASCADE; +CREATE TYPE timetable_vsu.day AS ENUM ('monday','tuesday','wednesday','thursday', 'friday', 'saturday'); -DROP TABLE IF EXISTS vsu_timetable.lesson CASCADE; -CREATE TABLE vsu_timetable.lesson ( +DROP TABLE IF EXISTS timetable_vsu.lesson CASCADE; +CREATE TABLE timetable_vsu.lesson ( id uuid NOT NULL DEFAULT uuid_generate_v4(), begin timestamptz, "end" timestamptz, number_lesson smallint, - type_lesson vsu_timetable.type_lesson, - type_week vsu_timetable.type_of_week, - subgroup vsu_timetable.subgroup, - day vsu_timetable.day, + type_lesson timetable_vsu.type_lesson, + type_week timetable_vsu.type_of_week, + subgroup timetable_vsu.subgroup, + day timetable_vsu.day, id_room uuid, id_shedule uuid, CONSTRAINT lesson_pk PRIMARY KEY (id) @@ -167,8 +167,8 @@ CREATE TABLE vsu_timetable.lesson ( -DROP TABLE IF EXISTS vsu_timetable.subject CASCADE; -CREATE TABLE vsu_timetable.subject ( +DROP TABLE IF EXISTS timetable_vsu.subject CASCADE; +CREATE TABLE timetable_vsu.subject ( id uuid NOT NULL DEFAULT uuid_generate_v4(), name text, CONSTRAINT subject_pk PRIMARY KEY (id) @@ -177,15 +177,15 @@ CREATE TABLE vsu_timetable.subject ( -ALTER TABLE vsu_timetable.lesson DROP CONSTRAINT IF EXISTS room_fk CASCADE; -ALTER TABLE vsu_timetable.lesson ADD CONSTRAINT room_fk FOREIGN KEY (id_room) -REFERENCES vsu_timetable.room (id) MATCH FULL +ALTER TABLE timetable_vsu.lesson DROP CONSTRAINT IF EXISTS room_fk CASCADE; +ALTER TABLE timetable_vsu.lesson ADD CONSTRAINT room_fk FOREIGN KEY (id_room) +REFERENCES timetable_vsu.room (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -DROP TABLE IF EXISTS vsu_timetable.shedule CASCADE; -CREATE TABLE vsu_timetable.shedule ( +DROP TABLE IF EXISTS timetable_vsu.shedule CASCADE; +CREATE TABLE timetable_vsu.shedule ( id uuid NOT NULL DEFAULT uuid_generate_v4(), id_teacher uuid, id_subject uuid, @@ -196,36 +196,36 @@ CREATE TABLE vsu_timetable.shedule ( -ALTER TABLE vsu_timetable.shedule DROP CONSTRAINT IF EXISTS teacher_fk CASCADE; -ALTER TABLE vsu_timetable.shedule ADD CONSTRAINT teacher_fk FOREIGN KEY (id_teacher) -REFERENCES vsu_timetable.teacher (id) MATCH FULL +ALTER TABLE timetable_vsu.shedule DROP CONSTRAINT IF EXISTS teacher_fk CASCADE; +ALTER TABLE timetable_vsu.shedule ADD CONSTRAINT teacher_fk FOREIGN KEY (id_teacher) +REFERENCES timetable_vsu.teacher (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -ALTER TABLE vsu_timetable.shedule DROP CONSTRAINT IF EXISTS subject_fk CASCADE; -ALTER TABLE vsu_timetable.shedule ADD CONSTRAINT subject_fk FOREIGN KEY (id_subject) -REFERENCES vsu_timetable.subject (id) MATCH FULL +ALTER TABLE timetable_vsu.shedule DROP CONSTRAINT IF EXISTS subject_fk CASCADE; +ALTER TABLE timetable_vsu.shedule ADD CONSTRAINT subject_fk FOREIGN KEY (id_subject) +REFERENCES timetable_vsu.subject (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -ALTER TABLE vsu_timetable.shedule DROP CONSTRAINT IF EXISTS group_stage_fk CASCADE; -ALTER TABLE vsu_timetable.shedule ADD CONSTRAINT group_stage_fk FOREIGN KEY (id_group_stage) -REFERENCES vsu_timetable.group_stage (id) MATCH FULL +ALTER TABLE timetable_vsu.shedule DROP CONSTRAINT IF EXISTS group_stage_fk CASCADE; +ALTER TABLE timetable_vsu.shedule ADD CONSTRAINT group_stage_fk FOREIGN KEY (id_group_stage) +REFERENCES timetable_vsu.group_stage (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -ALTER TABLE vsu_timetable.lesson DROP CONSTRAINT IF EXISTS shedule_fk CASCADE; -ALTER TABLE vsu_timetable.lesson ADD CONSTRAINT shedule_fk FOREIGN KEY (id_shedule) -REFERENCES vsu_timetable.shedule (id) MATCH FULL +ALTER TABLE timetable_vsu.lesson DROP CONSTRAINT IF EXISTS shedule_fk CASCADE; +ALTER TABLE timetable_vsu.lesson ADD CONSTRAINT shedule_fk FOREIGN KEY (id_shedule) +REFERENCES timetable_vsu.shedule (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -DROP TABLE IF EXISTS vsu_timetable.teacher_link CASCADE; -CREATE TABLE vsu_timetable.teacher_link ( +DROP TABLE IF EXISTS timetable_vsu.teacher_link CASCADE; +CREATE TABLE timetable_vsu.teacher_link ( id uuid NOT NULL DEFAULT uuid_generate_v4(), id_user uuid, id_teacher uuid NOT NULL, @@ -235,23 +235,23 @@ CREATE TABLE vsu_timetable.teacher_link ( -ALTER TABLE vsu_timetable.teacher_link DROP CONSTRAINT IF EXISTS user_fk CASCADE; -ALTER TABLE vsu_timetable.teacher_link ADD CONSTRAINT user_fk FOREIGN KEY (id_user) -REFERENCES vsu_timetable."user" (id) MATCH FULL +ALTER TABLE timetable_vsu.teacher_link DROP CONSTRAINT IF EXISTS user_fk CASCADE; +ALTER TABLE timetable_vsu.teacher_link ADD CONSTRAINT user_fk FOREIGN KEY (id_user) +REFERENCES timetable_vsu."user" (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -ALTER TABLE vsu_timetable.teacher_link DROP CONSTRAINT IF EXISTS teacher_fk CASCADE; -ALTER TABLE vsu_timetable.teacher_link ADD CONSTRAINT teacher_fk FOREIGN KEY (id_teacher) -REFERENCES vsu_timetable.teacher (id) MATCH FULL +ALTER TABLE timetable_vsu.teacher_link DROP CONSTRAINT IF EXISTS teacher_fk CASCADE; +ALTER TABLE timetable_vsu.teacher_link ADD CONSTRAINT teacher_fk FOREIGN KEY (id_teacher) +REFERENCES timetable_vsu.teacher (id) MATCH FULL ON DELETE SET NULL ON UPDATE CASCADE; -ALTER TABLE vsu_timetable.teacher_link DROP CONSTRAINT IF EXISTS teacher_link_user_unique CASCADE; -ALTER TABLE vsu_timetable.teacher_link ADD CONSTRAINT teacher_link_user_unique UNIQUE (id_user); +ALTER TABLE timetable_vsu.teacher_link DROP CONSTRAINT IF EXISTS teacher_link_user_unique CASCADE; +ALTER TABLE timetable_vsu.teacher_link ADD CONSTRAINT teacher_link_user_unique UNIQUE (id_user); -ALTER TABLE vsu_timetable.teacher_link DROP CONSTRAINT IF EXISTS teacher_unique CASCADE; -ALTER TABLE vsu_timetable.teacher_link ADD CONSTRAINT teacher_unique UNIQUE (id_teacher); +ALTER TABLE timetable_vsu.teacher_link DROP CONSTRAINT IF EXISTS teacher_unique CASCADE; +ALTER TABLE timetable_vsu.teacher_link ADD CONSTRAINT teacher_unique UNIQUE (id_teacher); COMMIT; diff --git a/postgresql/schemas/db_1/002_add_lesson_filter.sql b/postgresql/schemas/db_1/002_add_lesson_filter.sql index 790e91f5..8a557f44 100644 --- a/postgresql/schemas/db_1/002_add_lesson_filter.sql +++ b/postgresql/schemas/db_1/002_add_lesson_filter.sql @@ -1,12 +1,12 @@ BEGIN; -DROP TYPE IF EXISTS vsu_timetable.lesson_filter; -CREATE TYPE vsu_timetable.lesson_filter AS +DROP TYPE IF EXISTS timetable_vsu.lesson_filter; +CREATE TYPE timetable_vsu.lesson_filter AS ( lesson_ids uuid[], begin timestamptz, "end" timestamptz, - days vsu_timetable.day[], + days timetable_vsu.day[], department_ids uuid[], department_names text[], faculty_ids uuid[], @@ -14,17 +14,17 @@ CREATE TYPE vsu_timetable.lesson_filter AS group_ids uuid[], group_names text[], group_courses SMALLINT[], - group_types vsu_timetable.grouptype[], + group_types timetable_vsu.grouptype[], room_ids uuid[], room_names text[], - subgroup vsu_timetable.subgroup, + subgroup timetable_vsu.subgroup, subject_ids uuid[], subject_names text[], teacher_ids uuid[], teacher_fios text[], teacher_bios text[], - week vsu_timetable.type_of_week, - lesson_type vsu_timetable.type_lesson, + week timetable_vsu.type_of_week, + lesson_type timetable_vsu.type_lesson, numbers SMALLINT[] ); diff --git a/postgresql/schemas/db_1/003_add_user.sql b/postgresql/schemas/db_1/003_add_user.sql index 9d320947..add46bd8 100644 --- a/postgresql/schemas/db_1/003_add_user.sql +++ b/postgresql/schemas/db_1/003_add_user.sql @@ -1,18 +1,18 @@ BEGIN; -DROP TYPE IF EXISTS vsu_timetable.user_type CASCADE; -CREATE TYPE vsu_timetable.user_type AS +DROP TYPE IF EXISTS timetable_vsu.user_type CASCADE; +CREATE TYPE timetable_vsu.user_type AS ENUM ('user','admin','teacher'); -DROP TYPE IF EXISTS vsu_timetable.userV1; -CREATE TYPE vsu_timetable.userV1 AS +DROP TYPE IF EXISTS timetable_vsu.userV1; +CREATE TYPE timetable_vsu.userV1 AS ( id uuid, - type vsu_timetable.user_type + type timetable_vsu.user_type ); -DROP TYPE IF EXISTS vsu_timetable.user_credentials; -CREATE TYPE vsu_timetable.user_credentials AS +DROP TYPE IF EXISTS timetable_vsu.user_credentials; +CREATE TYPE timetable_vsu.user_credentials AS ( login text, password text diff --git a/postgresql/schemas/db_1/004_cascade_delete_on_token.sql b/postgresql/schemas/db_1/004_cascade_delete_on_token.sql index c82b831b..83406f13 100644 --- a/postgresql/schemas/db_1/004_cascade_delete_on_token.sql +++ b/postgresql/schemas/db_1/004_cascade_delete_on_token.sql @@ -1,6 +1,6 @@ BEGIN; -ALTER TABLE vsu_timetable.token DROP CONSTRAINT IF EXISTS user_fk CASCADE; -ALTER TABLE vsu_timetable.token ADD CONSTRAINT user_fk FOREIGN KEY (id_user) REFERENCES vsu_timetable."user" (id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE timetable_vsu.token DROP CONSTRAINT IF EXISTS user_fk CASCADE; +ALTER TABLE timetable_vsu.token ADD CONSTRAINT user_fk FOREIGN KEY (id_user) REFERENCES timetable_vsu."user" (id) MATCH FULL ON DELETE CASCADE ON UPDATE CASCADE; COMMIT; diff --git a/postgresql/schemas/db_1/005_add_admin_account.sql b/postgresql/schemas/db_1/005_add_admin_account.sql index af70772c..ba26d660 100644 --- a/postgresql/schemas/db_1/005_add_admin_account.sql +++ b/postgresql/schemas/db_1/005_add_admin_account.sql @@ -1,7 +1,7 @@ BEGIN; -DROP TYPE IF EXISTS vsu_timetable.admin_account; -CREATE TYPE vsu_timetable.admin_account AS +DROP TYPE IF EXISTS timetable_vsu.admin_account; +CREATE TYPE timetable_vsu.admin_account AS ( user_id uuid, admin_id uuid diff --git a/postgresql/schemas/db_1/006_unique_login_user.sql b/postgresql/schemas/db_1/006_unique_login_user.sql index aac9f4bd..8d2ceb8e 100644 --- a/postgresql/schemas/db_1/006_unique_login_user.sql +++ b/postgresql/schemas/db_1/006_unique_login_user.sql @@ -1,6 +1,6 @@ BEGIN; -ALTER TABLE vsu_timetable.user DROP CONSTRAINT IF EXISTS user_login_unique CASCADE; -ALTER TABLE vsu_timetable.user ADD CONSTRAINT user_login_unique UNIQUE(login); +ALTER TABLE timetable_vsu.user DROP CONSTRAINT IF EXISTS user_login_unique CASCADE; +ALTER TABLE timetable_vsu.user ADD CONSTRAINT user_login_unique UNIQUE(login); COMMIT; diff --git a/postgresql/schemas/db_1/007_add_admin_filter.sql b/postgresql/schemas/db_1/007_add_admin_filter.sql index db3ec10f..3b9c97d2 100644 --- a/postgresql/schemas/db_1/007_add_admin_filter.sql +++ b/postgresql/schemas/db_1/007_add_admin_filter.sql @@ -1,7 +1,7 @@ BEGIN; -DROP TYPE IF EXISTS vsu_timetable.admin_filter; -CREATE TYPE vsu_timetable.admin_filter AS +DROP TYPE IF EXISTS timetable_vsu.admin_filter; +CREATE TYPE timetable_vsu.admin_filter AS ( admin_ids uuid[], user_ids uuid[], diff --git a/postgresql/schemas/db_1/008_add_teacher_filter.sql b/postgresql/schemas/db_1/008_add_teacher_filter.sql index 943d69cf..5699c81d 100644 --- a/postgresql/schemas/db_1/008_add_teacher_filter.sql +++ b/postgresql/schemas/db_1/008_add_teacher_filter.sql @@ -1,7 +1,7 @@ BEGIN; -DROP TYPE IF EXISTS vsu_timetable.teacher_filter; -CREATE TYPE vsu_timetable.teacher_filter AS +DROP TYPE IF EXISTS timetable_vsu.teacher_filter; +CREATE TYPE timetable_vsu.teacher_filter AS ( teacher_ids text[], teacher_fios text[], diff --git a/postgresql/schemas/db_1/009_lesson_filter_change_uuid_to_text.sql b/postgresql/schemas/db_1/009_lesson_filter_change_uuid_to_text.sql index 782eb33e..9323dfc8 100644 --- a/postgresql/schemas/db_1/009_lesson_filter_change_uuid_to_text.sql +++ b/postgresql/schemas/db_1/009_lesson_filter_change_uuid_to_text.sql @@ -1,12 +1,12 @@ BEGIN; -DROP TYPE IF EXISTS vsu_timetable.lesson_filterv2; -CREATE TYPE vsu_timetable.lesson_filter_v2 AS +DROP TYPE IF EXISTS timetable_vsu.lesson_filterv2; +CREATE TYPE timetable_vsu.lesson_filter_v2 AS ( lesson_ids text[], begin timestamptz, "end" timestamptz, - days vsu_timetable.day[], + days timetable_vsu.day[], department_ids text[], department_names text[], faculty_ids text[], @@ -14,17 +14,17 @@ CREATE TYPE vsu_timetable.lesson_filter_v2 AS group_ids text[], group_names text[], group_courses SMALLINT[], - group_types vsu_timetable.grouptype[], + group_types timetable_vsu.grouptype[], room_ids text[], room_names text[], - subgroup vsu_timetable.subgroup, + subgroup timetable_vsu.subgroup, subject_ids text[], subject_names text[], teacher_ids text[], teacher_fios text[], teacher_bios text[], - week vsu_timetable.type_of_week, - lesson_type vsu_timetable.type_lesson, + week timetable_vsu.type_of_week, + lesson_type timetable_vsu.type_lesson, numbers SMALLINT[] ); diff --git a/postgresql/schemas/db_1/010_admin_filter_change_uuid_to_text.sql b/postgresql/schemas/db_1/010_admin_filter_change_uuid_to_text.sql index a494d1f8..8270cb89 100644 --- a/postgresql/schemas/db_1/010_admin_filter_change_uuid_to_text.sql +++ b/postgresql/schemas/db_1/010_admin_filter_change_uuid_to_text.sql @@ -1,7 +1,7 @@ BEGIN; -DROP TYPE IF EXISTS vsu_timetable.admin_filter_v2; -CREATE TYPE vsu_timetable.admin_filter_v2 AS +DROP TYPE IF EXISTS timetable_vsu.admin_filter_v2; +CREATE TYPE timetable_vsu.admin_filter_v2 AS ( admin_ids text[], user_ids text[], diff --git a/postgresql/schemas/db_1/011_create_requests.sql b/postgresql/schemas/db_1/011_create_requests.sql new file mode 100644 index 00000000..4f872a74 --- /dev/null +++ b/postgresql/schemas/db_1/011_create_requests.sql @@ -0,0 +1,33 @@ +BEGIN; + +DROP TABLE IF EXISTS timetable_vsu."teacher_requests" CASCADE; +CREATE TABLE timetable_vsu."teacher_requests" ( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + id_user uuid, + description text +); + +ALTER TABLE timetable_vsu.teacher_requests DROP CONSTRAINT IF EXISTS teacher_requests_user_fk CASCADE; +ALTER TABLE timetable_vsu.teacher_requests ADD CONSTRAINT teacher_requests_user_fk FOREIGN KEY (id_user) +REFERENCES timetable_vsu."user" (id) MATCH FULL +ON DELETE SET NULL ON UPDATE CASCADE; + +ALTER TABLE timetable_vsu.teacher_requests DROP CONSTRAINT IF EXISTS teacher_requests_user_uniq CASCADE; +ALTER TABLE timetable_vsu.teacher_requests ADD CONSTRAINT teacher_requests_user_uniq UNIQUE (id_user); + +DROP TABLE IF EXISTS timetable_vsu."admin_requests" CASCADE; +CREATE TABLE timetable_vsu."admin_requests" ( + id uuid NOT NULL DEFAULT uuid_generate_v4(), + id_user uuid, + description text +); + +ALTER TABLE timetable_vsu.admin_requests DROP CONSTRAINT IF EXISTS admin_requests_user_fk CASCADE; +ALTER TABLE timetable_vsu.admin_requests ADD CONSTRAINT admin_requests_user_fk FOREIGN KEY (id_user) +REFERENCES timetable_vsu."user" (id) MATCH FULL +ON DELETE SET NULL ON UPDATE CASCADE; + +ALTER TABLE timetable_vsu.admin_requests DROP CONSTRAINT IF EXISTS admin_requests_user_uniq CASCADE; +ALTER TABLE timetable_vsu.admin_requests ADD CONSTRAINT admin_requests_user_uniq UNIQUE (id_user); + +COMMIT; diff --git a/service/main.cpp b/service/main.cpp index a94b8b18..05460454 100644 --- a/service/main.cpp +++ b/service/main.cpp @@ -23,7 +23,8 @@ #include "views/teacher/list/view.hpp" #include "views/timetable/get/view.hpp" -int main(int argc, char* argv[]) { +int main(int argc, char* argv[]) +{ using namespace timetable_vsu_backend; auto component_list = userver::components::MinimalServerComponentList() diff --git a/src/components/controllers/postgres/admin/controller.cpp b/src/components/controllers/postgres/admin/controller.cpp index 13ed561b..f34093da 100644 --- a/src/components/controllers/postgres/admin/controller.cpp +++ b/src/components/controllers/postgres/admin/controller.cpp @@ -26,22 +26,28 @@ #include "utils/postgres_helper.hpp" #include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::admin { -vsu_timetable::utils::SharedTransaction Controller::CreateTransaction() { - return vsu_timetable::utils::MakeSharedTransaction(pg_cluster_); +namespace timetable_vsu_backend::components::controllers::postgres::admin +{ +utils::SharedTransaction Controller::CreateTransaction() const +{ + return timetable_vsu_backend::utils::MakeSharedTransaction(pg_cluster_); } + Controller::Controller(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context) : LoggableComponentBase(config, context), pg_cluster_( context.FindComponent("postgres-db-1") - .GetCluster()) { + .GetCluster()) +{ } std::optional Controller::GetAccountByAdminId( const boost::uuids::uuid& admin_id, - vsu_timetable::utils::SharedTransaction transaction) const { - vsu_timetable::utils::FillSharedTransaction(transaction, pg_cluster_); + timetable_vsu_backend::utils::SharedTransaction transaction) const +{ + timetable_vsu_backend::utils::FillSharedTransaction(transaction, + pg_cluster_); auto pg_result = transaction->transaction_.Execute( sql::qGetAdminAccountByAdminId, admin_id); return utils::ConvertPgResultToOptionalItem( @@ -50,12 +56,15 @@ std::optional Controller::GetAccountByAdminId( std::optional Controller::CreateAdmin( const models::UserCredentials& user, - vsu_timetable::utils::SharedTransaction transaction) const { - vsu_timetable::utils::FillSharedTransaction(transaction, pg_cluster_); + timetable_vsu_backend::utils::SharedTransaction transaction) const +{ + timetable_vsu_backend::utils::FillSharedTransaction(transaction, + pg_cluster_); auto tuple_user = utils::convert::DropPropertiesToConstRefs(user); auto result_id = transaction->transaction_.Execute(sql::qCreateAdminAccount, tuple_user); - if (result_id.Size() != 1) { + if (result_id.Size() != 1) + { return std::nullopt; } boost::uuids::uuid admin_id = result_id.AsSingleRow(); @@ -64,8 +73,10 @@ std::optional Controller::CreateAdmin( std::vector Controller::GetByFilter( std::optional& filter, - vsu_timetable::utils::SharedTransaction transaction) const { - vsu_timetable::utils::FillSharedTransaction(transaction, pg_cluster_); + timetable_vsu_backend::utils::SharedTransaction transaction) const +{ + timetable_vsu_backend::utils::FillSharedTransaction(transaction, + pg_cluster_); auto pg_result = utils::PgExecute(transaction, sql::qGetAdminsByFilter, filter); return utils::ConvertPgResultToArray(pg_result); diff --git a/src/components/controllers/postgres/admin/controller.hpp b/src/components/controllers/postgres/admin/controller.hpp index 8a368fdf..01b38d88 100644 --- a/src/components/controllers/postgres/admin/controller.hpp +++ b/src/components/controllers/postgres/admin/controller.hpp @@ -10,23 +10,25 @@ #include "models/user_credentials/type.hpp" #include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::admin { -class Controller final : public userver::components::LoggableComponentBase { +namespace timetable_vsu_backend::components::controllers::postgres::admin +{ +class Controller final : public userver::components::LoggableComponentBase +{ public: using userver::components::LoggableComponentBase::LoggableComponentBase; static constexpr inline std::string_view kName = "admin_controller"; std::optional GetAccountByAdminId( const boost::uuids::uuid& admin_id, - vsu_timetable::utils::SharedTransaction transaction = nullptr) const; + utils::SharedTransaction transaction = nullptr) const; std::optional CreateAdmin( const models::UserCredentials& user, - vsu_timetable::utils::SharedTransaction transaction = nullptr) const; + utils::SharedTransaction transaction = nullptr) const; Controller(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context); std::vector GetByFilter( std::optional& filter, - vsu_timetable::utils::SharedTransaction transaction = nullptr) const; - vsu_timetable::utils::SharedTransaction CreateTransaction(); + utils::SharedTransaction transaction = nullptr) const; + utils::SharedTransaction CreateTransaction() const; protected: userver::storages::postgres::ClusterPtr pg_cluster_; diff --git a/src/components/controllers/postgres/admin/fwd.cpp b/src/components/controllers/postgres/admin/fwd.cpp index ffec1bca..122d2796 100644 --- a/src/components/controllers/postgres/admin/fwd.cpp +++ b/src/components/controllers/postgres/admin/fwd.cpp @@ -4,8 +4,10 @@ #include "controller.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { -void AppendAdminController(userver::components::ComponentList& component_list) { +namespace timetable_vsu_backend::components::controllers::postgres +{ +void AppendAdminController(userver::components::ComponentList& component_list) +{ component_list.Append(); } } // namespace timetable_vsu_backend::components::controllers::postgres diff --git a/src/components/controllers/postgres/admin/fwd.hpp b/src/components/controllers/postgres/admin/fwd.hpp index 22badaa0..adebc89c 100644 --- a/src/components/controllers/postgres/admin/fwd.hpp +++ b/src/components/controllers/postgres/admin/fwd.hpp @@ -1,8 +1,10 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { -namespace admin { +namespace timetable_vsu_backend::components::controllers::postgres +{ +namespace admin +{ class Controller; } void AppendAdminController(userver::components::ComponentList& component_list); diff --git a/src/components/controllers/postgres/admin/sql_queries.hpp b/src/components/controllers/postgres/admin/sql_queries.hpp index 259eb3de..c827900a 100644 --- a/src/components/controllers/postgres/admin/sql_queries.hpp +++ b/src/components/controllers/postgres/admin/sql_queries.hpp @@ -1,14 +1,15 @@ #pragma once #include -namespace timetable_vsu_backend::components::controllers::postgres::admin::sql { +namespace timetable_vsu_backend::components::controllers::postgres::admin::sql +{ const userver::storages::postgres::Query qCreateAdminAccount(R"( WITH created_user AS( - INSERT INTO vsu_timetable."user"(login, password) values ($1.login, $1.password) ON CONFLICT DO NOTHING + INSERT INTO timetable_vsu."user"(login, password) values ($1.login, $1.password) ON CONFLICT DO NOTHING RETURNING id ) -INSERT INTO vsu_timetable."admin"(id_user) +INSERT INTO timetable_vsu."admin"(id_user) SELECT id FROM created_user RETURNING id ; @@ -18,8 +19,8 @@ RETURNING id u.id AS user_id, a.id AS admin_id, u.login AS user_login - FROM vsu_timetable."admin" AS a - LEFT JOIN vsu_timetable."user" AS u ON u.id = a.id_user + FROM timetable_vsu."admin" AS a + LEFT JOIN timetable_vsu."user" AS u ON u.id = a.id_user WHERE a.id = $1 ; )"), @@ -28,8 +29,8 @@ RETURNING id a.id AS admin_id, a.id_user AS user_id, u.login AS login - FROM vsu_timetable.admin AS a - LEFT JOIN vsu_timetable.user AS u ON a.id_user = u.id + FROM timetable_vsu.admin AS a + LEFT JOIN timetable_vsu.user AS u ON a.id_user = u.id ) SELECT user_id, diff --git a/src/components/controllers/postgres/lesson/controller.cpp b/src/components/controllers/postgres/lesson/controller.cpp index 87a32b23..f6c25cf2 100644 --- a/src/components/controllers/postgres/lesson/controller.cpp +++ b/src/components/controllers/postgres/lesson/controller.cpp @@ -24,12 +24,14 @@ #include "utils/postgres_helper.hpp" #include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::lesson { - +namespace timetable_vsu_backend::components::controllers::postgres::lesson +{ std::vector Controller::Search( const std::optional& filter, - vsu_timetable::utils::SharedTransaction transaction) const { - vsu_timetable::utils::FillSharedTransaction(transaction, pg_cluster_); + timetable_vsu_backend::utils::SharedTransaction transaction) const +{ + timetable_vsu_backend::utils::FillSharedTransaction(transaction, + pg_cluster_); auto pg_result = utils::PgExecute(transaction, sql::qGetLessonsByFilter, filter); return utils::ConvertPgResultToArray(pg_result); @@ -39,6 +41,7 @@ Controller::Controller(const userver::components::ComponentConfig& config, : LoggableComponentBase(config, context), pg_cluster_( context.FindComponent("postgres-db-1") - .GetCluster()) { + .GetCluster()) +{ } } // namespace timetable_vsu_backend::components::controllers::postgres::lesson diff --git a/src/components/controllers/postgres/lesson/controller.hpp b/src/components/controllers/postgres/lesson/controller.hpp index 7e8680df..56820248 100644 --- a/src/components/controllers/postgres/lesson/controller.hpp +++ b/src/components/controllers/postgres/lesson/controller.hpp @@ -9,15 +9,18 @@ #include "models/lesson_v1/type.hpp" #include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::lesson { -class Controller final : public userver::components::LoggableComponentBase { +namespace timetable_vsu_backend::components::controllers::postgres::lesson +{ +class Controller final : public userver::components::LoggableComponentBase +{ public: using userver::components::LoggableComponentBase::LoggableComponentBase; static constexpr inline std::string_view kName = "lesson_details_controller"; std::vector Search( const std::optional& filter, - vsu_timetable::utils::SharedTransaction transaction = nullptr) const; + timetable_vsu_backend::utils::SharedTransaction transaction = + nullptr) const; Controller(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context); diff --git a/src/components/controllers/postgres/lesson/fwd.cpp b/src/components/controllers/postgres/lesson/fwd.cpp index 7d2afa92..39a54267 100644 --- a/src/components/controllers/postgres/lesson/fwd.cpp +++ b/src/components/controllers/postgres/lesson/fwd.cpp @@ -4,9 +4,11 @@ #include "controller.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { +namespace timetable_vsu_backend::components::controllers::postgres +{ void AppendLessonDetailsController( - userver::components::ComponentList& component_list) { + userver::components::ComponentList& component_list) +{ component_list.Append(); } } // namespace timetable_vsu_backend::components::controllers::postgres diff --git a/src/components/controllers/postgres/lesson/fwd.hpp b/src/components/controllers/postgres/lesson/fwd.hpp index 178cbba7..7cb4daee 100644 --- a/src/components/controllers/postgres/lesson/fwd.hpp +++ b/src/components/controllers/postgres/lesson/fwd.hpp @@ -1,8 +1,10 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { -namespace lesson { +namespace timetable_vsu_backend::components::controllers::postgres +{ +namespace lesson +{ class Controller; } void AppendLessonDetailsController( diff --git a/src/components/controllers/postgres/lesson/sql_queries.hpp b/src/components/controllers/postgres/lesson/sql_queries.hpp index 4375bde2..c16c88ff 100644 --- a/src/components/controllers/postgres/lesson/sql_queries.hpp +++ b/src/components/controllers/postgres/lesson/sql_queries.hpp @@ -1,8 +1,8 @@ #pragma once #include -namespace timetable_vsu_backend::components::controllers::postgres::lesson:: - sql { +namespace timetable_vsu_backend::components::controllers::postgres::lesson::sql +{ const userver::storages::postgres::Query qGetLessonsByFilter(R"( WITH lesson_info as (SELECT l.id AS lesson_id, @@ -31,15 +31,15 @@ const userver::storages::postgres::Query qGetLessonsByFilter(R"( t.id AS teacher_id, t.fio AS teacher_fio, t.bio AS teacher_bio - FROM vsu_timetable.lesson AS l - LEFT JOIN vsu_timetable.room AS r ON l.id_room = r.id - LEFT JOIN vsu_timetable.shedule AS sh ON l.id_shedule = sh.id - LEFT JOIN vsu_timetable.subject AS s ON sh.id_subject = s.id - LEFT JOIN vsu_timetable.group_stage AS gs ON sh.id_group_stage = gs.id - LEFT JOIN vsu_timetable.group AS g ON gs.id_group = g.id - LEFT JOIN vsu_timetable.teacher AS t ON sh.id_teacher = t.id - LEFT JOIN vsu_timetable.department AS d ON t.id_department = d.id - LEFT JOIN vsu_timetable.faculty AS f ON d.id_faculty = f.id + FROM timetable_vsu.lesson AS l + LEFT JOIN timetable_vsu.room AS r ON l.id_room = r.id + LEFT JOIN timetable_vsu.shedule AS sh ON l.id_shedule = sh.id + LEFT JOIN timetable_vsu.subject AS s ON sh.id_subject = s.id + LEFT JOIN timetable_vsu.group_stage AS gs ON sh.id_group_stage = gs.id + LEFT JOIN timetable_vsu.group AS g ON gs.id_group = g.id + LEFT JOIN timetable_vsu.teacher AS t ON sh.id_teacher = t.id + LEFT JOIN timetable_vsu.department AS d ON t.id_department = d.id + LEFT JOIN timetable_vsu.faculty AS f ON d.id_faculty = f.id ) SELECT lesson_id, diff --git a/src/components/controllers/postgres/teacher/controller.cpp b/src/components/controllers/postgres/teacher/controller.cpp index c7a4ac50..0a4765f0 100644 --- a/src/components/controllers/postgres/teacher/controller.cpp +++ b/src/components/controllers/postgres/teacher/controller.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "models/admin_account/postgre.hpp" @@ -24,26 +25,30 @@ #include "models/teacher_filter/postgre.hpp" #include "models/user_credentials/postgre.hpp" #include "sql_queries.hpp" -#include "userver/storages/postgres/io/type_traits.hpp" #include "utils/convert/drop_properties_ref.hpp" #include "utils/postgres_helper.hpp" #include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::teacher { -vsu_timetable::utils::SharedTransaction Controller::CreateTransaction() { - return vsu_timetable::utils::MakeSharedTransaction(pg_cluster_); +namespace timetable_vsu_backend::components::controllers::postgres::teacher +{ +timetable_vsu_backend::utils::SharedTransaction Controller::CreateTransaction() +{ + return timetable_vsu_backend::utils::MakeSharedTransaction(pg_cluster_); } Controller::Controller(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context) : LoggableComponentBase(config, context), pg_cluster_( context.FindComponent("postgres-db-1") - .GetCluster()) { + .GetCluster()) +{ } std::vector Controller::GetByFilter( std::optional& filter, - vsu_timetable::utils::SharedTransaction transaction) const { - vsu_timetable::utils::FillSharedTransaction(transaction, pg_cluster_); + timetable_vsu_backend::utils::SharedTransaction transaction) const +{ + timetable_vsu_backend::utils::FillSharedTransaction(transaction, + pg_cluster_); auto pg_result = utils::PgExecute(transaction, sql::qGetTeachersByFilter, filter); return utils::ConvertPgResultToArray(pg_result); diff --git a/src/components/controllers/postgres/teacher/controller.hpp b/src/components/controllers/postgres/teacher/controller.hpp index 9dd388ba..dcd79caa 100644 --- a/src/components/controllers/postgres/teacher/controller.hpp +++ b/src/components/controllers/postgres/teacher/controller.hpp @@ -9,8 +9,10 @@ #include "models/teacher_filter/type.hpp" #include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::teacher { -class Controller final : public userver::components::LoggableComponentBase { +namespace timetable_vsu_backend::components::controllers::postgres::teacher +{ +class Controller final : public userver::components::LoggableComponentBase +{ public: using userver::components::LoggableComponentBase::LoggableComponentBase; static constexpr inline std::string_view kName = "teacher_controller"; @@ -18,8 +20,9 @@ class Controller final : public userver::components::LoggableComponentBase { const userver::components::ComponentContext& context); std::vector GetByFilter( std::optional& filter, - vsu_timetable::utils::SharedTransaction transaction = nullptr) const; - vsu_timetable::utils::SharedTransaction CreateTransaction(); + timetable_vsu_backend::utils::SharedTransaction transaction = + nullptr) const; + timetable_vsu_backend::utils::SharedTransaction CreateTransaction(); protected: userver::storages::postgres::ClusterPtr pg_cluster_; diff --git a/src/components/controllers/postgres/teacher/fwd.cpp b/src/components/controllers/postgres/teacher/fwd.cpp index 23917b76..fc9840bd 100644 --- a/src/components/controllers/postgres/teacher/fwd.cpp +++ b/src/components/controllers/postgres/teacher/fwd.cpp @@ -4,9 +4,10 @@ #include "controller.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { -void AppendTeacherController( - userver::components::ComponentList& component_list) { +namespace timetable_vsu_backend::components::controllers::postgres +{ +void AppendTeacherController(userver::components::ComponentList& component_list) +{ component_list.Append(); } } // namespace timetable_vsu_backend::components::controllers::postgres diff --git a/src/components/controllers/postgres/teacher/fwd.hpp b/src/components/controllers/postgres/teacher/fwd.hpp index 65b5c7cf..c284f55b 100644 --- a/src/components/controllers/postgres/teacher/fwd.hpp +++ b/src/components/controllers/postgres/teacher/fwd.hpp @@ -1,8 +1,10 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { -namespace teacher { +namespace timetable_vsu_backend::components::controllers::postgres +{ +namespace teacher +{ class Controller; } void AppendTeacherController( diff --git a/src/components/controllers/postgres/teacher/sql_queries.hpp b/src/components/controllers/postgres/teacher/sql_queries.hpp index 29540533..9eb4cb48 100644 --- a/src/components/controllers/postgres/teacher/sql_queries.hpp +++ b/src/components/controllers/postgres/teacher/sql_queries.hpp @@ -1,8 +1,8 @@ #pragma once #include -namespace timetable_vsu_backend::components::controllers::postgres::teacher:: - sql { +namespace timetable_vsu_backend::components::controllers::postgres::teacher::sql +{ const userver::storages::postgres::Query qGetTeachersByFilter(R"( WITH teacher_info as (SELECT t.id AS teacher_id, @@ -12,9 +12,9 @@ const userver::storages::postgres::Query qGetTeachersByFilter(R"( d.name AS department_name, f.id AS faculty_id, f.name AS faculty_name - FROM vsu_timetable.teacher AS t - LEFT JOIN vsu_timetable.department AS d ON t.id_department = d.id - LEFT JOIN vsu_timetable.faculty AS f ON d.id_faculty = f.id + FROM timetable_vsu.teacher AS t + LEFT JOIN timetable_vsu.department AS d ON t.id_department = d.id + LEFT JOIN timetable_vsu.faculty AS f ON d.id_faculty = f.id ) SELECT teacher_id, diff --git a/src/components/controllers/postgres/token/controller.cpp b/src/components/controllers/postgres/token/controller.cpp index f76816d9..06e5a9a3 100644 --- a/src/components/controllers/postgres/token/controller.cpp +++ b/src/components/controllers/postgres/token/controller.cpp @@ -15,39 +15,41 @@ #include #include "models/user/postgre.hpp" +#include "models/user/type.hpp" #include "models/user_type/postgre.hpp" #include "sql_queries.hpp" +#include "utils/postgres_helper.hpp" +#include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::token { +namespace timetable_vsu_backend::components::controllers::postgres::token +{ Controller::Controller(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context) : LoggableComponentBase(config, context), pg_cluster_( context.FindComponent("postgres-db-1") - .GetCluster()) { + .GetCluster()) +{ } -std::optional Controller::GetById(std::string_view id) const { - auto result = pg_cluster_->Execute( - userver::storages::postgres::ClusterHostType::kMaster, - sql::qGetUserByTokenId, id, userver::utils::datetime::Now()); - if (result.IsEmpty()) { - return std::nullopt; - } - return result.AsSingleRow( - userver::storages::postgres::kRowTag); +std::optional Controller::GetById( + std::string_view id, utils::SharedTransaction transaction) const +{ + utils::FillSharedTransaction(transaction, pg_cluster_); + auto result = utils::PgExecute(transaction, sql::qGetUserByTokenId, id, + userver::utils::datetime::Now()); + return utils::ConvertPgResultToOptionalItem(result); } std::optional Controller::CreateNew( const boost::uuids::uuid& user_id, - const std::chrono::system_clock::time_point& time) const { + const std::chrono::system_clock::time_point& time, + utils::SharedTransaction transaction) const +{ + utils::FillSharedTransaction(transaction, pg_cluster_); LOG_DEBUG() << fmt::format("Try to create new token, id_user: {}", boost::uuids::to_string(user_id)); - auto result = pg_cluster_->Execute( - userver::storages::postgres::ClusterHostType::kMaster, sql::qAddToken, - user_id, time); - if (result.IsEmpty()) { - return {}; - } - return result.AsSingleRow(); + + auto result = utils::PgExecute(transaction, sql::qAddToken, user_id, time); + return utils::ConvertPgResultToOptionalItem(result); } } // namespace timetable_vsu_backend::components::controllers::postgres::token diff --git a/src/components/controllers/postgres/token/controller.hpp b/src/components/controllers/postgres/token/controller.hpp index 84aaa37b..ed936a58 100644 --- a/src/components/controllers/postgres/token/controller.hpp +++ b/src/components/controllers/postgres/token/controller.hpp @@ -5,17 +5,26 @@ #include #include "models/user/type.hpp" +#include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::token { - -class Controller final : public userver::components::LoggableComponentBase { +namespace timetable_vsu_backend::components::controllers::postgres::token +{ +class Controller final : public userver::components::LoggableComponentBase +{ public: using userver::components::LoggableComponentBase::LoggableComponentBase; + static constexpr inline std::string_view kName = "token_controller"; - std::optional GetById(std::string_view id) const; + + std::optional GetById( + std::string_view id, + utils::SharedTransaction transaction = nullptr) const; + std::optional CreateNew( const boost::uuids::uuid& user_id, - const std::chrono::system_clock::time_point& time) const; + const std::chrono::system_clock::time_point& time, + utils::SharedTransaction transaction = nullptr) const; + Controller(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context); diff --git a/src/components/controllers/postgres/token/fwd.cpp b/src/components/controllers/postgres/token/fwd.cpp index 4e8f2916..9a7f2493 100644 --- a/src/components/controllers/postgres/token/fwd.cpp +++ b/src/components/controllers/postgres/token/fwd.cpp @@ -4,8 +4,10 @@ #include "controller.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { -void AppendTokenController(userver::components::ComponentList& component_list) { +namespace timetable_vsu_backend::components::controllers::postgres +{ +void AppendTokenController(userver::components::ComponentList& component_list) +{ component_list.Append(); } } // namespace timetable_vsu_backend::components::controllers::postgres diff --git a/src/components/controllers/postgres/token/fwd.hpp b/src/components/controllers/postgres/token/fwd.hpp index 20d07cce..5a222d14 100644 --- a/src/components/controllers/postgres/token/fwd.hpp +++ b/src/components/controllers/postgres/token/fwd.hpp @@ -1,7 +1,9 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { -namespace token { +namespace timetable_vsu_backend::components::controllers::postgres +{ +namespace token +{ class Controller; } void AppendTokenController(userver::components::ComponentList& component_list); diff --git a/src/components/controllers/postgres/token/sql_queries.hpp b/src/components/controllers/postgres/token/sql_queries.hpp index a86ef6a8..5bf41713 100644 --- a/src/components/controllers/postgres/token/sql_queries.hpp +++ b/src/components/controllers/postgres/token/sql_queries.hpp @@ -1,11 +1,12 @@ #include -namespace timetable_vsu_backend::components::controllers::postgres::token::sql { +namespace timetable_vsu_backend::components::controllers::postgres::token::sql +{ const userver::storages::postgres::Query qGetUserByTokenId(R"( WITH found_token AS (select id_user - from vsu_timetable.token WHERE id = $1 AND expire_time > $2) - SELECT id, login, password, user_type from vsu_timetable."user" LEFT OUTER JOIN found_token ON id_user = "user".id + from timetable_vsu.token WHERE id = $1 AND expire_time > $2) + SELECT id, login, password, user_type from timetable_vsu."user" LEFT OUTER JOIN found_token ON id_user = "user".id )"), qAddToken(R"( - insert into vsu_timetable."token" (id_user, expire_time) values ($1, $2) RETURNING id + insert into timetable_vsu."token" (id_user, expire_time) values ($1, $2) RETURNING id )"); } diff --git a/src/components/controllers/postgres/user/config_schema.hpp b/src/components/controllers/postgres/user/config_schema.hpp index 5726b6b8..7ad27f35 100644 --- a/src/components/controllers/postgres/user/config_schema.hpp +++ b/src/components/controllers/postgres/user/config_schema.hpp @@ -1,7 +1,7 @@ #pragma once #include -namespace timetable_vsu_backend::components::controllers::postgres::user:: - config { +namespace timetable_vsu_backend::components::controllers::postgres::user::config +{ const std::string schema = R"( type: object diff --git a/src/components/controllers/postgres/user/controller.cpp b/src/components/controllers/postgres/user/controller.cpp index c6d0a499..9cc54bd9 100644 --- a/src/components/controllers/postgres/user/controller.cpp +++ b/src/components/controllers/postgres/user/controller.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -23,95 +24,143 @@ #include "models/user/postgre.hpp" #include "models/user/type.hpp" #include "models/user_credentials/postgre.hpp" -#include "userver/storages/postgres/result_set.hpp" +#include "utils/postgres_helper.hpp" +#include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::user { +namespace timetable_vsu_backend::components::controllers::postgres::user +{ Controller::Controller(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context) : LoggableComponentBase(config, context), pg_cluster_( context.FindComponent("postgres-db-1") - .GetCluster()) { + .GetCluster()) +{ models::UserCredentials root; root.login() = config["root"]["login"].As(); root.password() = config["root"]["password"].As(); root_id = boost::lexical_cast( config["root"]["id"].As()); - try { + try + { InternalForceCreateUser(root_id.value(), root); - } catch (std::exception& exc) { + } + catch (std::exception& exc) + { LOG_WARNING() << fmt::format("Error while creating superuser : {}", exc.what()); root_id = std::nullopt; } } +utils::SharedTransaction Controller::CreateTransaction() +{ + return utils::MakeSharedTransaction(pg_cluster_); +} + void Controller::InternalForceCreateUser( - const boost::uuids::uuid&, - const models::UserCredentials& user_credentials) { - pg_cluster_->Execute(userver::storages::postgres::ClusterHostType::kMaster, - sql::qDropUserById, root_id); - pg_cluster_->Execute(userver::storages::postgres::ClusterHostType::kMaster, - sql::qDropUserByLogin, user_credentials.login()); - pg_cluster_->Execute( - userver::storages::postgres::ClusterHostType::kMaster, - sql::qInternalAddUser, root_id, - utils::convert::DropPropertiesToConstRefs(user_credentials)); + const boost::uuids::uuid&, const models::UserCredentials& user_credentials, + utils::SharedTransaction transaction) +{ + utils::FillSharedTransaction(transaction, pg_cluster_); + utils::PgExecute(transaction, sql::qDropUserById, root_id); + utils::PgExecute(transaction, sql::qDropUserByLogin, + user_credentials.login()); + utils::PgExecute(transaction, sql::qInternalAddUser, root_id, + user_credentials); +} + +std::optional Controller::CreateRequestTeacher( + const boost::uuids::uuid& user_id, const std::string& description, + utils::SharedTransaction transaction) const +{ + utils::FillSharedTransaction(transaction, pg_cluster_); + auto pg_result = utils::PgExecute(transaction, sql::qCreateTeacherRequest, + user_id, description); + return utils::ConvertPgResultToOptionalItem(pg_result); +} + +std::optional Controller::CreateRequestAdmin( + const boost::uuids::uuid& user_id, const std::string& description, + utils::SharedTransaction transaction) const +{ + utils::FillSharedTransaction(transaction, pg_cluster_); + auto pg_result = utils::PgExecute(transaction, sql::qCreateAdminRequest, + user_id, description); + return utils::ConvertPgResultToOptionalItem(pg_result); } std::optional Controller::HandleUserFromPg( - userver::storages::postgres::ResultSet& result) const { - if (result.IsEmpty()) { + userver::storages::postgres::ResultSet& result) const +{ + if (result.IsEmpty()) + { return std::nullopt; } std::optional user = std::nullopt; - if (result.Size() == 1) { - models::User read; - auto pg_user = utils::convert::DropPropertiesToMutRefs(read); - result[0].To(pg_user, userver::storages::postgres::kRowTag); - user = read; - } else if (result.Size() != 0) { + if (result.Size() == 1) + { + user = utils::ConvertPgResultToItem(result); + } + else if (result.Size() != 0) + { LOG_WARNING() << fmt::format("Unexpected quantity from postgres: {}", result.Size()); } - if (user && user->id() == root_id) { + if (user && user->id() == root_id) + { user->type() = models::UserType::kRoot; } return user; } std::optional Controller::GetByCredentials( - const models::UserCredentials& user_credentials) const { - auto result = pg_cluster_->Execute( - userver::storages::postgres::ClusterHostType::kMaster, + const models::UserCredentials& user_credentials, + utils::SharedTransaction transaction) const +{ + utils::FillSharedTransaction(transaction, pg_cluster_); + auto result = transaction->transaction_.Execute( sql::qGetUserByCredentials, utils::convert::DropPropertiesToConstRefs(user_credentials)); return HandleUserFromPg(result); } std::optional Controller::GetByToken( - const boost::uuids::uuid& token) const { - auto result = pg_cluster_->Execute( - userver::storages::postgres::ClusterHostType::kMaster, - sql::qGetUserByToken, token); + const boost::uuids::uuid& token, utils::SharedTransaction transaction) const +{ + utils::FillSharedTransaction(transaction, pg_cluster_); + auto result = + transaction->transaction_.Execute(sql::qGetUserByToken, token); return HandleUserFromPg(result); } + +utils::SharedTransaction Controller::CreateTransaction() const +{ + return utils::MakeSharedTransaction(pg_cluster_); +} + std::optional Controller::TryToAdd( - const models::UserCredentials& user_credentials) const { - auto result = pg_cluster_->Execute( - userver::storages::postgres::ClusterHostType::kMaster, sql::qAddUser, - utils::convert::DropPropertiesToConstRefs(user_credentials)); - if (result.IsEmpty()) { + const models::UserCredentials& user_credentials, + utils::SharedTransaction transaction) const +{ + utils::FillSharedTransaction(transaction, pg_cluster_); + auto result = + utils::PgExecute(transaction, sql::qAddUser, user_credentials); + if (result.IsEmpty()) + { return {}; } return result.AsSingleRow(); } -Controller::~Controller() { + +Controller::~Controller() +{ pg_cluster_->Execute(userver::storages::postgres::ClusterHostType::kMaster, sql::qDropUserById, root_id); } -userver::yaml_config::Schema Controller::GetStaticConfigSchema() { +userver::yaml_config::Schema Controller::GetStaticConfigSchema() +{ return userver::yaml_config::MergeSchemas< userver::components::LoggableComponentBase>(config::schema); } diff --git a/src/components/controllers/postgres/user/controller.hpp b/src/components/controllers/postgres/user/controller.hpp index 86f93a33..7712579e 100644 --- a/src/components/controllers/postgres/user/controller.hpp +++ b/src/components/controllers/postgres/user/controller.hpp @@ -7,29 +7,58 @@ #include "models/user/type.hpp" #include "models/user_credentials/fwd.hpp" #include "models/user_type/type.hpp" +#include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::components::controllers::postgres::user { - -class Controller final : public userver::components::LoggableComponentBase { +namespace timetable_vsu_backend::components::controllers::postgres::user +{ +class Controller final : public userver::components::LoggableComponentBase +{ public: using userver::components::LoggableComponentBase::LoggableComponentBase; + static constexpr inline std::string_view kName = "user-controller"; + void InternalForceCreateUser( const boost::uuids::uuid&, - const models::UserCredentials& user_credentials); - std::optional GetByToken(const boost::uuids::uuid&) const; + const models::UserCredentials& user_credentials, + utils::SharedTransaction transaction = nullptr); + + utils::SharedTransaction CreateTransaction(); + + std::optional GetByToken( + const boost::uuids::uuid& token, + utils::SharedTransaction transaction = nullptr) const; + + std::optional CreateRequestTeacher( + const boost::uuids::uuid& user_id, const std::string& description, + utils::SharedTransaction transaction = nullptr) const; + + std::optional CreateRequestAdmin( + const boost::uuids::uuid& user_id, const std::string& description, + utils::SharedTransaction transaction = nullptr) const; + std::optional GetByCredentials( - const models::UserCredentials& user_credentials) const; + const models::UserCredentials& user_credentials, + utils::SharedTransaction transaction = nullptr) const; + std::optional TryToAdd( - const models::UserCredentials& user_credentials) const; + const models::UserCredentials& user_credentials, + utils::SharedTransaction transaction = nullptr) const; + static userver::yaml_config::Schema GetStaticConfigSchema(); + + utils::SharedTransaction CreateTransaction() const; + Controller(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context); + ~Controller(); protected: std::optional HandleUserFromPg( userver::storages::postgres::ResultSet& result) const; + + private: std::optional root_id; userver::storages::postgres::ClusterPtr pg_cluster_; }; diff --git a/src/components/controllers/postgres/user/fwd.cpp b/src/components/controllers/postgres/user/fwd.cpp index 6e3b8d98..99d58d27 100644 --- a/src/components/controllers/postgres/user/fwd.cpp +++ b/src/components/controllers/postgres/user/fwd.cpp @@ -4,8 +4,10 @@ #include "controller.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { -void AppendUserController(userver::components::ComponentList& component_list) { +namespace timetable_vsu_backend::components::controllers::postgres +{ +void AppendUserController(userver::components::ComponentList& component_list) +{ component_list.Append(); } } // namespace timetable_vsu_backend::components::controllers::postgres diff --git a/src/components/controllers/postgres/user/fwd.hpp b/src/components/controllers/postgres/user/fwd.hpp index b96fd786..74c832e7 100644 --- a/src/components/controllers/postgres/user/fwd.hpp +++ b/src/components/controllers/postgres/user/fwd.hpp @@ -1,7 +1,9 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::components::controllers::postgres { -namespace user { +namespace timetable_vsu_backend::components::controllers::postgres +{ +namespace user +{ class Controller; } diff --git a/src/components/controllers/postgres/user/sql_queries.hpp b/src/components/controllers/postgres/user/sql_queries.hpp index 83077d24..21c2a2c8 100644 --- a/src/components/controllers/postgres/user/sql_queries.hpp +++ b/src/components/controllers/postgres/user/sql_queries.hpp @@ -2,22 +2,23 @@ #include -namespace timetable_vsu_backend::components::controllers::postgres::user::sql { +namespace timetable_vsu_backend::components::controllers::postgres::user::sql +{ const userver::storages::postgres::Query qGetUserByCredentials(R"( WITH all_user AS ( SELECT u.id AS user_id, a.id AS admin_id, tl.id_teacher AS teacher_id - from vsu_timetable.user AS u - left join vsu_timetable.admin AS a on u.id = a.id_user - left join vsu_timetable.teacher_link AS tl on u.id = tl.id_user + from timetable_vsu.user AS u + left join timetable_vsu.admin AS a on u.id = a.id_user + left join timetable_vsu.teacher_link AS tl on u.id = tl.id_user where u.login = $1.login and u."password" = $1.password ) SELECT user_id, CASE - WHEN admin_id IS NOT NULL THEN 'admin'::vsu_timetable.user_type - WHEN teacher_id IS NOT NULL THEN 'teacher'::vsu_timetable.user_type + WHEN admin_id IS NOT NULL THEN 'admin'::timetable_vsu.user_type + WHEN teacher_id IS NOT NULL THEN 'teacher'::timetable_vsu.user_type ELSE 'user' END AS type FROM all_user; @@ -28,32 +29,38 @@ const userver::storages::postgres::Query qGetUserByCredentials(R"( a.id AS admin_id, t.id AS token_id, tl.id_teacher AS teacher_id - from vsu_timetable.token AS t - left join vsu_timetable.user AS u on u.id = t.id_user - left join vsu_timetable.admin AS a on u.id = a.id_user - left join vsu_timetable.teacher_link AS tl on u.id = tl.id_user + from timetable_vsu.token AS t + left join timetable_vsu.user AS u on u.id = t.id_user + left join timetable_vsu.admin AS a on u.id = a.id_user + left join timetable_vsu.teacher_link AS tl on u.id = tl.id_user where t.id = $1 ) SELECT user_id, CASE - WHEN admin_id IS NOT NULL THEN 'admin'::vsu_timetable.user_type - WHEN teacher_id IS NOT NULL THEN 'teacher'::vsu_timetable.user_type + WHEN admin_id IS NOT NULL THEN 'admin'::timetable_vsu.user_type + WHEN teacher_id IS NOT NULL THEN 'teacher'::timetable_vsu.user_type ELSE 'user' END AS type FROM all_user; )"), qAddUser(R"( - insert into vsu_timetable."user"(login, password) values ($1.login, $1.password) ON CONFLICT DO NOTHING + insert into timetable_vsu."user"(login, password) values ($1.login, $1.password) ON CONFLICT DO NOTHING RETURNING id )"), qInternalAddUser(R"( - insert into vsu_timetable."user"(id, login, password) values ($1, $2.login, $2.password) + insert into timetable_vsu."user"(id, login, password) values ($1, $2.login, $2.password) )"), qDropUserByLogin(R"( - DELETE FROM vsu_timetable."user" WHERE login=$1; + DELETE FROM timetable_vsu."user" WHERE login=$1; )"), qDropUserById(R"( - DELETE FROM vsu_timetable."user" WHERE id=$1; + DELETE FROM timetable_vsu."user" WHERE id=$1; + )"), + qCreateTeacherRequest(R"( + INSERT INTO timetable_vsu."teacher_requests"(id_user, description) values ($1, $2) ON CONFLICT DO NOTHING + )"), + qCreateAdminRequest(R"( + INSERT INTO timetable_vsu."admin_requests"(id_user, description) values ($1, $2) ON CONFLICT DO NOTHING )"); } diff --git a/src/http/ErrorV1.hpp b/src/http/ErrorV1.hpp index 1265b8e4..4e8aaa0f 100644 --- a/src/http/ErrorV1.hpp +++ b/src/http/ErrorV1.hpp @@ -3,10 +3,12 @@ #include "../utils/convert/base.hpp" -namespace timetable_vsu_backend::http { +namespace timetable_vsu_backend::http +{ namespace convert = timetable_vsu_backend::utils::convert; template -struct ErrorV1 { +struct ErrorV1 +{ static constexpr convert::TypeOfBody kTypeOfBody = convert::TypeOfBody::Json; static constexpr convert::PolicyFields kPolicyFields = diff --git a/src/http/handler_parsed.hpp b/src/http/handler_parsed.hpp index 1447c421..8eff2e56 100644 --- a/src/http/handler_parsed.hpp +++ b/src/http/handler_parsed.hpp @@ -13,23 +13,28 @@ #include "../utils/convert/http_response_base.hpp" -namespace timetable_vsu_backend::http { +namespace timetable_vsu_backend::http +{ template -class HandlerParsed : public userver::server::handlers::HttpHandlerBase { +class HandlerParsed : public userver::server::handlers::HttpHandlerBase +{ public: using Response = std::variant; using HttpHandlerBase::HttpHandlerBase; HandlerParsed(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context) - : HttpHandlerBase(config, context) { + : HttpHandlerBase(config, context) + { } virtual Response Handle(Request&& request) const = 0; private: static std::optional ParseUserRequest( - const userver::server::http::HttpRequest& raw_request) { + const userver::server::http::HttpRequest& raw_request) + { std::optional request; - try { + try + { static_assert(userver::formats::common::impl::kHasParse< userver::server::http::HttpRequest, Request>, "Request should be able to parse from " @@ -37,7 +42,9 @@ class HandlerParsed : public userver::server::handlers::HttpHandlerBase { request = Parse(raw_request, userver::formats::parse::To{}); return request; - } catch (std::exception& exc) { + } + catch (std::exception& exc) + { LOG_DEBUG() << fmt::format( "Can't parse user request, return 400. Error: {}", exc.what()); request = std::nullopt; @@ -50,7 +57,8 @@ class HandlerParsed : public userver::server::handlers::HttpHandlerBase { template static std::string SerializeResponse( SomeResponse& some_response, - const userver::server::http::HttpRequest& raw_request) { + const userver::server::http::HttpRequest& raw_request) + { std::string body; timetable_vsu_backend::utils::convert::HttpResponse convert_response{ raw_request.GetHttpResponse(), body}; @@ -60,21 +68,26 @@ class HandlerParsed : public userver::server::handlers::HttpHandlerBase { std::string HandleRequestThrow( const userver::server::http::HttpRequest& raw_request, userver::server::request::RequestContext& /*context*/) - const override final { + const override final + { auto& http_response = raw_request.GetHttpResponse(); auto request = ParseUserRequest(raw_request); - if (!request) { + if (!request) + { http_response.SetStatus(HttpStatus::kBadRequest); return {}; } - try { + try + { Request&& parsed_request = std::move(*request); auto response = Handle(std::move(parsed_request)); auto visiter = [&raw_request](auto& value) { return SerializeResponse(value, raw_request); }; return std::visit(visiter, response); - } catch (std::exception& exc) { + } + catch (std::exception& exc) + { http_response.SetStatus(HttpStatus::kInternalServerError); LOG_ERROR() << fmt::format( "Unexpected error while handle request: {}", exc.what()); diff --git a/src/http/legacy_handler_parsed.hpp b/src/http/legacy_handler_parsed.hpp index 0990dc7b..7d3099c6 100644 --- a/src/http/legacy_handler_parsed.hpp +++ b/src/http/legacy_handler_parsed.hpp @@ -10,27 +10,34 @@ #include #include -namespace timetable_vsu_backend::http { +namespace timetable_vsu_backend::http +{ template -class LegacyHandlerParsed : public userver::server::handlers::HttpHandlerBase { +class LegacyHandlerParsed : public userver::server::handlers::HttpHandlerBase +{ public: using HttpHandlerBase::HttpHandlerBase; using HttpStatus = userver::server::http::HttpStatus; LegacyHandlerParsed(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context) - : HttpHandlerBase(config, context) { + : HttpHandlerBase(config, context) + { } virtual Response Handle( Request&& request, userver::server::http::HttpResponse& response) const = 0; static std::optional ParseUserRequest( - const userver::server::http::HttpRequest& raw_request) { + const userver::server::http::HttpRequest& raw_request) + { std::optional request; - try { + try + { request = Parse(raw_request, userver::formats::parse::To{}); return request; - } catch (std::exception& exc) { + } + catch (std::exception& exc) + { LOG_DEBUG() << fmt::format( "Can't parse user request, return 400. Error: {}", exc.what()); return std::nullopt; @@ -38,20 +45,25 @@ class LegacyHandlerParsed : public userver::server::handlers::HttpHandlerBase { } std::string HandleRequestThrow( const userver::server::http::HttpRequest& raw_request, - userver::server::request::RequestContext& /*context*/) const override { + userver::server::request::RequestContext& /*context*/) const override + { auto& http_response = raw_request.GetHttpResponse(); auto request = ParseUserRequest(raw_request); - if (!request) { + if (!request) + { http_response.SetStatus(HttpStatus::kBadRequest); return {}; } - try { + try + { auto response = Handle(std::move(*request), http_response); userver::formats::json::Value json = Serialize(response, userver::formats::serialize::To< userver::formats::json::Value>{}); return userver::formats::json::ToString(json); - } catch (std::exception& exc) { + } + catch (std::exception& exc) + { http_response.SetStatus(HttpStatus::kInternalServerError); LOG_ERROR() << fmt::format( "Unexpected error while handle request: {}", exc.what()); diff --git a/src/models/admin_account/postgre.hpp b/src/models/admin_account/postgre.hpp index 583fbb56..18de5ac3 100644 --- a/src/models/admin_account/postgre.hpp +++ b/src/models/admin_account/postgre.hpp @@ -5,16 +5,18 @@ #include "models/admin_account/type.hpp" #include "utils/convert/drop_properties_ref.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using AdminAccountTuple = timetable_vsu_backend::utils::convert::drop_properties_to_ref_mut_t< AdminAccount>; } // namespace timetable_vsu_backend::models -namespace userver::storages::postgres::io { - +namespace userver::storages::postgres::io +{ template <> -struct CppToUserPg { - static constexpr DBTypeName postgres_name = "vsu_timetable.admin_account"; +struct CppToUserPg +{ + static constexpr DBTypeName postgres_name = "timetable_vsu.admin_account"; }; } // namespace userver::storages::postgres::io diff --git a/src/models/admin_account/type.hpp b/src/models/admin_account/type.hpp index 64657ef5..a20d2739 100644 --- a/src/models/admin_account/type.hpp +++ b/src/models/admin_account/type.hpp @@ -4,9 +4,11 @@ #include "utils/convert/base.hpp" #include "utils/convert/json_serialize.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using namespace utils::convert; -struct AdminAccount { +struct AdminAccount +{ Property user_id; Property admin_id; Property credentials; diff --git a/src/models/admin_filter/fwd.hpp b/src/models/admin_filter/fwd.hpp index d772db1e..ca343653 100644 --- a/src/models/admin_filter/fwd.hpp +++ b/src/models/admin_filter/fwd.hpp @@ -1,5 +1,6 @@ #pragma once -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ struct AdminFilter; } diff --git a/src/models/admin_filter/postgre.hpp b/src/models/admin_filter/postgre.hpp index 94a9acc1..32aeb456 100644 --- a/src/models/admin_filter/postgre.hpp +++ b/src/models/admin_filter/postgre.hpp @@ -3,16 +3,18 @@ #include "models/admin_filter/type.hpp" #include "models/education_type/postgre.hpp" #include "utils/convert/drop_properties_ref.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using TupleAdminFilter = timetable_vsu_backend::utils::convert::drop_properties_to_ref_const_t< AdminFilter>; } // namespace timetable_vsu_backend::models -namespace userver::storages::postgres::io { - +namespace userver::storages::postgres::io +{ template <> -struct CppToUserPg { - static constexpr DBTypeName postgres_name = "vsu_timetable.admin_filter_v2"; +struct CppToUserPg +{ + static constexpr DBTypeName postgres_name = "timetable_vsu.admin_filter_v2"; }; } // namespace userver::storages::postgres::io diff --git a/src/models/admin_filter/type.hpp b/src/models/admin_filter/type.hpp index 6b6e3edf..93393d7d 100644 --- a/src/models/admin_filter/type.hpp +++ b/src/models/admin_filter/type.hpp @@ -12,9 +12,11 @@ #include "models/timestring/type.hpp" #include "utils/convert/additional_properties.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ namespace convert = utils::convert; -struct AdminFilter { +struct AdminFilter +{ convert::OptionalArrayProperty admin_ids; convert::OptionalArrayProperty user_ids; convert::OptionalArrayProperty logins; diff --git a/src/models/auth_token/serialize.hpp b/src/models/auth_token/serialize.hpp index 25dd53fe..697e5000 100644 --- a/src/models/auth_token/serialize.hpp +++ b/src/models/auth_token/serialize.hpp @@ -9,10 +9,12 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ inline userver::formats::json::Value Serialize( const AuthToken& token, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ userver::formats::json::ValueBuilder json; json["token"] = boost::uuids::to_string(token.id); return json.ExtractValue(); diff --git a/src/models/auth_token/type.hpp b/src/models/auth_token/type.hpp index ac54a5b5..8d5101f7 100644 --- a/src/models/auth_token/type.hpp +++ b/src/models/auth_token/type.hpp @@ -1,8 +1,10 @@ #pragma once #include -namespace timetable_vsu_backend::models { -struct AuthToken { +namespace timetable_vsu_backend::models +{ +struct AuthToken +{ boost::uuids::uuid id; }; } // namespace timetable_vsu_backend::models diff --git a/src/models/day/parse.cpp b/src/models/day/parse.cpp index 0048b575..04659d5c 100644 --- a/src/models/day/parse.cpp +++ b/src/models/day/parse.cpp @@ -8,27 +8,43 @@ #include "type.hpp" #include "utils/json_type.hpp" -namespace timetable_vsu_backend::models { -Day Parse(std::string_view str, userver::formats::parse::To) { - if (str == "monday") { +namespace timetable_vsu_backend::models +{ +Day Parse(std::string_view str, userver::formats::parse::To) +{ + if (str == "monday") + { return Day::kMonday; - } else if (str == "tuesday") { + } + else if (str == "tuesday") + { return Day::kTuesday; - } else if (str == "thursday") { + } + else if (str == "thursday") + { return Day::kThursday; - } else if (str == "wednesday") { + } + else if (str == "wednesday") + { return Day::kWednesday; - } else if (str == "saturday") { + } + else if (str == "saturday") + { return Day::kSaturday; - } else if (str == "friday") { + } + else if (str == "friday") + { return Day::kFriday; - } else + } + else throw std::runtime_error( fmt::format("Fail parse Day, get unexpected value: {}", str)); } Day Parse(const userver::formats::json::Value& value, - userver::formats::parse::To) { - if (!value.IsString()) { + userver::formats::parse::To) +{ + if (!value.IsString()) + { throw std::runtime_error(fmt::format( "Expected string type, but got: {}", utils::GetType(value))); } diff --git a/src/models/day/parse.hpp b/src/models/day/parse.hpp index 46cb9fdf..d9d6f253 100644 --- a/src/models/day/parse.hpp +++ b/src/models/day/parse.hpp @@ -5,7 +5,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ Day Parse(std::string_view str, userver::formats::parse::To); Day Parse(const userver::formats::json::Value& value, userver::formats::parse::To); diff --git a/src/models/day/postgre.hpp b/src/models/day/postgre.hpp index b9be4ee4..977f0314 100644 --- a/src/models/day/postgre.hpp +++ b/src/models/day/postgre.hpp @@ -5,12 +5,14 @@ #include "type.hpp" -namespace userver::storages::postgres::io { +namespace userver::storages::postgres::io +{ using timetable_vsu_backend::models::Day; template <> -struct CppToUserPg : EnumMappingBase { +struct CppToUserPg : EnumMappingBase +{ static constexpr userver::storages::postgres::DBTypeName postgres_name = - "vsu_timetable.day"; + "timetable_vsu.day"; static constexpr userver::utils::TrivialBiMap enumerators = [](auto selector) { return selector() diff --git a/src/models/day/serialize.cpp b/src/models/day/serialize.cpp index f750a6f0..f6c84247 100644 --- a/src/models/day/serialize.cpp +++ b/src/models/day/serialize.cpp @@ -2,10 +2,13 @@ #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ std::string Serialize(const Day& value, - userver::formats::serialize::To) { - switch (value) { + userver::formats::serialize::To) +{ + switch (value) + { case Day::kMonday: return "monday"; case Day::kTuesday: @@ -22,7 +25,8 @@ std::string Serialize(const Day& value, } userver::formats::json::Value Serialize( const Day& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ std::string str = Serialize(value, userver::formats::serialize::To{}); return userver::formats::json::ValueBuilder(str).ExtractValue(); diff --git a/src/models/day/serialize.hpp b/src/models/day/serialize.hpp index 50efe278..11760416 100644 --- a/src/models/day/serialize.hpp +++ b/src/models/day/serialize.hpp @@ -3,7 +3,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ userver::formats::json::Value Serialize( const Day& value, userver::formats::serialize::To); diff --git a/src/models/day/type.hpp b/src/models/day/type.hpp index 24963d76..71e868cc 100644 --- a/src/models/day/type.hpp +++ b/src/models/day/type.hpp @@ -1,7 +1,9 @@ #pragma once -namespace timetable_vsu_backend::models { -enum struct Day { +namespace timetable_vsu_backend::models +{ +enum struct Day +{ kMonday, kTuesday, kWednesday, diff --git a/src/models/education_type/parse.cpp b/src/models/education_type/parse.cpp index cc77cd9e..04de3278 100644 --- a/src/models/education_type/parse.cpp +++ b/src/models/education_type/parse.cpp @@ -8,24 +8,36 @@ #include "type.hpp" #include "utils/json_type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ EducationType Parse(std::string_view str, - userver::formats::parse::To) { - if (str == "magistracy") { + userver::formats::parse::To) +{ + if (str == "magistracy") + { return EducationType::kMagistracy; - } else if (str == "postgraduate") { + } + else if (str == "postgraduate") + { return EducationType::kPostgraduate; - } else if (str == "specialty") { + } + else if (str == "specialty") + { return EducationType::kSpecialty; - } else if (str == "undergraduate") { + } + else if (str == "undergraduate") + { return EducationType::kUndergraduate; - } else + } + else throw std::runtime_error(fmt::format( "Fail parse EducationType, get unexpected value: {}", str)); } EducationType Parse(const userver::formats::json::Value& value, - userver::formats::parse::To) { - if (!value.IsString()) { + userver::formats::parse::To) +{ + if (!value.IsString()) + { throw std::runtime_error(fmt::format( "Expected string type, but got: {}", utils::GetType(value))); } diff --git a/src/models/education_type/parse.hpp b/src/models/education_type/parse.hpp index 1895e7d3..eaeefa39 100644 --- a/src/models/education_type/parse.hpp +++ b/src/models/education_type/parse.hpp @@ -5,7 +5,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ EducationType Parse(std::string_view str, userver::formats::parse::To); EducationType Parse(const userver::formats::json::Value& value, diff --git a/src/models/education_type/postgre.hpp b/src/models/education_type/postgre.hpp index 6b8d0356..3273d0de 100644 --- a/src/models/education_type/postgre.hpp +++ b/src/models/education_type/postgre.hpp @@ -5,12 +5,14 @@ #include "type.hpp" -namespace userver::storages::postgres::io { +namespace userver::storages::postgres::io +{ using timetable_vsu_backend::models::EducationType; template <> -struct CppToUserPg : EnumMappingBase { +struct CppToUserPg : EnumMappingBase +{ static constexpr userver::storages::postgres::DBTypeName postgres_name = - "vsu_timetable.grouptype"; + "timetable_vsu.grouptype"; static constexpr userver::utils::TrivialBiMap enumerators = [](auto selector) { return selector() diff --git a/src/models/education_type/serialize.cpp b/src/models/education_type/serialize.cpp index 76a119b0..12081010 100644 --- a/src/models/education_type/serialize.cpp +++ b/src/models/education_type/serialize.cpp @@ -2,10 +2,13 @@ #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ std::string Serialize(const EducationType& value, - userver::formats::serialize::To) { - switch (value) { + userver::formats::serialize::To) +{ + switch (value) + { case EducationType::kMagistracy: return "magistracy"; case EducationType::kPostgraduate: @@ -18,7 +21,8 @@ std::string Serialize(const EducationType& value, } userver::formats::json::Value Serialize( const EducationType& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ std::string str = Serialize(value, userver::formats::serialize::To{}); return userver::formats::json::ValueBuilder(str).ExtractValue(); diff --git a/src/models/education_type/serialize.hpp b/src/models/education_type/serialize.hpp index bc087643..1cd39508 100644 --- a/src/models/education_type/serialize.hpp +++ b/src/models/education_type/serialize.hpp @@ -3,7 +3,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ userver::formats::json::Value Serialize( const EducationType& value, userver::formats::serialize::To); diff --git a/src/models/education_type/type.hpp b/src/models/education_type/type.hpp index 3ed6d3fa..558a34e9 100644 --- a/src/models/education_type/type.hpp +++ b/src/models/education_type/type.hpp @@ -1,7 +1,9 @@ #pragma once -namespace timetable_vsu_backend::models { -enum struct EducationType { +namespace timetable_vsu_backend::models +{ +enum struct EducationType +{ kUndergraduate, kMagistracy, kPostgraduate, diff --git a/src/models/lesson_filter/fwd.hpp b/src/models/lesson_filter/fwd.hpp index b7b8e922..2514724d 100644 --- a/src/models/lesson_filter/fwd.hpp +++ b/src/models/lesson_filter/fwd.hpp @@ -1,5 +1,6 @@ #pragma once -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ struct LessonFilter; } diff --git a/src/models/lesson_filter/postgre.hpp b/src/models/lesson_filter/postgre.hpp index 706a316d..0229c8d8 100644 --- a/src/models/lesson_filter/postgre.hpp +++ b/src/models/lesson_filter/postgre.hpp @@ -3,17 +3,19 @@ #include "models/education_type/postgre.hpp" #include "models/lesson_filter/type.hpp" #include "utils/convert/drop_properties_ref.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using TupleLessonFilter = timetable_vsu_backend::utils::convert::drop_properties_to_ref_const_t< LessonFilter>; } // namespace timetable_vsu_backend::models -namespace userver::storages::postgres::io { - +namespace userver::storages::postgres::io +{ template <> -struct CppToUserPg { +struct CppToUserPg +{ static constexpr DBTypeName postgres_name = - "vsu_timetable.lesson_filter_v2"; + "timetable_vsu.lesson_filter_v2"; }; } // namespace userver::storages::postgres::io diff --git a/src/models/lesson_filter/type.hpp b/src/models/lesson_filter/type.hpp index 6314ba3b..10f4e1b9 100644 --- a/src/models/lesson_filter/type.hpp +++ b/src/models/lesson_filter/type.hpp @@ -12,9 +12,11 @@ #include "models/timestring/type.hpp" #include "utils/convert/additional_properties.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ namespace convert = utils::convert; -struct LessonFilter { +struct LessonFilter +{ convert::OptionalArrayProperty lesson_ids; convert::OptionalProperty begin; convert::OptionalProperty end; diff --git a/src/models/lesson_type/parse.cpp b/src/models/lesson_type/parse.cpp index d7f49f0d..e1cfec96 100644 --- a/src/models/lesson_type/parse.cpp +++ b/src/models/lesson_type/parse.cpp @@ -8,22 +8,31 @@ #include "type.hpp" #include "utils/json_type.hpp" -namespace timetable_vsu_backend::models { -LessonType Parse(std::string_view str, - userver::formats::parse::To) { - if (str == "labaratory") { +namespace timetable_vsu_backend::models +{ +LessonType Parse(std::string_view str, userver::formats::parse::To) +{ + if (str == "labaratory") + { return LessonType::kLabaratory; - } else if (str == "lection") { + } + else if (str == "lection") + { return LessonType::kLection; - } else if (str == "practice") { + } + else if (str == "practice") + { return LessonType::kPractice; - } else + } + else throw std::runtime_error(fmt::format( "Fail parse LessonType, get unexpected value: {}", str)); } LessonType Parse(const userver::formats::json::Value& value, - userver::formats::parse::To) { - if (!value.IsString()) { + userver::formats::parse::To) +{ + if (!value.IsString()) + { throw std::runtime_error(fmt::format( "Expected string type, but got: {}", utils::GetType(value))); } diff --git a/src/models/lesson_type/parse.hpp b/src/models/lesson_type/parse.hpp index e569df19..a1c29008 100644 --- a/src/models/lesson_type/parse.hpp +++ b/src/models/lesson_type/parse.hpp @@ -5,7 +5,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ LessonType Parse(std::string_view str, userver::formats::parse::To); LessonType Parse(const userver::formats::json::Value& value, userver::formats::parse::To); diff --git a/src/models/lesson_type/postgre.hpp b/src/models/lesson_type/postgre.hpp index e70d1b92..f97965b0 100644 --- a/src/models/lesson_type/postgre.hpp +++ b/src/models/lesson_type/postgre.hpp @@ -5,12 +5,14 @@ #include "type.hpp" -namespace userver::storages::postgres::io { +namespace userver::storages::postgres::io +{ using timetable_vsu_backend::models::LessonType; template <> -struct CppToUserPg : EnumMappingBase { +struct CppToUserPg : EnumMappingBase +{ static constexpr userver::storages::postgres::DBTypeName postgres_name = - "vsu_timetable.type_lesson"; + "timetable_vsu.type_lesson"; static constexpr userver::utils::TrivialBiMap enumerators = [](auto selector) { return selector() diff --git a/src/models/lesson_type/serialize.cpp b/src/models/lesson_type/serialize.cpp index b40d508b..15c1cf51 100644 --- a/src/models/lesson_type/serialize.cpp +++ b/src/models/lesson_type/serialize.cpp @@ -2,10 +2,13 @@ #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ std::string Serialize(const LessonType& value, - userver::formats::serialize::To) { - switch (value) { + userver::formats::serialize::To) +{ + switch (value) + { case LessonType::kLabaratory: return "labaratory"; case LessonType::kLection: @@ -16,7 +19,8 @@ std::string Serialize(const LessonType& value, } userver::formats::json::Value Serialize( const LessonType& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ std::string str = Serialize(value, userver::formats::serialize::To{}); return userver::formats::json::ValueBuilder(str).ExtractValue(); diff --git a/src/models/lesson_type/serialize.hpp b/src/models/lesson_type/serialize.hpp index b8525801..2b35b66f 100644 --- a/src/models/lesson_type/serialize.hpp +++ b/src/models/lesson_type/serialize.hpp @@ -3,7 +3,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ userver::formats::json::Value Serialize( const LessonType& value, userver::formats::serialize::To); diff --git a/src/models/lesson_type/type.hpp b/src/models/lesson_type/type.hpp index 3c18811e..97497bf0 100644 --- a/src/models/lesson_type/type.hpp +++ b/src/models/lesson_type/type.hpp @@ -1,5 +1,11 @@ #pragma once -namespace timetable_vsu_backend::models { -enum struct LessonType { kLabaratory, kLection, kPractice }; +namespace timetable_vsu_backend::models +{ +enum struct LessonType +{ + kLabaratory, + kLection, + kPractice +}; } diff --git a/src/models/lesson_v1/postgre.hpp b/src/models/lesson_v1/postgre.hpp index 6ac5dab2..d9f4200e 100644 --- a/src/models/lesson_v1/postgre.hpp +++ b/src/models/lesson_v1/postgre.hpp @@ -8,7 +8,8 @@ #include "models/subgroup/postgre.hpp" #include "models/timestring/postgre.hpp" #include "utils/convert/drop_properties_ref.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using TupleLessonV1 = timetable_vsu_backend::utils::convert::drop_properties_to_ref_mut_t< LessonV1>; diff --git a/src/models/lesson_v1/type.hpp b/src/models/lesson_v1/type.hpp index e052dee9..c3bfe6ea 100644 --- a/src/models/lesson_v1/type.hpp +++ b/src/models/lesson_v1/type.hpp @@ -12,9 +12,11 @@ namespace convert = timetable_vsu_backend::utils::convert; -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ //Пара со всей дополнительной информацией -struct LessonV1 { +struct LessonV1 +{ convert::Property lesson_id; convert::Property lesson_begin; convert::Property lesson_end; diff --git a/src/models/lesson_week_type/parse.cpp b/src/models/lesson_week_type/parse.cpp index c6327034..41be92c9 100644 --- a/src/models/lesson_week_type/parse.cpp +++ b/src/models/lesson_week_type/parse.cpp @@ -8,22 +8,32 @@ #include "type.hpp" #include "utils/json_type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ LessonWeekType Parse(std::string_view str, - userver::formats::parse::To) { - if (str == "all") { + userver::formats::parse::To) +{ + if (str == "all") + { return LessonWeekType::kAll; - } else if (str == "even") { + } + else if (str == "even") + { return LessonWeekType::kEven; - } else if (str == "odd") { + } + else if (str == "odd") + { return LessonWeekType::kOdd; - } else + } + else throw std::runtime_error(fmt::format( "Fail parse LessonWeekType, get unexpected value: {}", str)); } LessonWeekType Parse(const userver::formats::json::Value& value, - userver::formats::parse::To) { - if (!value.IsString()) { + userver::formats::parse::To) +{ + if (!value.IsString()) + { throw std::runtime_error(fmt::format( "Expected string type, but got: {}", utils::GetType(value))); } diff --git a/src/models/lesson_week_type/parse.hpp b/src/models/lesson_week_type/parse.hpp index c63efbb7..450c3191 100644 --- a/src/models/lesson_week_type/parse.hpp +++ b/src/models/lesson_week_type/parse.hpp @@ -5,7 +5,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ LessonWeekType Parse(std::string_view str, userver::formats::parse::To); LessonWeekType Parse(const userver::formats::json::Value& value, diff --git a/src/models/lesson_week_type/postgre.hpp b/src/models/lesson_week_type/postgre.hpp index e9a0a8d2..acae2b58 100644 --- a/src/models/lesson_week_type/postgre.hpp +++ b/src/models/lesson_week_type/postgre.hpp @@ -5,12 +5,14 @@ #include "type.hpp" -namespace userver::storages::postgres::io { +namespace userver::storages::postgres::io +{ using timetable_vsu_backend::models::LessonWeekType; template <> -struct CppToUserPg : EnumMappingBase { +struct CppToUserPg : EnumMappingBase +{ static constexpr userver::storages::postgres::DBTypeName postgres_name = - "vsu_timetable.type_of_week"; + "timetable_vsu.type_of_week"; static constexpr userver::utils::TrivialBiMap enumerators = [](auto selector) { return selector() diff --git a/src/models/lesson_week_type/serialize.cpp b/src/models/lesson_week_type/serialize.cpp index 865653f5..ea348dd8 100644 --- a/src/models/lesson_week_type/serialize.cpp +++ b/src/models/lesson_week_type/serialize.cpp @@ -2,10 +2,13 @@ #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ std::string Serialize(const LessonWeekType& value, - userver::formats::serialize::To) { - switch (value) { + userver::formats::serialize::To) +{ + switch (value) + { case LessonWeekType::kAll: return "all"; case LessonWeekType::kEven: @@ -16,7 +19,8 @@ std::string Serialize(const LessonWeekType& value, } userver::formats::json::Value Serialize( const LessonWeekType& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ std::string str = Serialize(value, userver::formats::serialize::To{}); return userver::formats::json::ValueBuilder(str).ExtractValue(); diff --git a/src/models/lesson_week_type/serialize.hpp b/src/models/lesson_week_type/serialize.hpp index c4cca84a..b09dbc13 100644 --- a/src/models/lesson_week_type/serialize.hpp +++ b/src/models/lesson_week_type/serialize.hpp @@ -3,7 +3,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ userver::formats::json::Value Serialize( const LessonWeekType& value, userver::formats::serialize::To); diff --git a/src/models/lesson_week_type/type.hpp b/src/models/lesson_week_type/type.hpp index 7d971fbb..7d534380 100644 --- a/src/models/lesson_week_type/type.hpp +++ b/src/models/lesson_week_type/type.hpp @@ -1,5 +1,11 @@ #pragma once -namespace timetable_vsu_backend::models { -enum struct LessonWeekType { kAll, kEven, kOdd }; +namespace timetable_vsu_backend::models +{ +enum struct LessonWeekType +{ + kAll, + kEven, + kOdd +}; } diff --git a/src/models/register_request/fwd.hpp b/src/models/register_request/fwd.hpp new file mode 100644 index 00000000..736fb12e --- /dev/null +++ b/src/models/register_request/fwd.hpp @@ -0,0 +1,5 @@ +#pragma once +namespace timetable_vsu_backend::models +{ +struct RegisterRequest; +} diff --git a/src/models/register_request/type.hpp b/src/models/register_request/type.hpp new file mode 100644 index 00000000..3d8a43fb --- /dev/null +++ b/src/models/register_request/type.hpp @@ -0,0 +1,22 @@ +#pragma once +#include +#include + +#include "models/user_credentials/type.hpp" +#include "models/user_type/type.hpp" +#include "utils/convert/additional_properties.hpp" +#include "utils/convert/base.hpp" +namespace timetable_vsu_backend::models +{ +using namespace utils::convert; +struct RegisterRequest +{ + Property user_credentials; + OptionalProperty description; + OptionalProperty desired_type; + static constexpr TypeOfBody kTypeOfBody = + TypeOfBody::Json; //открываем возможность использовать структуру, как + //запрос + static constexpr PolicyFields kPolicyFields = PolicyFields::ConvertAll; +}; +} // namespace timetable_vsu_backend::models diff --git a/src/models/subgroup/parse.cpp b/src/models/subgroup/parse.cpp index 14f7d8b1..c955e5e0 100644 --- a/src/models/subgroup/parse.cpp +++ b/src/models/subgroup/parse.cpp @@ -8,21 +8,31 @@ #include "type.hpp" #include "utils/json_type.hpp" -namespace timetable_vsu_backend::models { -Subgroup Parse(std::string_view str, userver::formats::parse::To) { - if (str == "all") { +namespace timetable_vsu_backend::models +{ +Subgroup Parse(std::string_view str, userver::formats::parse::To) +{ + if (str == "all") + { return Subgroup::kAll; - } else if (str == "first") { + } + else if (str == "first") + { return Subgroup::kFirst; - } else if (str == "second") { + } + else if (str == "second") + { return Subgroup::kSecond; - } else + } + else throw std::runtime_error( fmt::format("Fail parse Subgroup, get unexpected value: {}", str)); } Subgroup Parse(const userver::formats::json::Value& value, - userver::formats::parse::To) { - if (!value.IsString()) { + userver::formats::parse::To) +{ + if (!value.IsString()) + { throw std::runtime_error(fmt::format( "Expected string type, but got: {}", utils::GetType(value))); } diff --git a/src/models/subgroup/parse.hpp b/src/models/subgroup/parse.hpp index effdf729..b1d9232a 100644 --- a/src/models/subgroup/parse.hpp +++ b/src/models/subgroup/parse.hpp @@ -5,7 +5,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ Subgroup Parse(std::string_view str, userver::formats::parse::To); Subgroup Parse(const userver::formats::json::Value& value, userver::formats::parse::To); diff --git a/src/models/subgroup/postgre.hpp b/src/models/subgroup/postgre.hpp index ff27c143..c00a237a 100644 --- a/src/models/subgroup/postgre.hpp +++ b/src/models/subgroup/postgre.hpp @@ -5,12 +5,14 @@ #include "type.hpp" -namespace userver::storages::postgres::io { +namespace userver::storages::postgres::io +{ using timetable_vsu_backend::models::Subgroup; template <> -struct CppToUserPg : EnumMappingBase { +struct CppToUserPg : EnumMappingBase +{ static constexpr userver::storages::postgres::DBTypeName postgres_name = - "vsu_timetable.subgroup"; + "timetable_vsu.subgroup"; static constexpr userver::utils::TrivialBiMap enumerators = [](auto selector) { return selector() diff --git a/src/models/subgroup/serialize.cpp b/src/models/subgroup/serialize.cpp index a83ba485..6c0be608 100644 --- a/src/models/subgroup/serialize.cpp +++ b/src/models/subgroup/serialize.cpp @@ -2,10 +2,13 @@ #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ std::string Serialize(const Subgroup& value, - userver::formats::serialize::To) { - switch (value) { + userver::formats::serialize::To) +{ + switch (value) + { case Subgroup::kAll: return "all"; case Subgroup::kFirst: @@ -16,7 +19,8 @@ std::string Serialize(const Subgroup& value, } userver::formats::json::Value Serialize( const Subgroup& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ std::string str = Serialize(value, userver::formats::serialize::To{}); return userver::formats::json::ValueBuilder(str).ExtractValue(); diff --git a/src/models/subgroup/serialize.hpp b/src/models/subgroup/serialize.hpp index d7d23893..41043627 100644 --- a/src/models/subgroup/serialize.hpp +++ b/src/models/subgroup/serialize.hpp @@ -3,7 +3,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ userver::formats::json::Value Serialize( const Subgroup& value, userver::formats::serialize::To); diff --git a/src/models/subgroup/type.hpp b/src/models/subgroup/type.hpp index 0f7dc379..aaebd1c4 100644 --- a/src/models/subgroup/type.hpp +++ b/src/models/subgroup/type.hpp @@ -1,5 +1,11 @@ #pragma once -namespace timetable_vsu_backend::models { -enum struct Subgroup { kAll, kFirst, kSecond }; +namespace timetable_vsu_backend::models +{ +enum struct Subgroup +{ + kAll, + kFirst, + kSecond +}; } diff --git a/src/models/substring/fwd.hpp b/src/models/substring/fwd.hpp index 7f0f5115..084398b2 100644 --- a/src/models/substring/fwd.hpp +++ b/src/models/substring/fwd.hpp @@ -1,4 +1,5 @@ #pragma once -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ struct SubString; } diff --git a/src/models/substring/parse.cpp b/src/models/substring/parse.cpp index 3e850e34..279a0072 100644 --- a/src/models/substring/parse.cpp +++ b/src/models/substring/parse.cpp @@ -7,21 +7,22 @@ #include #include "type.hpp" -#include "userver/logging/log.hpp" #include "utils/json_type.hpp" -namespace timetable_vsu_backend::models { -SubString Parse(const std::string& str, - userver::formats::parse::To) { +namespace timetable_vsu_backend::models +{ +SubString Parse(const std::string& str, userver::formats::parse::To) +{ SubString result; result.GetUnderlying().reserve(str.size() + 2); result.GetUnderlying().append("%").append(str).append("%"); - LOG_DEBUG() << fmt::format("result: {}", result); return result; } SubString Parse(const userver::formats::json::Value& value, - userver::formats::parse::To) { - if (!value.IsString()) { + userver::formats::parse::To) +{ + if (!value.IsString()) + { throw std::runtime_error(fmt::format( "Expected string type, but got: {}", utils::GetType(value))); } diff --git a/src/models/substring/parse.hpp b/src/models/substring/parse.hpp index 72cb8eed..7fcf870e 100644 --- a/src/models/substring/parse.hpp +++ b/src/models/substring/parse.hpp @@ -5,7 +5,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ SubString Parse(const std::string& str, userver::formats::parse::To); SubString Parse(const userver::formats::json::Value& value, userver::formats::parse::To); diff --git a/src/models/substring/postgre.hpp b/src/models/substring/postgre.hpp index 4228387a..5af4e19c 100644 --- a/src/models/substring/postgre.hpp +++ b/src/models/substring/postgre.hpp @@ -4,8 +4,11 @@ #include "type.hpp" -namespace userver::storages::postgres::io { +namespace userver::storages::postgres::io +{ using timetable_vsu_backend::models::SubString; template <> -struct CppToSystemPg : PredefinedOid {}; +struct CppToSystemPg : PredefinedOid +{ +}; } // namespace userver::storages::postgres::io diff --git a/src/models/substring/serialize.cpp b/src/models/substring/serialize.cpp index e4811b51..90ab3581 100644 --- a/src/models/substring/serialize.cpp +++ b/src/models/substring/serialize.cpp @@ -3,14 +3,17 @@ #include #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ std::string Serialize(const SubString& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ return value.GetUnderlying().substr(1, value.GetUnderlying().size() - 2); } userver::formats::json::Value Serialize( const SubString& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ std::string str = Serialize(value, userver::formats::serialize::To{}); return userver::formats::json::ValueBuilder(str).ExtractValue(); diff --git a/src/models/substring/serialize.hpp b/src/models/substring/serialize.hpp index 37abf00d..434f2b28 100644 --- a/src/models/substring/serialize.hpp +++ b/src/models/substring/serialize.hpp @@ -3,7 +3,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ userver::formats::json::Value Serialize( const SubString& value, userver::formats::serialize::To); diff --git a/src/models/substring/type.hpp b/src/models/substring/type.hpp index fa954104..2efd1873 100644 --- a/src/models/substring/type.hpp +++ b/src/models/substring/type.hpp @@ -1,7 +1,8 @@ #pragma once #include #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ //расставляет % с обоих сторон строки, чтобы запросы в постгресе с //использованием ILIKE работали как поиск подстроки using SubString = diff --git a/src/models/teacher/postgre.hpp b/src/models/teacher/postgre.hpp index 6c1fbddd..c54c4cbd 100644 --- a/src/models/teacher/postgre.hpp +++ b/src/models/teacher/postgre.hpp @@ -4,17 +4,19 @@ #include "models/teacher/type.hpp" #include "utils/convert/drop_properties_ref.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using ConstTupleTeacher = timetable_vsu_backend::utils::convert::drop_properties_to_ref_const_t< Teacher>; } // namespace timetable_vsu_backend::models -namespace userver::storages::postgres::io { - +namespace userver::storages::postgres::io +{ template <> -struct CppToUserPg { - static constexpr DBTypeName postgres_name = "vsu_timetable.teacher_filter"; +struct CppToUserPg +{ + static constexpr DBTypeName postgres_name = "timetable_vsu.teacher_filter"; }; } // namespace userver::storages::postgres::io diff --git a/src/models/teacher/type.hpp b/src/models/teacher/type.hpp index 8ae8eca5..825520fd 100644 --- a/src/models/teacher/type.hpp +++ b/src/models/teacher/type.hpp @@ -5,9 +5,11 @@ #include "models/user_type/type.hpp" #include "utils/convert/base.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ namespace convert = utils::convert; -struct Teacher { +struct Teacher +{ convert::Property id; convert::Property fio; convert::Property bio; diff --git a/src/models/teacher_filter/fwd.hpp b/src/models/teacher_filter/fwd.hpp index 3cd5af39..be8792b9 100644 --- a/src/models/teacher_filter/fwd.hpp +++ b/src/models/teacher_filter/fwd.hpp @@ -1,5 +1,6 @@ #pragma once -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ struct TeacherFilter; } diff --git a/src/models/teacher_filter/postgre.hpp b/src/models/teacher_filter/postgre.hpp index 1a0f14e2..edc92449 100644 --- a/src/models/teacher_filter/postgre.hpp +++ b/src/models/teacher_filter/postgre.hpp @@ -3,16 +3,18 @@ #include "models/education_type/postgre.hpp" #include "models/teacher_filter/type.hpp" #include "utils/convert/drop_properties_ref.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using TupleTeacherFilter = timetable_vsu_backend::utils::convert::drop_properties_to_ref_const_t< TeacherFilter>; } // namespace timetable_vsu_backend::models -namespace userver::storages::postgres::io { - +namespace userver::storages::postgres::io +{ template <> -struct CppToUserPg { - static constexpr DBTypeName postgres_name = "vsu_timetable.teacher_filter"; +struct CppToUserPg +{ + static constexpr DBTypeName postgres_name = "timetable_vsu.teacher_filter"; }; } // namespace userver::storages::postgres::io diff --git a/src/models/teacher_filter/type.hpp b/src/models/teacher_filter/type.hpp index 7e68bfb0..29883d90 100644 --- a/src/models/teacher_filter/type.hpp +++ b/src/models/teacher_filter/type.hpp @@ -13,9 +13,11 @@ #include "models/timestring/type.hpp" #include "utils/convert/additional_properties.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ namespace convert = utils::convert; -struct TeacherFilter { +struct TeacherFilter +{ convert::OptionalArrayProperty admin_ids; convert::OptionalArrayProperty fios; convert::OptionalArrayProperty bios; diff --git a/src/models/timestring/fwd.hpp b/src/models/timestring/fwd.hpp index 0703ea2d..040a8a88 100644 --- a/src/models/timestring/fwd.hpp +++ b/src/models/timestring/fwd.hpp @@ -1,4 +1,5 @@ #pragma once -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ struct TimeString; } diff --git a/src/models/timestring/parse.cpp b/src/models/timestring/parse.cpp index 8ade93f8..8d3c337f 100644 --- a/src/models/timestring/parse.cpp +++ b/src/models/timestring/parse.cpp @@ -8,15 +8,19 @@ #include "type.hpp" #include "utils/json_type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ TimeString Parse(const std::string& str, - userver::formats::parse::To) { + userver::formats::parse::To) +{ auto value = userver::utils::datetime::GuessStringtime(str, "UTC"); return TimeString{value}; } TimeString Parse(const userver::formats::json::Value& value, - userver::formats::parse::To) { - if (!value.IsString()) { + userver::formats::parse::To) +{ + if (!value.IsString()) + { throw std::runtime_error(fmt::format( "Expected string type, but got: {}", utils::GetType(value))); } diff --git a/src/models/timestring/parse.hpp b/src/models/timestring/parse.hpp index caea51b6..e0d993de 100644 --- a/src/models/timestring/parse.hpp +++ b/src/models/timestring/parse.hpp @@ -5,7 +5,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ TimeString Parse(const std::string& str, userver::formats::parse::To); TimeString Parse(const userver::formats::json::Value& value, diff --git a/src/models/timestring/postgre.hpp b/src/models/timestring/postgre.hpp index 36adbe63..69a368ae 100644 --- a/src/models/timestring/postgre.hpp +++ b/src/models/timestring/postgre.hpp @@ -4,9 +4,11 @@ #include "type.hpp" -namespace userver::storages::postgres::io { +namespace userver::storages::postgres::io +{ using timetable_vsu_backend::models::TimeString; template <> -struct CppToSystemPg : PredefinedOid { +struct CppToSystemPg : PredefinedOid +{ }; } // namespace userver::storages::postgres::io diff --git a/src/models/timestring/serialize.cpp b/src/models/timestring/serialize.cpp index 25ca2339..e44648a8 100644 --- a/src/models/timestring/serialize.cpp +++ b/src/models/timestring/serialize.cpp @@ -3,14 +3,17 @@ #include #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ std::string Serialize(const TimeString& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ return userver::utils::datetime::Timestring(value.GetUnderlying()); } userver::formats::json::Value Serialize( const TimeString& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ std::string str = Serialize(value, userver::formats::serialize::To{}); return userver::formats::json::ValueBuilder(str).ExtractValue(); diff --git a/src/models/timestring/serialize.hpp b/src/models/timestring/serialize.hpp index 03285b54..76a0ef05 100644 --- a/src/models/timestring/serialize.hpp +++ b/src/models/timestring/serialize.hpp @@ -3,7 +3,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ userver::formats::json::Value Serialize( const TimeString& value, userver::formats::serialize::To); diff --git a/src/models/timestring/type.hpp b/src/models/timestring/type.hpp index ecee3cda..77197949 100644 --- a/src/models/timestring/type.hpp +++ b/src/models/timestring/type.hpp @@ -1,7 +1,8 @@ #pragma once #include #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using TimeString = userver::utils::StrongTypedef; diff --git a/src/models/user/postgre.hpp b/src/models/user/postgre.hpp index cb84b0c3..e80f5017 100644 --- a/src/models/user/postgre.hpp +++ b/src/models/user/postgre.hpp @@ -5,7 +5,8 @@ #include "models/user/type.hpp" #include "models/user_type/postgre.hpp" #include "utils/convert/drop_properties_ref.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using TupleUserRaw = timetable_vsu_backend::utils::convert::drop_properties_to_ref_const_t; @@ -15,10 +16,11 @@ using TupleUserRaw = using TupleUser = TupleUserRaw; } // namespace timetable_vsu_backend::models -namespace userver::storages::postgres::io { - +namespace userver::storages::postgres::io +{ template <> -struct CppToUserPg { - static constexpr DBTypeName postgres_name = "vsu_timetable.userV1"; +struct CppToUserPg +{ + static constexpr DBTypeName postgres_name = "timetable_vsu.userV1"; }; } // namespace userver::storages::postgres::io diff --git a/src/models/user/type.hpp b/src/models/user/type.hpp index 5a36abdb..06e5231b 100644 --- a/src/models/user/type.hpp +++ b/src/models/user/type.hpp @@ -5,9 +5,11 @@ #include "models/user_type/type.hpp" #include "utils/convert/base.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ namespace convert = utils::convert; -struct User { +struct User +{ convert::Property id; convert::Property type; static constexpr convert::PolicyFields kPolicyFields = diff --git a/src/models/user_credentials/fwd.hpp b/src/models/user_credentials/fwd.hpp index 8cec434c..594d4a56 100644 --- a/src/models/user_credentials/fwd.hpp +++ b/src/models/user_credentials/fwd.hpp @@ -1,4 +1,5 @@ #pragma once -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ struct UserCredentials; } diff --git a/src/models/user_credentials/postgre.hpp b/src/models/user_credentials/postgre.hpp index 920a1c70..4127b7a3 100644 --- a/src/models/user_credentials/postgre.hpp +++ b/src/models/user_credentials/postgre.hpp @@ -4,18 +4,20 @@ #include "models/user_credentials/type.hpp" #include "utils/convert/drop_properties_ref.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using TupleUserCredentialsRaw = timetable_vsu_backend::utils::convert::drop_properties_to_ref_const_t< UserCredentials>; using TupleUserCredentials = TupleUserCredentialsRaw; } // namespace timetable_vsu_backend::models -namespace userver::storages::postgres::io { - +namespace userver::storages::postgres::io +{ template <> -struct CppToUserPg { +struct CppToUserPg +{ static constexpr DBTypeName postgres_name = - "vsu_timetable.user_credentials"; + "timetable_vsu.user_credentials"; }; } // namespace userver::storages::postgres::io diff --git a/src/models/user_credentials/type.hpp b/src/models/user_credentials/type.hpp index 16d644d9..181f829b 100644 --- a/src/models/user_credentials/type.hpp +++ b/src/models/user_credentials/type.hpp @@ -2,9 +2,11 @@ #include #include "utils/convert/base.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ using namespace utils::convert; -struct UserCredentials { +struct UserCredentials +{ Property login; Property password; static constexpr TypeOfBody kTypeOfBody = diff --git a/src/models/user_type/parse.cpp b/src/models/user_type/parse.cpp index 305faa26..dcf99115 100644 --- a/src/models/user_type/parse.cpp +++ b/src/models/user_type/parse.cpp @@ -8,23 +8,35 @@ #include "type.hpp" #include "utils/json_type.hpp" -namespace timetable_vsu_backend::models { -UserType Parse(std::string_view str, userver::formats::parse::To) { - if (str == "user") { +namespace timetable_vsu_backend::models +{ +UserType Parse(std::string_view str, userver::formats::parse::To) +{ + if (str == "user") + { return UserType::kUser; - } else if (str == "root") { + } + else if (str == "root") + { return UserType::kRoot; - } else if (str == "admin") { + } + else if (str == "admin") + { return UserType::kAdmin; - } else if (str == "teacher") { + } + else if (str == "teacher") + { return UserType::kTeacher; - } else + } + else throw std::runtime_error( fmt::format("Fail parse UserType, get unexpected value: {}", str)); } UserType Parse(const userver::formats::json::Value& value, - userver::formats::parse::To) { - if (!value.IsString()) { + userver::formats::parse::To) +{ + if (!value.IsString()) + { throw std::runtime_error(fmt::format( "Expected string type, but got: {}", utils::GetType(value))); } diff --git a/src/models/user_type/parse.hpp b/src/models/user_type/parse.hpp index 13ce01c3..596df3a0 100644 --- a/src/models/user_type/parse.hpp +++ b/src/models/user_type/parse.hpp @@ -5,7 +5,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ UserType Parse(std::string_view str, userver::formats::parse::To); UserType Parse(const userver::formats::json::Value& value, userver::formats::parse::To); diff --git a/src/models/user_type/postgre.hpp b/src/models/user_type/postgre.hpp index 36d1a549..fe2945c2 100644 --- a/src/models/user_type/postgre.hpp +++ b/src/models/user_type/postgre.hpp @@ -5,12 +5,14 @@ #include "type.hpp" -namespace userver::storages::postgres::io { +namespace userver::storages::postgres::io +{ using timetable_vsu_backend::models::UserType; template <> -struct CppToUserPg : EnumMappingBase { +struct CppToUserPg : EnumMappingBase +{ static constexpr userver::storages::postgres::DBTypeName postgres_name = - "vsu_timetable.user_type"; + "timetable_vsu.user_type"; static constexpr userver::utils::TrivialBiMap enumerators = [](auto selector) { return selector() diff --git a/src/models/user_type/serialize.cpp b/src/models/user_type/serialize.cpp index 15667144..6408a595 100644 --- a/src/models/user_type/serialize.cpp +++ b/src/models/user_type/serialize.cpp @@ -2,10 +2,13 @@ #include -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ std::string Serialize(const UserType& value, - userver::formats::serialize::To) { - switch (value) { + userver::formats::serialize::To) +{ + switch (value) + { case UserType::kUser: return "user"; case UserType::kAdmin: @@ -18,7 +21,8 @@ std::string Serialize(const UserType& value, } userver::formats::json::Value Serialize( const UserType& value, - userver::formats::serialize::To) { + userver::formats::serialize::To) +{ std::string str = Serialize(value, userver::formats::serialize::To{}); return userver::formats::json::ValueBuilder(str).ExtractValue(); diff --git a/src/models/user_type/serialize.hpp b/src/models/user_type/serialize.hpp index 9cc00559..91bd296b 100644 --- a/src/models/user_type/serialize.hpp +++ b/src/models/user_type/serialize.hpp @@ -3,7 +3,8 @@ #include "type.hpp" -namespace timetable_vsu_backend::models { +namespace timetable_vsu_backend::models +{ userver::formats::json::Value Serialize( const UserType& value, userver::formats::serialize::To); diff --git a/src/models/user_type/type.hpp b/src/models/user_type/type.hpp index 8a716586..a575b4a9 100644 --- a/src/models/user_type/type.hpp +++ b/src/models/user_type/type.hpp @@ -1,5 +1,12 @@ #pragma once -namespace timetable_vsu_backend::models { -enum struct UserType { kUser, kAdmin, kRoot, kTeacher }; +namespace timetable_vsu_backend::models +{ +enum struct UserType +{ + kUser, + kAdmin, + kRoot, + kTeacher +}; } diff --git a/src/utils/component_list_fwd.hpp b/src/utils/component_list_fwd.hpp index 6f669f0c..94ca43d7 100644 --- a/src/utils/component_list_fwd.hpp +++ b/src/utils/component_list_fwd.hpp @@ -1,4 +1,5 @@ #pragma once -namespace userver::components { +namespace userver::components +{ class ComponentList; } diff --git a/src/utils/constexpr_string.hpp b/src/utils/constexpr_string.hpp index c275a8a7..5f89c2a4 100644 --- a/src/utils/constexpr_string.hpp +++ b/src/utils/constexpr_string.hpp @@ -4,36 +4,43 @@ #include #include -namespace timetable_vsu_backend::utils { - +namespace timetable_vsu_backend::utils +{ template -struct ConstexprString { +struct ConstexprString +{ std::array contents{}; constexpr ConstexprString() noexcept = default; - constexpr ConstexprString(const char (&str)[Size]) noexcept { + constexpr ConstexprString(const char (&str)[Size]) noexcept + { std::copy_n(str, Size, begin(contents)); } - constexpr operator std::string_view() const { + constexpr operator std::string_view() const + { return AsStringView(); } - constexpr std::string_view AsStringView() const { + constexpr std::string_view AsStringView() const + { return {contents.begin(), contents.begin() + Size - 1}; } - constexpr auto c_str() const -> const char* { + constexpr auto c_str() const -> const char* + { return contents.data(); } friend constexpr bool operator==(const ConstexprString& string, - const char* rhs) { + const char* rhs) + { std::string_view right{rhs}; return string.AsStringView() == right; } friend constexpr bool operator==(const char* lhs, - const ConstexprString& string) { + const ConstexprString& string) + { return string == lhs; } }; diff --git a/src/utils/convert/additional_properties.hpp b/src/utils/convert/additional_properties.hpp index c0851c11..0d284d83 100644 --- a/src/utils/convert/additional_properties.hpp +++ b/src/utils/convert/additional_properties.hpp @@ -1,25 +1,28 @@ #pragma once #include "base.hpp" -namespace std { +namespace std +{ template class optional; } -namespace timetable_vsu_backend::utils::convert { - +namespace timetable_vsu_backend::utils::convert +{ template using OptionalProperty = BaseProperty, name, RequestParse::Unspecified>; template -concept IsArray = requires { +concept IsArray = requires +{ typename U::value_type; requires std::is_same_v, U>; }; template -concept IsOptionalProperty = requires { +concept IsOptionalProperty = requires +{ requires std::is_class_v; typename T::value_type; typename T::value_type::value_type; @@ -38,7 +41,8 @@ using ArrayProperty = //Оригинальный тип, спрятанный под ArrayProperty template -concept IsArrayProperty = requires { +concept IsArrayProperty = requires +{ requires std::is_class_v; typename T::value_type; typename T::value_type::value_type; @@ -54,7 +58,8 @@ using OptionalArrayProperty = BaseProperty>, name, RequestParse::Unspecified>; template -concept IsOptionalArrayProperty = requires { +concept IsOptionalArrayProperty = requires +{ requires std::is_class_v; typename T::value_type; typename T::value_type::value_type; @@ -73,7 +78,8 @@ using optional_array_property_t = //концепт проверяет, является ли свойство структурным, то есть несёт в себе //структуру, которую так же необходимо разложить template -concept IsStructuralProperty = requires { +concept IsStructuralProperty = requires +{ requires IsAnyProperty; requires IsConvertAll; }; diff --git a/src/utils/convert/base.hpp b/src/utils/convert/base.hpp index 9df92776..ae1a17a9 100644 --- a/src/utils/convert/base.hpp +++ b/src/utils/convert/base.hpp @@ -6,18 +6,24 @@ #include "utils/constexpr_string.hpp" #include "utils/meta.hpp" -namespace timetable_vsu_backend::utils::convert { +namespace timetable_vsu_backend::utils::convert +{ //В данный момент поддерживаются только конвертация всех полей -enum struct PolicyFields { ConvertAll }; +enum struct PolicyFields +{ + ConvertAll +}; //тип тела в запросе -enum struct TypeOfBody { +enum struct TypeOfBody +{ Empty, // Empty body = body игнорируеттся Json }; //указание откуда следует парсить в http запросе -enum struct RequestParse { +enum struct RequestParse +{ Unspecified, //данное поле в запросах будет парсится из body Query, Header, @@ -26,20 +32,24 @@ enum struct RequestParse { template -struct BaseProperty { +struct BaseProperty +{ using value_type = T; constexpr auto static kName = name; constexpr auto static kRequestParse = request_parse; template - value_type& operator=(Arg&& arg) { + value_type& operator=(Arg&& arg) + { value = std::forward(arg); return value; } - value_type& operator()() { + value_type& operator()() + { return value; } - const value_type& operator()() const { + const value_type& operator()() const + { return value; } value_type value; @@ -78,14 +88,18 @@ concept IsAnyProperty = std::is_class_v&& std::is_same_v< BaseProperty, T>; template -concept HasTypeOfBody = requires { - { T::kTypeOfBody } +concept HasTypeOfBody = requires +{ + { + T::kTypeOfBody + } ->std::convertible_to; requires IsConstexpr; }; template -concept IsConvertAll = requires { +concept IsConvertAll = requires +{ requires T::kPolicyFields == PolicyFields::ConvertAll; }; } // namespace timetable_vsu_backend::utils::convert diff --git a/src/utils/convert/detail/drop_properties/const_dropper_to_ref.hpp b/src/utils/convert/detail/drop_properties/const_dropper_to_ref.hpp index 87ec7eaa..0e1263d5 100644 --- a/src/utils/convert/detail/drop_properties/const_dropper_to_ref.hpp +++ b/src/utils/convert/detail/drop_properties/const_dropper_to_ref.hpp @@ -14,15 +14,18 @@ #include "../../base.hpp" #include "utils/convert/additional_properties.hpp" #include "utils/type_holder.hpp" -namespace timetable_vsu_backend::utils::convert::detail::drop_properties { - +namespace timetable_vsu_backend::utils::convert::detail::drop_properties +{ template -struct ConstDropperToRef final { - static auto Do(const T& t) { +struct ConstDropperToRef final +{ + static auto Do(const T& t) + { auto tuple = GetTuple(t); return HandleTuple(tuple, IndexSequence{}); } - static auto ResultType() { + static auto ResultType() + { return type_holder()))>{}; } @@ -37,99 +40,121 @@ struct ConstDropperToRef final { //последовательность индексов для обхода полей using IndexSequence = std::make_index_sequence; //создаем кортеж ссылок на изначальную структуру - static TupleType GetTuple(const ValueType& v) { + static TupleType GetTuple(const ValueType& v) + { return boost::pfr::structure_tie(v); } //если это usual propery, то через () получаем ссылку на изначальный объект //под template - static decltype(auto) HandleMember(const Member& member) { + static decltype(auto) HandleMember(const Member& member) + { return member(); } template - static decltype(auto) HandleMember(const Member& member) { + static decltype(auto) HandleMember(const Member& member) + { using NestedType = optional_property_t; //если вложенный тип структурный, то нужна дополнительная магия - if constexpr (IsConvertAll) { + if constexpr (IsConvertAll) + { //подсматривает результирующий тип using ResultTypeHelper = decltype(ConstDropperToRef::ResultType()); using ResultType = typename ResultTypeHelper::value_type; std::optional result = std::nullopt; - if (member().has_value()) { + if (member().has_value()) + { result = ConstDropperToRef::Do(member().value()); } return result; - } else { + } + else + { return member(); } } template - static decltype(auto) HandleMember(const Member& member) { + static decltype(auto) HandleMember(const Member& member) + { using NestedType = array_property_t; auto& value = member(); //если вложенный тип структурный, то нужна дополнительная магия - if constexpr (IsConvertAll) { + if constexpr (IsConvertAll) + { //подсматривает результирующий тип using ResultTypeHelper = decltype(ConstDropperToRef::ResultType()); using ResultType = typename ResultTypeHelper::value_type; std::vector result; result.reserve(value.size()); - for (auto& elem : value) { + for (auto& elem : value) + { result.emplace_back(ConstDropperToRef::Do(elem)); } return result; - } else { + } + else + { return member(); } } template - static decltype(auto) HandleMember(const Member& member) { + static decltype(auto) HandleMember(const Member& member) + { using NestedType = optional_array_property_t; auto& value = member(); //если вложенный тип структурный, то нужна дополнительная магия - if constexpr (IsConvertAll) { + if constexpr (IsConvertAll) + { //подсматривает результирующий тип using ResultTypeHelper = decltype(ConstDropperToRef::ResultType()); using ResultType = typename ResultTypeHelper::value_type; std::optional> result = std::nullopt; - if (value.has_value()) { + if (value.has_value()) + { result = std::vector{}; result->reserve(value->size()); - for (auto& elem : *value) { + for (auto& elem : *value) + { result.emplace_back( ConstDropperToRef::Do(elem)); } } return result; - } else { + } + else + { return member(); } } //если это структурное свойство, то раскладываем его template - static decltype(auto) HandleMember(const Member& member) { + static decltype(auto) HandleMember(const Member& member) + { using RawType = typename Member::value_type; return ConstDropperToRef::Do(member()); } template - static decltype(auto) HelpHandleMember(Tuple& tuple) { + static decltype(auto) HelpHandleMember(Tuple& tuple) + { return HandleMember(std::get(tuple)); } template - static auto ConstructResult(Type&&... values) { + static auto ConstructResult(Type&&... values) + { return std::tuple(std::forward(values)...); } template static decltype(auto) HandleTuple(Tuple& tuple, - std::index_sequence) { + std::index_sequence) + { return ConstructResult(HelpHandleMember(tuple)...); } }; diff --git a/src/utils/convert/detail/drop_properties/mut_dropper_to_ref.hpp b/src/utils/convert/detail/drop_properties/mut_dropper_to_ref.hpp index 80f1c9ba..c0507815 100644 --- a/src/utils/convert/detail/drop_properties/mut_dropper_to_ref.hpp +++ b/src/utils/convert/detail/drop_properties/mut_dropper_to_ref.hpp @@ -14,15 +14,18 @@ #include "../../base.hpp" #include "utils/convert/additional_properties.hpp" #include "utils/type_holder.hpp" -namespace timetable_vsu_backend::utils::convert::detail::drop_properties { - +namespace timetable_vsu_backend::utils::convert::detail::drop_properties +{ template -struct MutDropperToRef final { - static auto Do(T& t) { +struct MutDropperToRef final +{ + static auto Do(T& t) + { auto tuple = GetTuple(t); return HandleTuple(tuple, IndexSequence{}); } - static auto ResultType() { + static auto ResultType() + { return type_holder()))>{}; } @@ -36,98 +39,120 @@ struct MutDropperToRef final { //последовательность индексов для обхода полей using IndexSequence = std::make_index_sequence; //создаем кортеж ссылок на изначальную структуру - static TupleType GetTuple(ValueType& v) { + static TupleType GetTuple(ValueType& v) + { return boost::pfr::structure_tie(v); } //если это usual propery, то через () получаем ссылку на изначальный объект //под template - static decltype(auto) HandleMember(Member& member) { + static decltype(auto) HandleMember(Member& member) + { return member(); } template - static decltype(auto) HandleMember(Member& member) { + static decltype(auto) HandleMember(Member& member) + { using NestedType = optional_property_t; //если вложенный тип структурный, то нужна дополнительная магия - if constexpr (IsConvertAll) { + if constexpr (IsConvertAll) + { //подсматривает результирующий тип using ResultTypeHelper = decltype(MutDropperToRef::ResultType()); using ResultType = typename ResultTypeHelper::value_type; std::optional result = std::nullopt; - if (member().has_value()) { + if (member().has_value()) + { result = MutDropperToRef::Do(member().value()); } return result; - } else { + } + else + { return member(); } } template - static decltype(auto) HandleMember(Member& member) { + static decltype(auto) HandleMember(Member& member) + { using NestedType = array_property_t; auto& value = member(); //если вложенный тип структурный, то нужна дополнительная магия - if constexpr (IsConvertAll) { + if constexpr (IsConvertAll) + { //подсматривает результирующий тип using ResultTypeHelper = decltype(MutDropperToRef::ResultType()); using ResultType = typename ResultTypeHelper::value_type; std::vector result; result.reserve(value.size()); - for (auto& elem : value) { + for (auto& elem : value) + { result.emplace_back(MutDropperToRef::Do(elem)); } return result; - } else { + } + else + { return member(); } } template - static decltype(auto) HandleMember(Member& member) { + static decltype(auto) HandleMember(Member& member) + { using NestedType = optional_array_property_t; auto& value = member(); //если вложенный тип структурный, то нужна дополнительная магия - if constexpr (IsConvertAll) { + if constexpr (IsConvertAll) + { //подсматривает результирующий тип using ResultTypeHelper = decltype(MutDropperToRef::ResultType()); using ResultType = typename ResultTypeHelper::value_type; std::optional> result = std::nullopt; - if (value.has_value()) { + if (value.has_value()) + { result = std::vector{}; result->reserve(value->size()); - for (auto& elem : *value) { + for (auto& elem : *value) + { result.emplace_back(MutDropperToRef::Do(elem)); } } return result; - } else { + } + else + { return member(); } } //если это структурное свойство, то раскладываем его template - static decltype(auto) HandleMember(Member& member) { + static decltype(auto) HandleMember(Member& member) + { using RawType = typename Member::value_type; return MutDropperToRef::Do(member()); } template - static decltype(auto) HelpHandleMember(Tuple& tuple) { + static decltype(auto) HelpHandleMember(Tuple& tuple) + { return HandleMember(std::get(tuple)); } template - static auto ConstructResult(Type&&... values) { + static auto ConstructResult(Type&&... values) + { return std::tuple(std::forward(values)...); } template static decltype(auto) HandleTuple(Tuple& tuple, - std::index_sequence) { + std::index_sequence) + { return ConstructResult(HelpHandleMember(tuple)...); } }; diff --git a/src/utils/convert/detail/parse/converter_http_request.hpp b/src/utils/convert/detail/parse/converter_http_request.hpp index 7b30845c..f5c64061 100644 --- a/src/utils/convert/detail/parse/converter_http_request.hpp +++ b/src/utils/convert/detail/parse/converter_http_request.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -12,12 +13,14 @@ #include #include "../../base.hpp" -#include "userver/formats/common/meta.hpp" -namespace timetable_vsu_backend::utils::convert::detail::parse { +namespace timetable_vsu_backend::utils::convert::detail::parse +{ template -struct ConverterHttpRequest { - static void Do(T& t, const userver::server::http::HttpRequest& value) { +struct ConverterHttpRequest +{ + static void Do(T& t, const userver::server::http::HttpRequest& value) + { auto tuple = GetTuple(t); static_assert(HasTypeOfBody, "Type must have kTypeOfBody"); auto body = GetBody(value); @@ -26,27 +29,33 @@ struct ConverterHttpRequest { // protected: //тип для обозначения пустого тела - struct EmptyBody {}; + struct EmptyBody + { + }; using ValueType = T; using TupleType = decltype(boost::pfr::structure_tie(std::declval())); static constexpr std::size_t kSize = std::tuple_size::value; using IndexSequence = std::make_index_sequence; - static TupleType GetTuple(ValueType& v) { + static TupleType GetTuple(ValueType& v) + { return boost::pfr::structure_tie(v); } //проверяем, что каждое поле кортежа является Property template - static constexpr void check_properties(const std::tuple&) { + static constexpr void check_properties(const std::tuple&) + { static_assert((IsAnyProperty> && ...), "Not all properties satisfy IsProperty concept"); } //невозможно распарсить поле из тела, если оно пустое template static void ParseField(const userver::server::http::HttpRequest&, - const EmptyBody&, Field&) { - auto bad = []() { + const EmptyBody&, Field&) + { + auto bad = []() + { static_assert(flag, "Found property from body, but body marked empty"); }; @@ -55,20 +64,28 @@ struct ConverterHttpRequest { template static void ParseField(const userver::server::http::HttpRequest&, const userver::formats::json::Value& body, - Field& field) { + Field& field) + { static constexpr std::string_view kName = Field::kName; using FieldValue = typename Field::value_type; - if (body.IsNull()) { + if (body.IsNull()) + { throw std::runtime_error(fmt::format( "Unexpected null json get while parsing field: {}", kName)); - } else if (body.IsMissing()) { + } + else if (body.IsMissing()) + { throw std::runtime_error(fmt::format( "Unexpected missing json get while parsing field: {}", kName)); } - if (!body.HasMember(kName)) { - if constexpr (userver::meta::kIsOptional) { + if (!body.HasMember(kName)) + { + if constexpr (userver::meta::kIsOptional) + { field = std::nullopt; - } else { + } + else + { throw std::runtime_error( fmt::format("Missing field: {}", kName)); } @@ -78,19 +95,26 @@ struct ConverterHttpRequest { //парсим поле из query template static void ParseField(const userver::server::http::HttpRequest& value, - const userver::formats::json::Value&, Field& field) { + const userver::formats::json::Value&, Field& field) + { static constexpr std::string_view kName = Field::kName; using FieldValue = typename Field::value_type; std::string temp{kName}; auto& query_value = value.GetArg(temp); - try { - if constexpr (std::is_same_v) { + try + { + if constexpr (std::is_same_v) + { field = Field{query_value}; - } else { + } + else + { field = Parse(query_value, userver::formats::parse::To{}); } - } catch (std::exception& exc) { + } + catch (std::exception& exc) + { throw std::runtime_error(fmt::format( "Error while parsing field with name: {} and error: {}", kName, exc.what())); @@ -99,19 +123,26 @@ struct ConverterHttpRequest { //парсим поле из cookie template static void ParseField(const userver::server::http::HttpRequest& value, - const userver::formats::json::Value&, Field& field) { + const userver::formats::json::Value&, Field& field) + { static constexpr std::string_view kName = Field::kName; using FieldValue = typename Field::value_type; std::string temp{kName}; auto& cookie_value = value.GetCookie(temp); - try { - if constexpr (std::is_same_v) { + try + { + if constexpr (std::is_same_v) + { field = Field{cookie_value}; - } else { + } + else + { field = Parse(cookie_value, userver::formats::parse::To{}); } - } catch (std::exception& exc) { + } + catch (std::exception& exc) + { throw std::runtime_error(fmt::format( "Error while parsing field with name: {} and error: {}", kName, exc.what())); @@ -120,19 +151,26 @@ struct ConverterHttpRequest { //парсим поле из header template static void ParseField(const userver::server::http::HttpRequest& value, - const userver::formats::json::Value&, Field& field) { + const userver::formats::json::Value&, Field& field) + { static constexpr std::string_view kName = Field::kName; using FieldValue = typename Field::value_type; std::string temp{kName}; auto& header_value = value.GetHeader(temp); - try { - if constexpr (std::is_same_v) { + try + { + if constexpr (std::is_same_v) + { field = Field{header_value}; - } else { + } + else + { field = Parse(header_value, userver::formats::parse::To{}); } - } catch (std::exception& exc) { + } + catch (std::exception& exc) + { throw std::runtime_error(fmt::format( "Error while parsing field with name: {} and error: {}", kName, exc.what())); @@ -140,18 +178,23 @@ struct ConverterHttpRequest { } //Паттерн-матчинг относительно типа поля template - static auto GetBody(const userver::server::http::HttpRequest& value) { - if constexpr (type_of_body == TypeOfBody::Json) { + static auto GetBody(const userver::server::http::HttpRequest& value) + { + if constexpr (type_of_body == TypeOfBody::Json) + { auto json = userver::formats::json::FromString(value.RequestBody()); return json; - } else { + } + else + { return EmptyBody{}; } } template static void ParseTuple(const userver::server::http::HttpRequest& value, const Body& body, Tuple&& tuple, - std::index_sequence) { + std::index_sequence) + { check_properties(tuple); //парсим все поля (ParseField(value, body, std::get(tuple)), ...); diff --git a/src/utils/convert/detail/parse/converter_json.hpp b/src/utils/convert/detail/parse/converter_json.hpp index 20712b07..70459b45 100644 --- a/src/utils/convert/detail/parse/converter_json.hpp +++ b/src/utils/convert/detail/parse/converter_json.hpp @@ -4,10 +4,13 @@ #include "utils/convert/base.hpp" -namespace timetable_vsu_backend::utils::convert::detail::parse { +namespace timetable_vsu_backend::utils::convert::detail::parse +{ template -struct ConverterJson { - static void Do(T& t, const userver::formats::json::Value& value) { +struct ConverterJson +{ + static void Do(T& t, const userver::formats::json::Value& value) + { auto tuple = GetTuple(t); ParseTuple(value, std::move(tuple), IndexSequence{}); } @@ -22,26 +25,35 @@ struct ConverterJson { //последовательность индексов для обхода полей using IndexSequence = std::make_index_sequence; //создаем кортеж ссылок на изначальную структуру - static TupleType GetTuple(ValueType& v) { + static TupleType GetTuple(ValueType& v) + { return boost::pfr::structure_tie(v); } //для парса поля достаем соответствующее поле JSON по названию из Property template static void ParseField(const userver::formats::json::Value& value, - Field& field) { + Field& field) + { static constexpr std::string_view kName = Field::kName; using FieldValue = typename Field::value_type; - if (value.IsNull()) { + if (value.IsNull()) + { throw std::runtime_error(fmt::format( "Unexpected null json get while parsing field: {}", kName)); - } else if (value.IsMissing()) { + } + else if (value.IsMissing()) + { throw std::runtime_error(fmt::format( "Unexpected missing json get while parsing field: {}", kName)); } - if (!value.HasMember(kName)) { - if constexpr (userver::meta::kIsOptional) { + if (!value.HasMember(kName)) + { + if constexpr (userver::meta::kIsOptional) + { field = std::nullopt; - } else { + } + else + { throw std::runtime_error( fmt::format("Missing field: {}", kName)); } @@ -50,13 +62,15 @@ struct ConverterJson { } //проверяем, что каждое поле кортежа является Property template - static constexpr void check_properties(const std::tuple&) { + static constexpr void check_properties(const std::tuple&) + { static_assert((IsProperty> && ...), "Not all properties satisfy IsProperty concept"); } template static void ParseTuple(const userver::formats::json::Value& value, - TupleType&& tuple, std::index_sequence) { + TupleType&& tuple, std::index_sequence) + { check_properties(tuple); //парсим каждое поле (ParseField(value, std::get(tuple)), ...); diff --git a/src/utils/convert/detail/serialize/converter_http_response.hpp b/src/utils/convert/detail/serialize/converter_http_response.hpp index fc65cac9..d2bbb5ac 100644 --- a/src/utils/convert/detail/serialize/converter_http_response.hpp +++ b/src/utils/convert/detail/serialize/converter_http_response.hpp @@ -7,10 +7,13 @@ #include "utils/convert/base.hpp" #include "utils/convert/http_response_base.hpp" -namespace timetable_vsu_backend::utils::convert::detail::serialize { +namespace timetable_vsu_backend::utils::convert::detail::serialize +{ template -struct ConverterHttpResponse { - static void Do(const T& t, HttpResponse& response) { +struct ConverterHttpResponse +{ + static void Do(const T& t, HttpResponse& response) + { auto tuple = GetTuple(t); static_assert(HasTypeOfBody, "Type must have kTypeOfBody"); static_assert(HasStatusCode, "Type must have kStatusCode"); @@ -21,15 +24,20 @@ struct ConverterHttpResponse { } protected: - struct EmptyBody {}; - static void SetStatus(HttpResponse& response) { + struct EmptyBody + { + }; + static void SetStatus(HttpResponse& response) + { response().SetStatus(T::kStatusCode); } - static void TranslateBody(HttpResponse& response, EmptyBody&) { + static void TranslateBody(HttpResponse& response, EmptyBody&) + { response.body = ""; } static void TranslateBody(HttpResponse& response, - userver::formats::json::ValueBuilder& body) { + userver::formats::json::ValueBuilder& body) + { response.body = ToString(body.ExtractValue()); } using ValueType = T; @@ -41,20 +49,24 @@ struct ConverterHttpResponse { //последовательность индексов для обхода полей using IndexSequence = std::make_index_sequence; //создаем кортеж ссылок на поля изначальной структуры - static ConstTupleType GetTuple(const ValueType& v) { + static ConstTupleType GetTuple(const ValueType& v) + { return boost::pfr::structure_tie(v); } //проверяем, что каждое поле кортежа является Property template - static constexpr void check_properties(const std::tuple&) { + static constexpr void check_properties(const std::tuple&) + { static_assert((IsAnyProperty> && ...), "Not all properties satisfy IsProperty concept"); } //невозможно распарсить поле в тело, если оно пустое template - static void SerializeField(HttpResponse&, const EmptyBody&, const Field&) { - auto bad = []() { + static void SerializeField(HttpResponse&, const EmptyBody&, const Field&) + { + auto bad = []() + { static_assert(flag, "Found property from body, but body marked empty"); }; @@ -63,7 +75,8 @@ struct ConverterHttpResponse { template static void SerializeField(HttpResponse&, userver::formats::json::ValueBuilder& body, - const Field& field) { + const Field& field) + { static constexpr std::string_view kName = Field::kName; std::string temp{kName}; body[temp] = field(); @@ -72,8 +85,10 @@ struct ConverterHttpResponse { template static void SerializeField(HttpResponse&, userver::formats::json::ValueBuilder&, - const Field&) { - auto bad = []() { + const Field&) + { + auto bad = []() + { static_assert( flag, "A query property was found, which is invalid because " @@ -84,7 +99,8 @@ struct ConverterHttpResponse { template static void SerializeField(HttpResponse& response, userver::formats::json::ValueBuilder&, - const Field& field) { + const Field& field) + { static constexpr std::string_view kName = Field::kName; std::string temp{kName}; std::string field_value = @@ -99,7 +115,8 @@ struct ConverterHttpResponse { template static void SerializeField(HttpResponse& response, userver::formats::json::ValueBuilder&, - const Field& field) { + const Field& field) + { static constexpr std::string_view kName = Field::kName; std::string temp{kName}; std::string field_value = @@ -108,19 +125,24 @@ struct ConverterHttpResponse { } //Паттерн-матчинг относительно типа поля template - static auto GetBody() { - if constexpr (type_of_body == TypeOfBody::Json) { + static auto GetBody() + { + if constexpr (type_of_body == TypeOfBody::Json) + { //было бы неплохо поддерживать не только возврат как объекта, но //пока так return userver::formats::json::ValueBuilder( userver::formats::json::Type::kObject); - } else { + } + else + { return EmptyBody{}; } } template static void SerializeTuple(HttpResponse& response, Body& body, - Tuple&& tuple, std::index_sequence) { + Tuple&& tuple, std::index_sequence) + { check_properties(tuple); //сериализуем все поля (SerializeField(response, body, std::get(tuple)), ...); diff --git a/src/utils/convert/detail/serialize/converter_json.hpp b/src/utils/convert/detail/serialize/converter_json.hpp index 207a99f8..56bc4d4d 100644 --- a/src/utils/convert/detail/serialize/converter_json.hpp +++ b/src/utils/convert/detail/serialize/converter_json.hpp @@ -4,10 +4,13 @@ #include "utils/convert/base.hpp" -namespace timetable_vsu_backend::utils::convert::detail::serialize { +namespace timetable_vsu_backend::utils::convert::detail::serialize +{ template -struct ConverterJson { - static void Do(const T& t, userver::formats::json::ValueBuilder& value) { +struct ConverterJson +{ + static void Do(const T& t, userver::formats::json::ValueBuilder& value) + { auto tuple = GetTuple(t); SerializeTuple(value, std::move(tuple), IndexSequence{}); } @@ -22,19 +25,22 @@ struct ConverterJson { //последовательность индексов для обхода полей using IndexSequence = std::make_index_sequence; //создаем кортеж ссылок на поля изначальной структуры - static ConstTupleType GetTuple(const ValueType& v) { + static ConstTupleType GetTuple(const ValueType& v) + { return boost::pfr::structure_tie(v); } template static void SerializeField(userver::formats::json::ValueBuilder& value, - const Field& field) { + const Field& field) + { constexpr std::string_view kName = Field::kName; std::string temp{kName}; value.EmplaceNocheck(temp, field); } //проверка, что все поля являются Property template - static constexpr void check_properties(const std::tuple&) { + static constexpr void check_properties(const std::tuple&) + { static_assert((IsProperty> && ...), "Not all properties satisfy IsProperty concept"); } @@ -42,7 +48,8 @@ struct ConverterJson { template static void SerializeTuple(userver::formats::json::ValueBuilder& value, ConstTupleType&& tuple, - std::index_sequence) { + std::index_sequence) + { check_properties(tuple); //сериализуем все поля при помощи индексов (SerializeField(value, std::get(tuple)), ...); diff --git a/src/utils/convert/drop_properties_ref.hpp b/src/utils/convert/drop_properties_ref.hpp index 3cec4e11..0bd9c235 100644 --- a/src/utils/convert/drop_properties_ref.hpp +++ b/src/utils/convert/drop_properties_ref.hpp @@ -6,14 +6,16 @@ #include "base.hpp" #include "detail/drop_properties/const_dropper_to_ref.hpp" #include "detail/drop_properties/mut_dropper_to_ref.hpp" -namespace timetable_vsu_backend::utils::convert { +namespace timetable_vsu_backend::utils::convert +{ //данный концепт лишь активирует перегрузки, но не проверяет все требования для //типа template concept DroppableToTupleRef = IsConvertAll; template -concept OptionalDroppableToTupleRef = requires { +concept OptionalDroppableToTupleRef = requires +{ typename T::value_type; requires std::same_as, T>; requires IsConvertAll; @@ -22,19 +24,22 @@ concept OptionalDroppableToTupleRef = requires { //возвращает кортеж константных ссылок на поля структуры, где будут изначальные //поля template -auto DropPropertiesToMutRefs(T& t) { +auto DropPropertiesToMutRefs(T& t) +{ return detail::drop_properties::MutDropperToRef::Do(t); } //возвращает кортеж ссылок на поля структуры, где будут изначальные поля template -auto DropPropertiesToMutRefs(T& t) { +auto DropPropertiesToMutRefs(T& t) +{ using ValueType = typename std::remove_cvref_t::value_type; using ResultTypeHelper = decltype( detail::drop_properties::MutDropperToRef::ResultType()); using ResultType = typename ResultTypeHelper::value_type; std::optional result = std::nullopt; - if (t) { + if (t) + { result.emplace( detail::drop_properties::MutDropperToRef::Do(*t)); } @@ -43,19 +48,22 @@ auto DropPropertiesToMutRefs(T& t) { //возвращает кортеж ссылок на поля структуры, где будут изначальные поля template -auto DropPropertiesToConstRefs(T& t) { +auto DropPropertiesToConstRefs(T& t) +{ return detail::drop_properties::ConstDropperToRef::Do(t); } //возвращает кортеж ссылок на поля структуры, где будут изначальные поля template -auto DropPropertiesToConstRefs(const T& t) { +auto DropPropertiesToConstRefs(const T& t) +{ using ValueType = typename std::remove_cvref_t::value_type; using ResultTypeHelper = decltype( detail::drop_properties::ConstDropperToRef::ResultType()); using ResultType = typename ResultTypeHelper::value_type; std::optional result = std::nullopt; - if (t.has_value()) { + if (t.has_value()) + { result.emplace( detail::drop_properties::ConstDropperToRef::Do( t.value())); diff --git a/src/utils/convert/http_request_parse.hpp b/src/utils/convert/http_request_parse.hpp index b7828efe..db54acfb 100644 --- a/src/utils/convert/http_request_parse.hpp +++ b/src/utils/convert/http_request_parse.hpp @@ -1,18 +1,19 @@ #pragma once #include "detail/parse/converter_http_request.hpp" -namespace timetable_vsu_backend::utils::convert { +namespace timetable_vsu_backend::utils::convert +{ //данный концепт лишь активирует перегрузки, но не проверяет все требования для //типа template concept HttpRequestParsable = IsConvertAll&& HasTypeOfBody; } // namespace timetable_vsu_backend::utils::convert -namespace userver::formats::parse { - +namespace userver::formats::parse +{ template -T Parse(const userver::server::http::HttpRequest& value, - formats::parse::To) { +T Parse(const userver::server::http::HttpRequest& value, formats::parse::To) +{ T t; timetable_vsu_backend::utils::convert::detail::parse::ConverterHttpRequest< T>::Do(t, value); diff --git a/src/utils/convert/http_response_base.hpp b/src/utils/convert/http_response_base.hpp index 4afb58b3..96028600 100644 --- a/src/utils/convert/http_response_base.hpp +++ b/src/utils/convert/http_response_base.hpp @@ -3,24 +3,32 @@ #include "utils/meta.hpp" -namespace userver::server::http { +namespace userver::server::http +{ class HttpResponse; } -namespace timetable_vsu_backend::utils::convert { -struct HttpResponse { +namespace timetable_vsu_backend::utils::convert +{ +struct HttpResponse +{ userver::server::http::HttpResponse& response; std::string& body; - userver::server::http::HttpResponse& operator()() { + userver::server::http::HttpResponse& operator()() + { return response; } - userver::server::http::HttpResponse& operator()() const { + userver::server::http::HttpResponse& operator()() const + { return response; } }; template -concept HasStatusCode = requires { - { T::kStatusCode } +concept HasStatusCode = requires +{ + { + T::kStatusCode + } ->std::convertible_to; requires IsConstexpr; }; diff --git a/src/utils/convert/http_response_serialize.hpp b/src/utils/convert/http_response_serialize.hpp index cdf6f9dc..9ce6ac36 100644 --- a/src/utils/convert/http_response_serialize.hpp +++ b/src/utils/convert/http_response_serialize.hpp @@ -1,7 +1,8 @@ #pragma once #include "detail/serialize/converter_http_response.hpp" -namespace timetable_vsu_backend::utils::convert { +namespace timetable_vsu_backend::utils::convert +{ //данный концепт лишь активирует перегрузки, но не проверяет все требования для //типа template @@ -9,7 +10,8 @@ concept HttpResponseSeriazable = IsConvertAll&& HasTypeOfBody&& HasStatusCode; template -void Serialize(const T& t, HttpResponse& response) { +void Serialize(const T& t, HttpResponse& response) +{ detail::serialize::ConverterHttpResponse::Do(t, response); } } // namespace timetable_vsu_backend::utils::convert diff --git a/src/utils/convert/json_parse.hpp b/src/utils/convert/json_parse.hpp index 4be73456..1bb261b2 100644 --- a/src/utils/convert/json_parse.hpp +++ b/src/utils/convert/json_parse.hpp @@ -4,22 +4,25 @@ #include "detail/parse/converter_json.hpp" -namespace timetable_vsu_backend::utils::convert { +namespace timetable_vsu_backend::utils::convert +{ //данный концепт лишь активирует перегрузки, но не проверяет все требования для //типа template concept JsonParsable = IsConvertAll; } // namespace timetable_vsu_backend::utils::convert -namespace userver::formats::parse { - +namespace userver::formats::parse +{ template -T Parse(const json::Value& value, To) { +T Parse(const json::Value& value, To) +{ return T{value.As()}; } template -T Parse(const json::Value& value, To) { +T Parse(const json::Value& value, To) +{ T t; timetable_vsu_backend::utils::convert::detail::parse::ConverterJson::Do( t, value); diff --git a/src/utils/convert/json_serialize.hpp b/src/utils/convert/json_serialize.hpp index 3fd072a7..1bf28536 100644 --- a/src/utils/convert/json_serialize.hpp +++ b/src/utils/convert/json_serialize.hpp @@ -2,22 +2,25 @@ #include "detail/serialize/converter_json.hpp" #include "utils/convert/base.hpp" -namespace timetable_vsu_backend::utils::convert { +namespace timetable_vsu_backend::utils::convert +{ //данный концепт лишь активирует перегрузки, но не проверяет все требования для //типа template concept JsonSeriazable = IsConvertAll; } // namespace timetable_vsu_backend::utils::convert -namespace userver::formats::serialize { - +namespace userver::formats::serialize +{ template -json::Value Serialize(const T& t, To) { +json::Value Serialize(const T& t, To) +{ return json::ValueBuilder(t.value).ExtractValue(); } template -json::Value Serialize(const T& t, To) { +json::Value Serialize(const T& t, To) +{ json::ValueBuilder json; timetable_vsu_backend::utils::convert::detail::serialize::ConverterJson< T>::Do(t, json); diff --git a/src/utils/json_type.cpp b/src/utils/json_type.cpp index 13fdcbde..36491357 100644 --- a/src/utils/json_type.cpp +++ b/src/utils/json_type.cpp @@ -3,27 +3,47 @@ #include #include -namespace timetable_vsu_backend::utils { -std::string_view GetType(const userver::formats::json::Value& value) { - if (value.IsNull()) { +namespace timetable_vsu_backend::utils +{ +std::string_view GetType(const userver::formats::json::Value& value) +{ + if (value.IsNull()) + { return "Null"; - } else if (value.IsArray()) { + } + else if (value.IsArray()) + { return "Array"; - } else if (value.IsBool()) { + } + else if (value.IsBool()) + { return "Bool"; - } else if (value.IsDouble()) { + } + else if (value.IsDouble()) + { return "Double"; - } else if (value.IsInt()) { + } + else if (value.IsInt()) + { return "Int"; - } else if (value.IsInt64()) { + } + else if (value.IsInt64()) + { return "Int64"; - } else if (value.IsUInt64()) { + } + else if (value.IsUInt64()) + { return "UInt64"; - } else if (value.IsObject()) { + } + else if (value.IsObject()) + { return "Object"; - } else if (value.IsString()) { + } + else if (value.IsString()) + { return "String"; - } else + } + else return "Unknown"; } } // namespace timetable_vsu_backend::utils diff --git a/src/utils/json_type.hpp b/src/utils/json_type.hpp index a13a2da2..c78fce86 100644 --- a/src/utils/json_type.hpp +++ b/src/utils/json_type.hpp @@ -3,6 +3,7 @@ #include #include -namespace timetable_vsu_backend::utils { +namespace timetable_vsu_backend::utils +{ std::string_view GetType(const userver::formats::json::Value& value); } diff --git a/src/utils/meta.hpp b/src/utils/meta.hpp index 4f8989fd..0ad0fba4 100644 --- a/src/utils/meta.hpp +++ b/src/utils/meta.hpp @@ -1,5 +1,6 @@ #pragma once template -concept IsConstexpr = requires { +concept IsConstexpr = requires +{ requires true; }; diff --git a/src/utils/parse/uuid/string.cpp b/src/utils/parse/uuid/string.cpp index 3b3ba5c2..48351ca3 100644 --- a/src/utils/parse/uuid/string.cpp +++ b/src/utils/parse/uuid/string.cpp @@ -4,9 +4,11 @@ #include #include -namespace userver::formats::parse { +namespace userver::formats::parse +{ boost::uuids::uuid Parse(const std::string& value, - userver::formats::parse::To) { + userver::formats::parse::To) +{ return boost::lexical_cast(value); } } // namespace userver::formats::parse diff --git a/src/utils/parse/uuid/string.hpp b/src/utils/parse/uuid/string.hpp index a79c1556..376bf743 100644 --- a/src/utils/parse/uuid/string.hpp +++ b/src/utils/parse/uuid/string.hpp @@ -3,7 +3,8 @@ #include #include #include -namespace userver::formats::parse { +namespace userver::formats::parse +{ boost::uuids::uuid Parse(const std::string& value, userver::formats::parse::To); } diff --git a/src/utils/postgres_helper.hpp b/src/utils/postgres_helper.hpp index 2a233da4..05b9fc1b 100644 --- a/src/utils/postgres_helper.hpp +++ b/src/utils/postgres_helper.hpp @@ -1,92 +1,116 @@ #pragma once #include +#include +#include +#include #include #include "convert/base.hpp" -#include "userver/storages/postgres/exceptions.hpp" -#include "userver/storages/postgres/io/row_types.hpp" -#include "userver/storages/postgres/query.hpp" +#include "userver/utils/meta.hpp" #include "utils/convert/drop_properties_ref.hpp" #include "utils/shared_transaction.hpp" -namespace timetable_vsu_backend::utils { +namespace timetable_vsu_backend::utils +{ //Прямая конвертация используя встроенные методы pg_result не будет работать с //рефлективными типами. Использует промежуточные кортежи ссылок для перегона //данных. -template +template std::vector ConvertPgResultToArray( - const userver::storages::postgres::ResultSet& pg_result) { - std::vector result; - result.reserve(pg_result.Size()); - for (auto& row : pg_result) { - To to; - auto tuple_to = convert::DropPropertiesToMutRefs(to); - row.To(tuple_to, userver::storages::postgres::kRowTag); - result.emplace_back(std::move(to)); + const userver::storages::postgres::ResultSet& pg_result) +{ + if constexpr (convert::IsConvertAll) + { + std::vector result; + result.reserve(pg_result.Size()); + for (auto& row : pg_result) + { + To to; + auto tuple_to = convert::DropPropertiesToMutRefs(to); + row.To(tuple_to, userver::storages::postgres::kRowTag); + result.emplace_back(std::move(to)); + } + return result; } - return result; + else + return pg_result.AsContainer>(); } //Прямая конвертация используя встроенные методы pg_result не будет работать с //рефлективными типами. Использует промежуточные кортежи ссылок для перегона //данных. //@throws userver::storages::postgres::NonSingleRowResultSet, если размер сета //!= 1 -template +template To ConvertPgResultToItem( - const userver::storages::postgres::ResultSet& pg_result) { - if (pg_result.Size() != 1) { + const userver::storages::postgres::ResultSet& pg_result) +{ + if (pg_result.Size() != 1) + { throw userver::storages::postgres::NonSingleRowResultSet( pg_result.Size()); } - To to; - auto tuple_to = convert::DropPropertiesToMutRefs(to); - pg_result[0].To(tuple_to, userver::storages::postgres::kRowTag); - return to; + if constexpr (convert::IsConvertAll) + { + To to; + auto tuple_to = convert::DropPropertiesToMutRefs(to); + pg_result[0].To(tuple_to, userver::storages::postgres::kRowTag); + return to; + } + else + return pg_result.AsSingleRow(); } -template +template std::optional ConvertPgResultToOptionalItem( - const userver::storages::postgres::ResultSet& pg_result) { - if (pg_result.Size() > 1) { + const userver::storages::postgres::ResultSet& pg_result) +{ + if (pg_result.Size() > 1) + { throw userver::storages::postgres::NonSingleRowResultSet( pg_result.Size()); - } else if (pg_result.IsEmpty()) { + } + else if (pg_result.IsEmpty()) + { return std::nullopt; } - To to; - auto tuple_to = convert::DropPropertiesToMutRefs(to); - pg_result[0].To(tuple_to, userver::storages::postgres::kRowTag); - return to; + if constexpr (convert::IsConvertAll) + { + To to; + auto tuple_to = convert::DropPropertiesToMutRefs(to); + pg_result[0].To(tuple_to, userver::storages::postgres::kRowTag); + return to; + } + else + return pg_result.AsSingleRow(); } -//обертка для повседневного использования магических структур -//так как было решено во всех контроллерах использовать shared transaction, то -//этого интерфейса достаточно -template -userver::storages::postgres::ResultSet PgExecute( - const vsu_timetable::utils::SharedTransaction& transaction, - const userver::storages::postgres::Query& query, Args&&... args) { - auto some_magic = - [... tuple_args = convert::DropPropertiesToConstRefs(args)]( - const vsu_timetable::utils::SharedTransaction& transaction, - const userver::storages::postgres::Query& query) mutable { - return transaction->transaction_.Execute(query, tuple_args...); - }; - return some_magic(transaction, query); + +namespace details +{ +//Небольшой хелпер, чтобы обобщить обработку рефлективных типов и нерефлективных +template +decltype(auto) HelpForwardArg(const Arg& arg) +{ + //если это рефлективный тип, то превращаем в кортеж + if constexpr (convert::DroppableToTupleRef || + convert::OptionalDroppableToTupleRef) + { + return convert::DropPropertiesToConstRefs(arg); + } + //в противном случае ничего не делаем + else + return arg; } +} // namespace details + //обертка для повседневного использования магических структур //так как было решено во всех контроллерах использовать shared transaction, то //этого интерфейса достаточно -template +template userver::storages::postgres::ResultSet PgExecute( - const vsu_timetable::utils::SharedTransaction& transaction, - const userver::storages::postgres::Query& query, - const std::optional&... args) { - auto some_magic = - [... tuple_args = convert::DropPropertiesToConstRefs(args)]( - const vsu_timetable::utils::SharedTransaction& transaction, - const userver::storages::postgres::Query& query) mutable { - return transaction->transaction_.Execute(query, tuple_args...); - }; - return some_magic(transaction, query); + const timetable_vsu_backend::utils::SharedTransaction& transaction, + const userver::storages::postgres::Query& query, const Args&... args) +{ + return transaction->transaction_.Execute(query, + details::HelpForwardArg(args)...); } } // namespace timetable_vsu_backend::utils diff --git a/src/utils/shared_transaction.hpp b/src/utils/shared_transaction.hpp index a7e3c939..53da8293 100644 --- a/src/utils/shared_transaction.hpp +++ b/src/utils/shared_transaction.hpp @@ -5,29 +5,35 @@ #include #include -namespace vsu_timetable::utils { - +namespace timetable_vsu_backend::utils +{ // thread unsafe // count owners -struct SafeTranscaction { +struct SafeTranscaction +{ userver::storages::postgres::Transaction transaction_; SafeTranscaction(const userver::storages::postgres::ClusterPtr& ptr, const std::string& name, bool auto_commit) : transaction_(ptr->Begin( name, userver::storages::postgres::ClusterHostType::kMaster, {})), - auto_commit_(auto_commit) { + auto_commit_(auto_commit) + { } - friend void intrusive_ptr_add_ref(SafeTranscaction* transaction) { + friend void intrusive_ptr_add_ref(SafeTranscaction* transaction) + { transaction->counter++; } - friend void intrusive_ptr_release(SafeTranscaction* transaction) { + friend void intrusive_ptr_release(SafeTranscaction* transaction) + { transaction->counter--; if (transaction->counter == 0) delete transaction; } - ~SafeTranscaction() { - if (auto_commit_) { + ~SafeTranscaction() + { + if (auto_commit_) + { transaction_.Commit(); } } @@ -51,7 +57,8 @@ using SharedTransaction = boost::intrusive_ptr; inline auto MakeSharedTransaction( const userver::storages::postgres::ClusterPtr& ptr, - const std::string& name = "", bool auto_commit = true) { + const std::string& name = "", bool auto_commit = true) +{ return userver::utils::make_intrusive_ptr(ptr, name, auto_commit); } @@ -59,10 +66,12 @@ inline auto MakeSharedTransaction( inline void FillSharedTransaction( SharedTransaction& transaction, const userver::storages::postgres::ClusterPtr& ptr, - const std::string& name = "", bool auto_commit = true) { - if (!transaction) { - transaction = - vsu_timetable::utils::MakeSharedTransaction(ptr, name, auto_commit); + const std::string& name = "", bool auto_commit = true) +{ + if (!transaction) + { + transaction = timetable_vsu_backend::utils::MakeSharedTransaction( + ptr, name, auto_commit); } } -} // namespace vsu_timetable::utils +} // namespace timetable_vsu_backend::utils diff --git a/src/utils/type_holder.hpp b/src/utils/type_holder.hpp index 29d63d22..5aefdf3a 100644 --- a/src/utils/type_holder.hpp +++ b/src/utils/type_holder.hpp @@ -1,5 +1,6 @@ #pragma once template -struct type_holder { +struct type_holder +{ using value_type = Type; }; diff --git a/src/views/admin/create/Request.hpp b/src/views/admin/create/Request.hpp index f671c31b..896e6642 100644 --- a/src/views/admin/create/Request.hpp +++ b/src/views/admin/create/Request.hpp @@ -1,16 +1,18 @@ #pragma once #include +#include #include #include "models/user_credentials/type.hpp" -#include "userver/formats/json/value.hpp" #include "utils/convert/base.hpp" #include "utils/convert/http_request_parse.hpp" #include "utils/convert/json_parse.hpp" #include "utils/parse/uuid/string.hpp" -namespace timetable_vsu_backend::views::admin::create { +namespace timetable_vsu_backend::views::admin::create +{ using namespace utils::convert; -struct Request { +struct Request +{ Property credentials; HeaderProperty token; static constexpr auto kPolicyFields = PolicyFields::ConvertAll; diff --git a/src/views/admin/create/Responses.hpp b/src/views/admin/create/Responses.hpp index cb313248..3756b0bd 100644 --- a/src/views/admin/create/Responses.hpp +++ b/src/views/admin/create/Responses.hpp @@ -1,20 +1,22 @@ #pragma once #include #include +#include #include "http/ErrorV1.hpp" #include "models/admin_account/type.hpp" #include "models/user/type.hpp" #include "models/user_type/serialize.hpp" #include "models/user_type/type.hpp" -#include "userver/server/http/http_status.hpp" #include "utils/convert/base.hpp" #include "utils/convert/http_response_serialize.hpp" #include "utils/convert/json_parse.hpp" -namespace timetable_vsu_backend::views::admin::create { +namespace timetable_vsu_backend::views::admin::create +{ using namespace utils::convert; -struct Response200 { +struct Response200 +{ Property created_account; static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Json; @@ -32,7 +34,8 @@ using Response401 = using Response403 = http::ErrorV1; -struct Response500 { +struct Response500 +{ static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Empty; static constexpr PolicyFields kPolicyFields = PolicyFields::ConvertAll; static constexpr userver::server::http::HttpStatus kStatusCode = diff --git a/src/views/admin/create/view.cpp b/src/views/admin/create/view.cpp index 9dc91219..de6b5357 100644 --- a/src/views/admin/create/view.cpp +++ b/src/views/admin/create/view.cpp @@ -16,29 +16,34 @@ #include "models/user/serialize.hpp" #include "models/user_type/serialize.hpp" #include "utils/parse/uuid/string.hpp" -namespace timetable_vsu_backend::views::admin::create { - +namespace timetable_vsu_backend::views::admin::create +{ static_assert( userver::formats::common::impl::kHasSerialize< userver::formats::json::Value, timetable_vsu_backend::models::User>); -namespace { +namespace +{ namespace pg = components::controllers::postgres; class Handler final : public http::HandlerParsed { - static Response400 PerformLoginTaken() { + Response403> +{ + static Response400 PerformLoginTaken() + { Response400 resp; resp.description = "Account can't created: login is already taken"; resp.machine_id = "LOGIN_TAKEN"; return resp; } - static Response401 PerformInvalidToken() { + static Response401 PerformInvalidToken() + { Response401 resp; resp.description = "Account not founded: token invalid"; resp.machine_id = "INVALID_TOKEN"; return resp; } - static Response403 PerformForbidden() { + static Response403 PerformForbidden() + { Response403 resp; resp.description = "Not enough permissions to do so"; resp.machine_id = "NOT_ENOUGH_PERMISSIONS"; @@ -52,19 +57,24 @@ class Handler final const userver::components::ComponentContext& context) : HandlerParsed(config, context), user_controller(context.FindComponent()), - admin_controller(context.FindComponent()) { + admin_controller(context.FindComponent()) + { } - Response Handle(Request&& request) const override { + Response Handle(Request&& request) const override + { auto user = user_controller.GetByToken(request.token()); - if (!user) { + if (!user) + { return PerformInvalidToken(); } - if (user->type() != models::UserType::kRoot) { + if (user->type() != models::UserType::kRoot) + { return PerformForbidden(); } auto admin = admin_controller.CreateAdmin(request.credentials()); - if (!admin) { + if (!admin) + { return PerformLoginTaken(); } Response200 resp; @@ -78,7 +88,8 @@ class Handler final }; } // namespace -void Append(userver::components::ComponentList& component_list) { +void Append(userver::components::ComponentList& component_list) +{ component_list.Append(); } diff --git a/src/views/admin/create/view.hpp b/src/views/admin/create/view.hpp index 0512c848..0ac146a6 100644 --- a/src/views/admin/create/view.hpp +++ b/src/views/admin/create/view.hpp @@ -1,7 +1,7 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::views::admin::create { - +namespace timetable_vsu_backend::views::admin::create +{ void Append(userver::components::ComponentList& component_list); } diff --git a/src/views/admin/list/Request.hpp b/src/views/admin/list/Request.hpp index 792f6025..cb83530f 100644 --- a/src/views/admin/list/Request.hpp +++ b/src/views/admin/list/Request.hpp @@ -1,16 +1,18 @@ #pragma once #include +#include #include #include "models/admin_filter/postgre.hpp" -#include "userver/formats/json/value.hpp" #include "utils/convert/base.hpp" #include "utils/convert/http_request_parse.hpp" #include "utils/convert/json_parse.hpp" #include "utils/parse/uuid/string.hpp" -namespace timetable_vsu_backend::views::admin::list { +namespace timetable_vsu_backend::views::admin::list +{ using namespace utils::convert; -struct Request { +struct Request +{ OptionalProperty filter; HeaderProperty token; static constexpr auto kPolicyFields = PolicyFields::ConvertAll; diff --git a/src/views/admin/list/Responses.hpp b/src/views/admin/list/Responses.hpp index d0bb1e23..6d0471e8 100644 --- a/src/views/admin/list/Responses.hpp +++ b/src/views/admin/list/Responses.hpp @@ -1,21 +1,23 @@ #pragma once #include #include +#include #include "http/ErrorV1.hpp" #include "models/admin_account/type.hpp" #include "models/user/type.hpp" #include "models/user_type/serialize.hpp" #include "models/user_type/type.hpp" -#include "userver/server/http/http_status.hpp" #include "utils/convert/additional_properties.hpp" #include "utils/convert/base.hpp" #include "utils/convert/http_response_serialize.hpp" #include "utils/convert/json_parse.hpp" -namespace timetable_vsu_backend::views::admin::list { +namespace timetable_vsu_backend::views::admin::list +{ using namespace utils::convert; -struct Response200 { +struct Response200 +{ ArrayProperty admins; static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Json; static constexpr PolicyFields kPolicyFields = PolicyFields::ConvertAll; @@ -32,7 +34,8 @@ using Response401 = using Response403 = http::ErrorV1; -struct Response500 { +struct Response500 +{ static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Empty; static constexpr PolicyFields kPolicyFields = PolicyFields::ConvertAll; static constexpr userver::server::http::HttpStatus kStatusCode = diff --git a/src/views/admin/list/view.cpp b/src/views/admin/list/view.cpp index 5d2ba9c3..c3ee6656 100644 --- a/src/views/admin/list/view.cpp +++ b/src/views/admin/list/view.cpp @@ -18,29 +18,34 @@ #include "models/user/serialize.hpp" #include "models/user_type/serialize.hpp" #include "utils/parse/uuid/string.hpp" -namespace timetable_vsu_backend::views::admin::list { - +namespace timetable_vsu_backend::views::admin::list +{ static_assert( userver::formats::common::impl::kHasSerialize< userver::formats::json::Value, timetable_vsu_backend::models::User>); -namespace { +namespace +{ namespace pg = components::controllers::postgres; class Handler final : public http::HandlerParsed { - static Response400 PerformLoginTaken() { + Response403> +{ + static Response400 PerformLoginTaken() + { Response400 resp; resp.description = "Account can't created: login is already taken"; resp.machine_id = "LOGIN_TAKEN"; return resp; } - static Response401 PerformInvalidToken() { + static Response401 PerformInvalidToken() + { Response401 resp; resp.description = "Account not founded: token invalid"; resp.machine_id = "INVALID_TOKEN"; return resp; } - static Response403 PerformForbidden() { + static Response403 PerformForbidden() + { Response403 resp; resp.description = "Not enough permissions to do so"; resp.machine_id = "NOT_ENOUGH_PERMISSIONS"; @@ -54,15 +59,19 @@ class Handler final const userver::components::ComponentContext& context) : HandlerParsed(config, context), user_controller(context.FindComponent()), - admin_controller(context.FindComponent()) { + admin_controller(context.FindComponent()) + { } - Response Handle(Request&& request) const override { + Response Handle(Request&& request) const override + { auto user = user_controller.GetByToken(request.token()); - if (!user) { + if (!user) + { return PerformInvalidToken(); } - if (user->type() != models::UserType::kRoot) { + if (user->type() != models::UserType::kRoot) + { return PerformForbidden(); } auto admins = admin_controller.GetByFilter(request.filter()); @@ -77,7 +86,8 @@ class Handler final }; } // namespace -void Append(userver::components::ComponentList& component_list) { +void Append(userver::components::ComponentList& component_list) +{ component_list.Append(); } diff --git a/src/views/admin/list/view.hpp b/src/views/admin/list/view.hpp index 9c3a68dd..efeb621b 100644 --- a/src/views/admin/list/view.hpp +++ b/src/views/admin/list/view.hpp @@ -1,7 +1,7 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::views::admin::list { - +namespace timetable_vsu_backend::views::admin::list +{ void Append(userver::components::ComponentList& component_list); } diff --git a/src/views/hello/view.cpp b/src/views/hello/view.cpp index fbfcb649..41a332c1 100644 --- a/src/views/hello/view.cpp +++ b/src/views/hello/view.cpp @@ -8,11 +8,12 @@ #include #include -namespace service_template { - -namespace { - -class Hello final : public userver::server::handlers::HttpHandlerBase { +namespace service_template +{ +namespace +{ +class Hello final : public userver::server::handlers::HttpHandlerBase +{ public: static constexpr std::string_view kName = "handler-hello"; @@ -22,16 +23,19 @@ class Hello final : public userver::server::handlers::HttpHandlerBase { pg_cluster_( component_context .FindComponent("postgres-db-1") - .GetCluster()) { + .GetCluster()) + { } std::string HandleRequestThrow( const userver::server::http::HttpRequest& request, - userver::server::request::RequestContext&) const override { + userver::server::request::RequestContext&) const override + { const auto& name = request.GetArg("name"); auto user_type = UserType::kFirstTime; - if (!name.empty()) { + if (!name.empty()) + { auto result = pg_cluster_->Execute( userver::storages::postgres::ClusterHostType::kMaster, "INSERT INTO hello_schema.users(name, count) VALUES($1, 1) " @@ -40,7 +44,8 @@ class Hello final : public userver::server::handlers::HttpHandlerBase { "RETURNING users.count", name); - if (result.AsSingleRow() > 1) { + if (result.AsSingleRow() > 1) + { user_type = UserType::kKnown; } } @@ -53,12 +58,15 @@ class Hello final : public userver::server::handlers::HttpHandlerBase { } // namespace -std::string SayHelloTo(std::string_view name, UserType type) { - if (name.empty()) { +std::string SayHelloTo(std::string_view name, UserType type) +{ + if (name.empty()) + { name = "unknown user"; } - switch (type) { + switch (type) + { case UserType::kFirstTime: return fmt::format("Hello, {}!\n", name); case UserType::kKnown: @@ -68,7 +76,8 @@ std::string SayHelloTo(std::string_view name, UserType type) { UASSERT(false); } -void AppendHello(userver::components::ComponentList& component_list) { +void AppendHello(userver::components::ComponentList& component_list) +{ component_list.Append(); } diff --git a/src/views/hello/view.hpp b/src/views/hello/view.hpp index 6e14a601..f5a160df 100644 --- a/src/views/hello/view.hpp +++ b/src/views/hello/view.hpp @@ -4,9 +4,13 @@ #include #include -namespace service_template { - -enum class UserType { kFirstTime, kKnown }; +namespace service_template +{ +enum class UserType +{ + kFirstTime, + kKnown +}; std::string SayHelloTo(std::string_view name, UserType type); void AppendHello(userver::components::ComponentList& component_list); diff --git a/src/views/login/Request.hpp b/src/views/login/Request.hpp index c5d268e5..dd967d53 100644 --- a/src/views/login/Request.hpp +++ b/src/views/login/Request.hpp @@ -2,6 +2,7 @@ #include "models/user_credentials/type.hpp" #include "utils/convert/http_request_parse.hpp" #include "utils/convert/json_parse.hpp" -namespace timetable_vsu_backend::views::login { +namespace timetable_vsu_backend::views::login +{ using Request = models::UserCredentials; } // namespace timetable_vsu_backend::views::login diff --git a/src/views/login/Responses.hpp b/src/views/login/Responses.hpp index e91a0e1a..e5ab1479 100644 --- a/src/views/login/Responses.hpp +++ b/src/views/login/Responses.hpp @@ -10,9 +10,11 @@ #include "utils/convert/http_response_serialize.hpp" #include "utils/convert/json_parse.hpp" -namespace timetable_vsu_backend::views::login { +namespace timetable_vsu_backend::views::login +{ using namespace utils::convert; -struct Response200 { +struct Response200 +{ Property id; Property user; static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Json; @@ -22,7 +24,8 @@ struct Response200 { }; using Response401 = http::ErrorV1; -struct Response500 { +struct Response500 +{ static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Empty; static constexpr PolicyFields kPolicyFields = PolicyFields::ConvertAll; static constexpr userver::server::http::HttpStatus kStatusCode = diff --git a/src/views/login/view.cpp b/src/views/login/view.cpp index b85f8c85..16d3717c 100644 --- a/src/views/login/view.cpp +++ b/src/views/login/view.cpp @@ -16,16 +16,19 @@ #include "models/user/serialize.hpp" #include "models/user_type/serialize.hpp" -namespace timetable_vsu_backend::views::login { - +namespace timetable_vsu_backend::views::login +{ static_assert( userver::formats::common::impl::kHasSerialize< userver::formats::json::Value, timetable_vsu_backend::models::User>); -namespace { +namespace +{ namespace pg = components::controllers::postgres; -class Handler final : public http::HandlerParsed { - static Response401 PerformInvalidCredentials() { +class Handler final + : public http::HandlerParsed +{ + static Response401 PerformInvalidCredentials() + { Response401 resp; resp.description = "Account not founded: login or password invalid"; resp.machine_id = "INVALID_CREDENTIALS"; @@ -38,18 +41,22 @@ class Handler final : public http::HandlerParsed()), - token_controller(context.FindComponent()) { + token_controller(context.FindComponent()) + { } - Response Handle(Request&& request) const override { + Response Handle(Request&& request) const override + { auto user = user_controller.GetByCredentials(request); - if (!user) { + if (!user) + { return PerformInvalidCredentials(); } auto id = token_controller.CreateNew( user->id(), userver::utils::datetime::Now() + std::chrono::hours(24)); - if (!id) { + if (!id) + { LOG_WARNING() << fmt::format( "Failed to create token for user, id: {}", boost::uuids::to_string(user->id())); @@ -67,7 +74,8 @@ class Handler final : public http::HandlerParsed(); } diff --git a/src/views/login/view.hpp b/src/views/login/view.hpp index 2f940d01..7db14934 100644 --- a/src/views/login/view.hpp +++ b/src/views/login/view.hpp @@ -1,7 +1,7 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::views::login { - +namespace timetable_vsu_backend::views::login +{ void Append(userver::components::ComponentList& component_list); } diff --git a/src/views/register/Request.hpp b/src/views/register/Request.hpp index a9731bda..72053499 100644 --- a/src/views/register/Request.hpp +++ b/src/views/register/Request.hpp @@ -1,7 +1,8 @@ #pragma once -#include "models/user_credentials/type.hpp" +#include "models/register_request/type.hpp" #include "utils/convert/http_request_parse.hpp" #include "utils/convert/json_parse.hpp" -namespace timetable_vsu_backend::views::register_ { -using Request = models::UserCredentials; +namespace timetable_vsu_backend::views::register_ +{ +using Request = models::RegisterRequest; } // namespace timetable_vsu_backend::views::register_ diff --git a/src/views/register/Responses.hpp b/src/views/register/Responses.hpp index 9522852e..dfa10ab4 100644 --- a/src/views/register/Responses.hpp +++ b/src/views/register/Responses.hpp @@ -10,9 +10,11 @@ #include "utils/convert/http_response_serialize.hpp" #include "utils/convert/json_parse.hpp" -namespace timetable_vsu_backend::views::register_ { +namespace timetable_vsu_backend::views::register_ +{ using namespace utils::convert; -struct Response200 { +struct Response200 +{ Property id; Property user; static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Json; @@ -22,7 +24,8 @@ struct Response200 { }; using Response400 = http::ErrorV1; -struct Response500 { +struct Response500 +{ static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Empty; static constexpr PolicyFields kPolicyFields = PolicyFields::ConvertAll; static constexpr userver::server::http::HttpStatus kStatusCode = diff --git a/src/views/register/view.cpp b/src/views/register/view.cpp index 9e0ac285..626df9ec 100644 --- a/src/views/register/view.cpp +++ b/src/views/register/view.cpp @@ -20,15 +20,20 @@ #include "http/handler_parsed.hpp" #include "models/auth_token/serialize.hpp" #include "models/user/serialize.hpp" +#include "models/user_type/parse.hpp" +#include "models/user_type/type.hpp" +#include "utils/shared_transaction.hpp" #include "views/register/Responses.hpp" -namespace timetable_vsu_backend::views::register_ { - -namespace { +namespace timetable_vsu_backend::views::register_ +{ +namespace +{ namespace pg = components::controllers::postgres; using Response = models::AuthToken; -class Handler final : public http::HandlerParsed { +class Handler final + : public http::HandlerParsed +{ public: static constexpr std::string_view kName = "handler-register"; using http::HandlerParsed()), - token_controller(context.FindComponent()) { + token_controller(context.FindComponent()) + { } - - Response Handle(Request&& request) const override { - auto user_id = user_controller.TryToAdd(request); - if (!user_id) { - LOG_DEBUG() << fmt::format("Cannot create user, login: {}", - request.login()); - return Response400{}; + static Response400 PerformLoginTaken() + { + Response400 resp400; + resp400.machine_id() = "LOGIN_ALREADY_TAKEN"; + resp400.description() = "This login is busy, please use another one."; + return resp400; + } + static Response500 PerformFailToken(const boost::uuids::uuid& user_id) + { + LOG_WARNING() << fmt::format("Failed to create token for user, id: {}", + user_id); + return Response500{}; + } + void HandleDesiredType(const utils::SharedTransaction& transaction, + const Request& request, + const boost::uuids::uuid& user_id) const + { + using enum models::UserType; + switch (request.desired_type().value_or(kUser)) + { + case kAdmin: + user_controller.CreateRequestAdmin( + user_id, request.description().value_or(""), transaction); + return; + case kTeacher: + user_controller.CreateRequestTeacher( + user_id, request.description().value_or(""), transaction); + return; + default: + return; + } + } + Response Handle(Request&& request) const override + { + auto transaction = user_controller.CreateTransaction(); + auto user_id = + user_controller.TryToAdd(request.user_credentials(), transaction); + if (!user_id) + { + return PerformLoginTaken(); } auto id = token_controller.CreateNew( - *user_id, userver::utils::datetime::Now() + std::chrono::hours(24)); - if (!id) { - LOG_WARNING() << fmt::format( - "Failed to create token for user, id: {}", *user_id); - return Response500{}; + *user_id, userver::utils::datetime::Now() + std::chrono::hours(24), + transaction); + if (!id) + { + return PerformFailToken(user_id.value()); } + HandleDesiredType(transaction, request, user_id.value()); Response200 resp; resp.id() = *id; resp.user() = @@ -67,7 +107,8 @@ class Handler final : public http::HandlerParsed(); } diff --git a/src/views/register/view.hpp b/src/views/register/view.hpp index 76049f5d..6f4213d9 100644 --- a/src/views/register/view.hpp +++ b/src/views/register/view.hpp @@ -1,7 +1,7 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::views::register_ { - +namespace timetable_vsu_backend::views::register_ +{ void Append(userver::components::ComponentList& component_list); } diff --git a/src/views/teacher/list/Request.hpp b/src/views/teacher/list/Request.hpp index 2f9e15ce..0941d844 100644 --- a/src/views/teacher/list/Request.hpp +++ b/src/views/teacher/list/Request.hpp @@ -1,16 +1,18 @@ #pragma once #include +#include #include #include "models/teacher_filter/type.hpp" -#include "userver/formats/json/value.hpp" #include "utils/convert/base.hpp" #include "utils/convert/http_request_parse.hpp" #include "utils/convert/json_parse.hpp" #include "utils/parse/uuid/string.hpp" -namespace timetable_vsu_backend::views::teacher::list { +namespace timetable_vsu_backend::views::teacher::list +{ using namespace utils::convert; -struct Request { +struct Request +{ OptionalProperty filter; static constexpr auto kPolicyFields = PolicyFields::ConvertAll; static constexpr TypeOfBody kTypeOfBody = diff --git a/src/views/teacher/list/Responses.hpp b/src/views/teacher/list/Responses.hpp index a4170e32..6c03fc28 100644 --- a/src/views/teacher/list/Responses.hpp +++ b/src/views/teacher/list/Responses.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "http/ErrorV1.hpp" #include "models/admin_account/type.hpp" @@ -8,15 +9,16 @@ #include "models/user/type.hpp" #include "models/user_type/serialize.hpp" #include "models/user_type/type.hpp" -#include "userver/server/http/http_status.hpp" #include "utils/convert/additional_properties.hpp" #include "utils/convert/base.hpp" #include "utils/convert/http_response_serialize.hpp" #include "utils/convert/json_parse.hpp" -namespace timetable_vsu_backend::views::teacher::list { +namespace timetable_vsu_backend::views::teacher::list +{ using namespace utils::convert; -struct Response200 { +struct Response200 +{ ArrayProperty teachers; static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Json; static constexpr PolicyFields kPolicyFields = PolicyFields::ConvertAll; diff --git a/src/views/teacher/list/view.cpp b/src/views/teacher/list/view.cpp index e7f1448a..718bb02c 100644 --- a/src/views/teacher/list/view.cpp +++ b/src/views/teacher/list/view.cpp @@ -17,21 +17,25 @@ #include "models/user/serialize.hpp" #include "models/user_type/serialize.hpp" #include "utils/parse/uuid/string.hpp" -namespace timetable_vsu_backend::views::teacher::list { - -namespace { +namespace timetable_vsu_backend::views::teacher::list +{ +namespace +{ namespace pg = components::controllers::postgres; -class Handler final : public http::HandlerParsed { +class Handler final : public http::HandlerParsed +{ public: [[maybe_unused]] static constexpr std::string_view kName = "handler-teacher-list"; Handler(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context) : HandlerParsed(config, context), - teacher_controller(context.FindComponent()) { + teacher_controller(context.FindComponent()) + { } - Response Handle(Request&& request) const override { + Response Handle(Request&& request) const override + { auto teachers = teacher_controller.GetByFilter(request.filter()); Response200 resp; resp.teachers() = std::move(teachers); @@ -43,7 +47,8 @@ class Handler final : public http::HandlerParsed { }; } // namespace -void Append(userver::components::ComponentList& component_list) { +void Append(userver::components::ComponentList& component_list) +{ component_list.Append(); } diff --git a/src/views/teacher/list/view.hpp b/src/views/teacher/list/view.hpp index 90b4e146..c7b3e11d 100644 --- a/src/views/teacher/list/view.hpp +++ b/src/views/teacher/list/view.hpp @@ -1,7 +1,7 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::views::teacher::list { - +namespace timetable_vsu_backend::views::teacher::list +{ void Append(userver::components::ComponentList& component_list); } diff --git a/src/views/timetable/get/Request.hpp b/src/views/timetable/get/Request.hpp index 0e68e6a2..bb664c88 100644 --- a/src/views/timetable/get/Request.hpp +++ b/src/views/timetable/get/Request.hpp @@ -11,9 +11,11 @@ #include "utils/convert/http_request_parse.hpp" #include "utils/convert/json_parse.hpp" -namespace timetable_vsu_backend::views::timetable::get { +namespace timetable_vsu_backend::views::timetable::get +{ using namespace utils::convert; -struct Request { +struct Request +{ OptionalProperty filter; static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Json; static constexpr PolicyFields kPolicyFields = PolicyFields::ConvertAll; diff --git a/src/views/timetable/get/Responses.hpp b/src/views/timetable/get/Responses.hpp index ff7dd172..423f81e0 100644 --- a/src/views/timetable/get/Responses.hpp +++ b/src/views/timetable/get/Responses.hpp @@ -14,9 +14,11 @@ #include "utils/convert/json_parse.hpp" #include "utils/convert/json_serialize.hpp" -namespace timetable_vsu_backend::views::timetable::get { +namespace timetable_vsu_backend::views::timetable::get +{ using namespace utils::convert; -struct Response200 { +struct Response200 +{ ArrayProperty lessons; static constexpr TypeOfBody kTypeOfBody = TypeOfBody::Json; static constexpr PolicyFields kPolicyFields = PolicyFields::ConvertAll; diff --git a/src/views/timetable/get/view.cpp b/src/views/timetable/get/view.cpp index b4249887..73a40d01 100644 --- a/src/views/timetable/get/view.cpp +++ b/src/views/timetable/get/view.cpp @@ -28,29 +28,33 @@ static_assert(userver::formats::common::impl::kHasSerialize< userver::formats::json::Value, timetable_vsu_backend::models::LessonType>); -namespace timetable_vsu_backend::views::timetable::get { - -namespace { - +namespace timetable_vsu_backend::views::timetable::get +{ +namespace +{ namespace pg = components::controllers::postgres; -class Handler final : public http::HandlerParsed { +class Handler final : public http::HandlerParsed +{ public: static constexpr std::string_view kName = "handler-timetable-get"; Handler(const userver::components::ComponentConfig& config, const userver::components::ComponentContext& context) : HandlerParsed(config, context), - lesson_controller(context.FindComponent()) { + lesson_controller(context.FindComponent()) + { } - static void ValidateBeginEnd(Request& request) { + static void ValidateBeginEnd(Request& request) + { if (request.filter() and request.filter()->begin() and request.filter()->end() && - request.filter()->begin().value() > - request.filter()->end().value()) { + request.filter()->begin().value() > request.filter()->end().value()) + { std::swap(request.filter()->begin().value(), request.filter()->end().value()); } } - Response Handle(Request&& request) const override { + Response Handle(Request&& request) const override + { Response200 resp; ValidateBeginEnd(request); resp.lessons() = lesson_controller.Search(request.filter()); @@ -62,7 +66,8 @@ class Handler final : public http::HandlerParsed { }; } // namespace -void Append(userver::components::ComponentList& component_list) { +void Append(userver::components::ComponentList& component_list) +{ component_list.Append(); } diff --git a/src/views/timetable/get/view.hpp b/src/views/timetable/get/view.hpp index cc37c1f0..3ca7370e 100644 --- a/src/views/timetable/get/view.hpp +++ b/src/views/timetable/get/view.hpp @@ -1,7 +1,7 @@ #pragma once #include "utils/component_list_fwd.hpp" -namespace timetable_vsu_backend::views::timetable::get { - +namespace timetable_vsu_backend::views::timetable::get +{ void Append(userver::components::ComponentList& component_list); } diff --git a/tests/login/conftest.py b/tests/login/conftest.py deleted file mode 100644 index edd5bc71..00000000 --- a/tests/login/conftest.py +++ /dev/null @@ -1,21 +0,0 @@ -import pytest -K_ADD_USER = """ -insert into vsu_timetable."user"(id, login, password) values ('{}', '{}', '{}') -""" - - -@pytest.fixture(name='vsu_timetable_db') -def mock_vsu_timetable_db(pgsql): - class Context: - def __init__(self, pgsql): - pgsql = pgsql - - def add_user(self, user_id, login, password): - assert isinstance(user_id, str) - assert isinstance(login, str) - assert isinstance(password, str) - db = pgsql['db_1'] - cursor = db.cursor() - formated_query = K_ADD_USER.format(user_id, login, password) - cursor.execute(formated_query) - return Context(pgsql) diff --git a/tests/register/conftest.py b/tests/register/conftest.py new file mode 100644 index 00000000..e1fed62d --- /dev/null +++ b/tests/register/conftest.py @@ -0,0 +1,57 @@ +import pytest +K_GET_USER_BY_ID = """ +SELECT * from timetable_vsu."user" WHERE id = '{}' +""" + +K_GET_TOKEN_BY_ID_USER = """ +SELECT * from timetable_vsu."token" WHERE id_user = '{}'::uuid +""" + +K_GET_USER_BY_LOGIN = """ +SELECT * from timetable_vsu."user" WHERE login = '{}' +""" + +K_GET_ALL_TABLE = """ +SELECT * from {} +""" + + +@pytest.fixture(name='vsu_timetable_db') +def mock_vsu_timetable_db(pgsql): + class Context: + def __init__(self, pgsql): + pgsql = pgsql + + def get_all_from_table(self, table): + assert isinstance(table, str) + db = pgsql['db_1'] + cursor = db.cursor() + formated_query = K_GET_ALL_TABLE.format(table) + cursor.execute(formated_query) + return cursor.fetchall() + + def get_user_by_id(self, user_id): + assert isinstance(user_id, str) + db = pgsql['db_1'] + cursor = db.cursor() + formated_query = K_GET_USER_BY_ID.format(user_id) + cursor.execute(formated_query) + return cursor.fetchall() + + def get_user_by_login(self, user_login): + assert isinstance(user_login, str) + db = pgsql['db_1'] + cursor = db.cursor() + formated_query = K_GET_USER_BY_LOGIN.format(user_login) + cursor.execute(formated_query) + return cursor.fetchall() + + def get_token_by_id_user(self, id_user): + assert isinstance(id_user, str) + db = pgsql['db_1'] + cursor = db.cursor() + formated_query = K_GET_TOKEN_BY_ID_USER.format(id_user) + cursor.execute(formated_query) + return cursor.fetchall() + + return Context(pgsql) diff --git a/tests/register/test_register.py b/tests/register/test_register.py new file mode 100644 index 00000000..23ff49e3 --- /dev/null +++ b/tests/register/test_register.py @@ -0,0 +1,62 @@ +import pytest + +from testsuite.databases import pgsql + + +def _perform_request(login, password, type, description): + return { + 'user_credentials': { + 'login': login, + 'password': password + }, + 'desired_type': type, + 'description': description + } + + +def _assert_database(vsu_timetable_db, login, password, + description, table_requests, token): + users = vsu_timetable_db.get_user_by_login(login) + assert len(users) == 1 + (user_id, user_login, user_password) = users[0] + assert user_login == login + assert user_password == password + if table_requests is not None: + requests = vsu_timetable_db.get_all_from_table(table_requests) + assert len(requests) == 1 + (request_id, request_id_user, request_description) = requests[0] + assert user_id == request_id_user + assert description == request_description + tokens = vsu_timetable_db.get_token_by_id_user(user_id) + assert len(tokens) == 1 + (token_id, expire_time, token_id_user) = tokens[0] + assert token_id == token + + +def _assert_ok_response(response, type, user_id=None, token=None): + assert response.status_code == 200 + assert 'token' in response.json() + if token is not None: + assert response.json()['token'] == token + assert isinstance(response.json()['user'], dict) + assert 'id' in response.json()['user'] + if user_id is not None: + assert response.json()['user']['id'] == user_id + assert response.json()['user']['type'] == type + + +@pytest.mark.parametrize( + 'type, table_requests', + [('user', None), + ('teacher', 'timetable_vsu.teacher_requests'), + ('admin', 'timetable_vsu.admin_requests')], +) +async def test_register_successful(service_client, + vsu_timetable_db, type, table_requests): + request = _perform_request( + 'some_user', 'some_password', type, 'description') + response = await service_client.post('/register', + json=request) + _assert_ok_response(response, 'user') + _assert_database(vsu_timetable_db, 'some_user', 'some_password', + 'description', table_requests, response.json()['token']) diff --git a/united_api.yaml b/united_api.yaml index 4a9ccf8b..95adf068 100644 --- a/united_api.yaml +++ b/united_api.yaml @@ -196,10 +196,16 @@ components: $ref: '#/components/schemas/TypesUserV1' ViewsRegisterRequestV1: properties: + description: + description: Дополнительная информация для администраторов при регистрации + (в рамках запроса привиллегий преподавателя или администратора) + type: string + desired_type: + $ref: '#/components/schemas/TypesUserTypeV1' user_credential: $ref: '#/components/schemas/TypesUserCredentialV1' - user_type: - $ref: '#/components/schemas/TypesUserTypeV1' + required: + - user_credential ViewsTimetableGetRequest: properties: begin: diff --git a/utests/convert_test.cpp b/utests/convert_test.cpp index feab6bd4..1ea675e4 100644 --- a/utests/convert_test.cpp +++ b/utests/convert_test.cpp @@ -14,14 +14,16 @@ #include "utils/convert/json_serialize.hpp" namespace magic = timetable_vsu_backend::utils::convert; -struct TestStruct { +struct TestStruct +{ static constexpr auto kPolicyFields = magic::PolicyFields::ConvertAll; magic::Property Login; magic::Property Password; }; static_assert(magic::IsProperty); -UTEST(TestConvert, BasicJsonToStruct) { +UTEST(TestConvert, BasicJsonToStruct) +{ static_assert(magic::IsConvertAll); static_assert( userver::formats::common::impl::kHasParse); static_assert(userver::formats::common::impl::kHasSerialize< userver::formats::json::Value, TestStruct>); diff --git a/utests/dropper.cpp b/utests/dropper.cpp index 5333828c..8326228e 100644 --- a/utests/dropper.cpp +++ b/utests/dropper.cpp @@ -7,14 +7,17 @@ #include "utils/convert/drop_properties_ref.hpp" namespace magic = timetable_vsu_backend::utils::convert; -namespace { -struct TestStruct { +namespace +{ +struct TestStruct +{ static constexpr auto kPolicyFields = magic::PolicyFields::ConvertAll; magic::Property Login; magic::Property Password; }; -struct TestStruct2 { +struct TestStruct2 +{ static constexpr auto kPolicyFields = magic::PolicyFields::ConvertAll; magic::Property auth; magic::Property description; @@ -22,7 +25,8 @@ struct TestStruct2 { } // namespace -UTEST(TestDropProperties, Recursive) { +UTEST(TestDropProperties, Recursive) +{ TestStruct2 test; test.auth().Login() = "1232"; test.auth().Password() = "adad"; @@ -48,7 +52,8 @@ UTEST(TestDropProperties, Recursive) { UASSERT(&std::get<1>(tuple) == &test.description()); } -UTEST(TestDropProperties, Basic) { +UTEST(TestDropProperties, Basic) +{ TestStruct test; test.Login() = "1232"; test.Password() = "adad"; @@ -61,7 +66,8 @@ UTEST(TestDropProperties, Basic) { UASSERT(&std::get<1>(tuple) == &test.Password()); } -UTEST(TestDropProperties, ConstBasic) { +UTEST(TestDropProperties, ConstBasic) +{ TestStruct test; test.Login() = "1232"; test.Password() = "adad"; @@ -76,7 +82,8 @@ UTEST(TestDropProperties, ConstBasic) { UASSERT(&std::get<1>(tuple) == &test.Password()); } -UTEST(TestDropProperties, ConstRecursive) { +UTEST(TestDropProperties, ConstRecursive) +{ TestStruct2 test; test.auth().Login() = "1232"; test.auth().Password() = "adad"; diff --git a/utests/dropper_additional.cpp b/utests/dropper_additional.cpp index 8586065a..721b78f5 100644 --- a/utests/dropper_additional.cpp +++ b/utests/dropper_additional.cpp @@ -8,27 +8,32 @@ #include "utils/convert/drop_properties_ref.hpp" using namespace timetable_vsu_backend::utils::convert; -namespace { -struct TestStruct { +namespace +{ +struct TestStruct +{ static constexpr auto kPolicyFields = PolicyFields::ConvertAll; Property login; Property password; }; -struct TestStruct2 { +struct TestStruct2 +{ static constexpr auto kPolicyFields = PolicyFields::ConvertAll; Property descriptor; Property money; }; -struct TestStruct3 { +struct TestStruct3 +{ static constexpr auto kPolicyFields = PolicyFields::ConvertAll; OptionalProperty auth; OptionalProperty description; }; } // namespace -UTEST(TestDropAdditionalProperties, Recursive) { +UTEST(TestDropAdditionalProperties, Recursive) +{ TestStruct3 test; test.description() = {TestStruct2{.descriptor = {42}, .money = {43}}}; auto tuple = DropPropertiesToMutRefs(test); diff --git a/utests/hello_test.cpp b/utests/hello_test.cpp index 14aeeae7..8bc3898c 100644 --- a/utests/hello_test.cpp +++ b/utests/hello_test.cpp @@ -3,7 +3,8 @@ #include "views/hello/view.hpp" -UTEST(SayHelloTo, Basic) { +UTEST(SayHelloTo, Basic) +{ EXPECT_EQ(service_template::SayHelloTo("Developer", service_template::UserType::kKnown), "Hi again, Developer!\n"); diff --git a/vsu_timetable.code-workspace b/vsu_timetable.code-workspace index af0a1a58..dd7bcdb3 100644 --- a/vsu_timetable.code-workspace +++ b/vsu_timetable.code-workspace @@ -2,7 +2,7 @@ "folders": [ { "path": ".", - "name" : "vsu_timetable" + "name" : "timetable_vsu_backend" }, ], "extensions":{