From c18a35716df7b49c9b91d3b766c80cf18adaae67 Mon Sep 17 00:00:00 2001 From: sabudilovskiy Date: Thu, 26 Oct 2023 13:37:10 +0000 Subject: [PATCH] - --- .gen/objs.txt | 9 ++- configs/static_config.yaml.in | 6 ++ service/main.cpp | 19 ++++- src/controllers/lesson/controller.cpp | 24 ++++-- src/controllers/lesson/controller.hpp | 8 +- src/legacy/models/substring/doc.hpp | 13 ++++ src/models/lesson_filter/postgres.hpp | 16 ++++ src/models/lesson_filter/type.hpp | 61 +++++++++++++++ src/models/lesson_v1/postgres.hpp | 14 ---- src/models/lesson_v1/type.hpp | 37 +++++---- src/openapi/base/properties/datetime.hpp | 61 +++++++++++++++ src/openapi/base/properties/optional.hpp | 57 ++++++++++++++ src/openapi/base/property_base.hpp | 2 +- src/openapi/doc/array.hpp | 11 +++ src/openapi/doc/base.hpp | 6 ++ src/openapi/doc/int.hpp | 20 ++++- src/openapi/doc/optional.hpp | 1 + src/openapi/doc/reflective.hpp | 2 +- src/openapi/postgres/mapping.hpp | 78 ++++++++++++------- src/openapi/types/all.hpp | 1 + src/openapi/types/field.hpp | 9 +++ src/utils/constexpr_string.hpp | 1 + src/utils/initialize_dependents.hpp | 40 ++++++++++ src/views/timetable/declarations.hpp | 49 ++++++++++++ src/views/timetable/view.cpp | 93 +++++++++++++++++++++++ src/views/timetable/view.hpp | 7 ++ tests/timetable/get/timetable_get_data.py | 4 +- 27 files changed, 573 insertions(+), 76 deletions(-) create mode 100644 src/legacy/models/substring/doc.hpp create mode 100644 src/models/lesson_filter/postgres.hpp create mode 100644 src/models/lesson_filter/type.hpp delete mode 100644 src/models/lesson_v1/postgres.hpp create mode 100644 src/openapi/types/field.hpp create mode 100644 src/utils/initialize_dependents.hpp create mode 100644 src/views/timetable/declarations.hpp create mode 100644 src/views/timetable/view.cpp create mode 100644 src/views/timetable/view.hpp diff --git a/.gen/objs.txt b/.gen/objs.txt index 4b918fd8..9e392b7f 100644 --- a/.gen/objs.txt +++ b/.gen/objs.txt @@ -1,3 +1,6 @@ +src/views/timetable/view.hpp +src/views/timetable/view.cpp +src/views/timetable/declarations.hpp src/views/register/view.hpp src/views/register/view.cpp src/views/register/declarations.hpp @@ -19,6 +22,7 @@ src/utils/meta.hpp src/utils/json_type.hpp src/utils/json_type.cpp src/utils/is_complete_type.hpp +src/utils/initialize_dependents.hpp src/utils/formated_exception.hpp src/utils/convert/json_serialize.hpp src/utils/convert/json_parse.hpp @@ -44,6 +48,7 @@ src/openapi/types/uuid.hpp src/openapi/types/string.hpp src/openapi/types/optional.hpp src/openapi/types/object.hpp +src/openapi/types/field.hpp src/openapi/types/datetime.hpp src/openapi/types/array.hpp src/openapi/types/all.hpp @@ -162,7 +167,8 @@ src/models/user_credentials/postgres.hpp src/models/user/type.hpp src/models/user/postgres.hpp src/models/lesson_v1/type.hpp -src/models/lesson_v1/postgres.hpp +src/models/lesson_filter/type.hpp +src/models/lesson_filter/postgres.hpp src/models/error_v1/type.hpp src/legacy/views/timetable/get/view.hpp src/legacy/views/timetable/get/view.cpp @@ -241,6 +247,7 @@ src/legacy/models/substring/postgre.hpp src/legacy/models/substring/parse.hpp src/legacy/models/substring/parse.cpp src/legacy/models/substring/fwd.hpp +src/legacy/models/substring/doc.hpp src/legacy/models/substring/all.hpp src/legacy/models/subgroup/type.hpp src/legacy/models/subgroup/postgre.hpp diff --git a/configs/static_config.yaml.in b/configs/static_config.yaml.in index 7c58afc8..3d628cc4 100644 --- a/configs/static_config.yaml.in +++ b/configs/static_config.yaml.in @@ -54,6 +54,7 @@ components_manager: method: POST task_processor: main-task-processor handler-timetable-get: + load-enabled: false path: /timetable/get method: POST task_processor: main-task-processor @@ -137,6 +138,11 @@ components_manager: id: $root_id lesson_details_controller : {} teacher_controller : {} + new-lesson-controller: {} + timetable-view: + path: /timetable/get + method: POST + task_processor: main-task-processor handler-ping: path: /ping method: GET diff --git a/service/main.cpp b/service/main.cpp index 44d2794d..7da97994 100644 --- a/service/main.cpp +++ b/service/main.cpp @@ -12,6 +12,7 @@ #include #include +#include "controllers/lesson/controller_fwd.hpp" #include "controllers/token/controller_fwd.hpp" #include "controllers/user/controller.hpp" #include "controllers/user/controller_fwd.hpp" @@ -35,8 +36,10 @@ #include "legacy/views/timetable/get/view.hpp" #include "views/login/view.hpp" #include "views/register/view.hpp" +#include "views/timetable/view.hpp" -void AppendPgControllers(userver::components::ComponentList& component_list) +void AppendLegacyPgControllers( + userver::components::ComponentList& component_list) { using namespace legacy::components::controllers::postgres; user::Append(component_list); @@ -46,8 +49,6 @@ void AppendPgControllers(userver::components::ComponentList& component_list) teacher::Append(component_list); faculty::Append(component_list); group_stage::Append(component_list); - controllers::token::Append(component_list); - controllers::user::Append(component_list); } void AppendLegacyViews(userver::components::ComponentList& component_list) @@ -70,6 +71,15 @@ void AppendViews(userver::components::ComponentList& component_list) using namespace views; login::Append(component_list); Register::Append(component_list); + timetable::Append(component_list); +} + +void AppendControllers(userver::components::ComponentList& component_list) +{ + using namespace controllers; + token::Append(component_list); + user::Append(component_list); + lesson::Append(component_list); } int main(int argc, char* argv[]) @@ -84,7 +94,8 @@ int main(int argc, char* argv[]) .Append(); openapi::http::AppendOpenApiDescriptor(component_list); service_template::AppendHello(component_list); - AppendPgControllers(component_list); + AppendLegacyPgControllers(component_list); + AppendControllers(component_list); AppendLegacyViews(component_list); AppendViews(component_list); return userver::utils::DaemonMain(argc, argv, component_list); diff --git a/src/controllers/lesson/controller.cpp b/src/controllers/lesson/controller.cpp index f469b859..9665f1c3 100644 --- a/src/controllers/lesson/controller.cpp +++ b/src/controllers/lesson/controller.cpp @@ -3,17 +3,29 @@ #include #include #include +#include +#include #include #include #include #include #include #include +#include +#include +#include +#include +#include #include #include #include #include "controller_fwd.hpp" +#include "legacy/models/day/postgre.hpp" +#include "legacy/models/education_type/postgre.hpp" +#include "legacy/models/lesson_type/postgre.hpp" +#include "legacy/models/lesson_week_type/postgre.hpp" +#include "legacy/models/subgroup/postgre.hpp" #include "models/user_credentials/postgres.hpp" namespace controllers::lesson @@ -27,14 +39,12 @@ Controller::Controller(const userver::components::ComponentConfig& cfg, : Base(cfg, ctx) { } -boost::uuids::uuid Controller::CreateNew( - const boost::uuids::uuid& id_user, +std::vector Controller::FindLessons( + const std::optional& filter, utils::SharedTransaction transaction) const { - utils::FillSharedTransaction(transaction, pg_cluster_); - auto pg_result = transaction->transaction_.Execute( - sql::add_token_to_user, id_user, - userver::utils::datetime::Now() + std::chrono::hours(24)); - return pg_result.AsSingleRow(); + FillTransaction(transaction); + return transaction->Execute_R>( + sql::get_lessons_by_filter, filter); } } // namespace controllers::lesson diff --git a/src/controllers/lesson/controller.hpp b/src/controllers/lesson/controller.hpp index e378e573..821dbc9b 100644 --- a/src/controllers/lesson/controller.hpp +++ b/src/controllers/lesson/controller.hpp @@ -1,11 +1,13 @@ #pragma once -#include #include #include #include #include +#include "models/lesson_filter/type.hpp" +#include "models/lesson_v1/type.hpp" + namespace controllers::lesson { using Base = utils::PgController<"new-lesson-controller", "postgres-db-1">; @@ -13,8 +15,8 @@ struct Controller : Base { Controller(const userver::components::ComponentConfig& cfg, const userver::components::ComponentContext& ctx); - boost::uuids::uuid CreateNew( - const boost::uuids::uuid& id_user, + std::vector FindLessons( + const std::optional& filter, utils::SharedTransaction transaction = nullptr) const; }; } // namespace controllers::lesson diff --git a/src/legacy/models/substring/doc.hpp b/src/legacy/models/substring/doc.hpp new file mode 100644 index 00000000..aac8ac00 --- /dev/null +++ b/src/legacy/models/substring/doc.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include +#include +#include +namespace openapi +{ +inline void Append(DocHelper doc_helper, + std::type_identity) +{ + doc_helper.cur_place["type"] = "string"; +} +} // namespace openapi diff --git a/src/models/lesson_filter/postgres.hpp b/src/models/lesson_filter/postgres.hpp new file mode 100644 index 00000000..797c479d --- /dev/null +++ b/src/models/lesson_filter/postgres.hpp @@ -0,0 +1,16 @@ +#pragma once +#include +#include + +#include "type.hpp" + +namespace userver::storages::postgres::io +{ +template <> +struct CppToUserPg<::models::LessonFilter> +{ + static constexpr DBTypeName postgres_name = + "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 new file mode 100644 index 00000000..23ac88de --- /dev/null +++ b/src/models/lesson_filter/type.hpp @@ -0,0 +1,61 @@ +#pragma once +#include +#include +#include +#include +#include + +#include "legacy/models/day/type.hpp" +#include "legacy/models/education_type/type.hpp" +#include "legacy/models/lesson_type/type.hpp" +#include "legacy/models/lesson_week_type/type.hpp" +#include "legacy/models/subgroup/type.hpp" +#include "legacy/models/substring/type.hpp" + +namespace models +{ +using namespace openapi::types; +using namespace openapi::preferences; + +struct LessonFilter +{ + Optional, Name<"lesson_ids">> + lesson_ids; + Optional, Name<"begin">> begin; + Optional, Name<"end">> end; + Optional, Name<"days">> days; + Optional, Name<"department_ids">> + department_ids; + Optional, Name<"department_names">> + department_names; + Optional, Name<"faculty_ids">> + faculty_ids; + Optional, Name<"faculty_names">> + faculty_names; + Optional, Name<"group_ids">> + group_ids; + Optional, Name<"group_names">> + group_names; + Optional, Name<"group_courses">> group_courses; + Optional, Name<"group_types">> + group_types; + Optional, Name<"room_ids">> room_ids; + Optional, Name<"room_names">> + room_names; + Optional> subgroup; + Optional, Name<"subject_ids">> + subject_ids; + Optional, Name<"subject_names">> + subject_names; + Optional, Name<"teacher_ids">> + teacher_ids; + Optional, Name<"teacher_fios">> + teacher_fios; + Optional, Name<"teacher_bios">> + teacher_bios; + Optional> week; + Optional> type; + Optional, Name<"numbers">> numbers; + auto operator<=>(const LessonFilter&) const = default; +}; +} // namespace models diff --git a/src/models/lesson_v1/postgres.hpp b/src/models/lesson_v1/postgres.hpp deleted file mode 100644 index a9369bb5..00000000 --- a/src/models/lesson_v1/postgres.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include - -#include "type.hpp" -namespace userver::storages::postgres::io -{ -template <> -struct CppToUserPg -{ - static constexpr DBTypeName postgres_name = "timetable_vsu.user"; -}; - -} // namespace userver::storages::postgres::io diff --git a/src/models/lesson_v1/type.hpp b/src/models/lesson_v1/type.hpp index 41521d6c..7619d15f 100644 --- a/src/models/lesson_v1/type.hpp +++ b/src/models/lesson_v1/type.hpp @@ -1,8 +1,15 @@ #pragma once #include +#include +#include #include #include +#include "legacy/models/day/type.hpp" +#include "legacy/models/education_type/type.hpp" +#include "legacy/models/lesson_type/type.hpp" +#include "legacy/models/lesson_week_type/type.hpp" +#include "legacy/models/subgroup/type.hpp" #include "legacy/models/user_type/type.hpp" namespace models @@ -12,31 +19,29 @@ using namespace openapi::preferences; struct LessonV1 { Uuid> lesson_id; - convert::Property lesson_begin; - convert::Property lesson_end; - convert::Property lesson_number; - convert::Property lesson_type; - convert::Property lesson_week_type; - convert::Property lesson_subgroup; - convert::Property lesson_day; + Datetime> lesson_begin; + Datetime> lesson_end; + Field> lesson_number; + Field> lesson_type; + Field> lesson_week_type; + Field> lesson_subgroup; + Field> lesson_day; Uuid> room_id; String> room_name; Uuid> subject_id; - String < Name<"subject_name"> subject_name; + String> subject_name; Uuid> group_id; - convert::Property group_stage_course; - String < Name<"group_name"> group_name; - convert::Property group_type; + Field> group_stage_course; + String> group_name; + Field> group_type; Uuid> faculty_id; - String < Name<"faculty_name"> faculty_name; + String> faculty_name; Uuid> department_id; - String < Name<"department_name"> department_name; + String> department_name; Uuid> teacher_id; String> teacher_fio; String> teacher_bio; - static constexpr utils::convert::PolicyFields kPolicyFields = - utils::convert::PolicyFields::ConvertAll; -}; + auto operator<=>(const LessonV1&) const = default; }; } // namespace models diff --git a/src/openapi/base/properties/datetime.hpp b/src/openapi/base/properties/datetime.hpp index c1a166c8..725904e8 100644 --- a/src/openapi/base/properties/datetime.hpp +++ b/src/openapi/base/properties/datetime.hpp @@ -6,6 +6,67 @@ namespace openapi { +template +struct PropertyBase +{ + using T = userver::storages::postgres::TimePointTz; + using value_type = T; + using traits = Traits; + + template + PropertyBase(Args&&... args) noexcept( + std::is_nothrow_constructible_v) + : value(std::forward(args)...) + { + } + + template + PropertyBase(std::initializer_list init_list) noexcept( + std::is_nothrow_constructible_v>) + : value(std::move(init_list)) + { + } + + auto operator<=>(const PropertyBase& r) const + { + return *this <=> r.value; + } + auto operator<=>(const value_type& r) const + { + return value.GetUnderlying() <=> r.GetUnderlying(); + } + + bool operator==(const PropertyBase& r) const + { + return value.GetUnderlying() == r.value.GetUnderlying(); + } + bool operator==(const value_type& r) const + { + return value.GetUnderlying() == r.GetUnderlying(); + } + + template + auto& operator=(Arg&& arg) + { + value = std::forward(arg); + return value; + } + auto& operator=(value_type rhs) + { + value = std::move(rhs); + return *this; + } + value_type& operator()() noexcept + { + return value; + } + const value_type& operator()() const noexcept + { + return value; + } + value_type value; +}; + template struct DateTimeProperty : PropertyBase diff --git a/src/openapi/base/properties/optional.hpp b/src/openapi/base/properties/optional.hpp index 76eb2e3c..8dbaf013 100644 --- a/src/openapi/base/properties/optional.hpp +++ b/src/openapi/base/properties/optional.hpp @@ -1,9 +1,66 @@ #pragma once +#include #include #include namespace openapi { +template +struct PropertyBase, Traits> +{ + using value_type = std::optional; + using traits = Traits; + + template + PropertyBase(Args&&... args) noexcept( + std::is_nothrow_constructible_v) + : value(std::forward(args)...) + { + } + + template + PropertyBase(std::initializer_list init_list) noexcept( + std::is_nothrow_constructible_v>) + : value(std::move(init_list)) + { + } + + auto operator<=>(const PropertyBase& r) const + { + return *this <=> r.value; + } + std::partial_ordering operator<=>(const value_type& r) const + { + if (value.has_value() && r.has_value()) + { + return value.value() <=> r.value(); + } + else + return std::partial_ordering::unordered; + } + + template + auto& operator=(Arg&& arg) + { + value = std::forward(arg); + return value; + } + auto& operator=(value_type rhs) + { + value = std::move(rhs); + return *this; + } + value_type& operator()() noexcept + { + return value; + } + const value_type& operator()() const noexcept + { + return value; + } + value_type value; +}; + template struct OptionalProperty : public PropertyBase, Traits> { diff --git a/src/openapi/base/property_base.hpp b/src/openapi/base/property_base.hpp index 0eb72742..e7cd87f6 100644 --- a/src/openapi/base/property_base.hpp +++ b/src/openapi/base/property_base.hpp @@ -26,7 +26,7 @@ struct PropertyBase template PropertyBase(std::initializer_list init_list) noexcept( - std::is_nothrow_constructible_v>) + std::is_nothrow_constructible_v>) : value(std::move(init_list)) { } diff --git a/src/openapi/doc/array.hpp b/src/openapi/doc/array.hpp index 011a1e2a..7f9f1422 100644 --- a/src/openapi/doc/array.hpp +++ b/src/openapi/doc/array.hpp @@ -27,4 +27,15 @@ void Append(DocHelper doc_helper, auto items_node = field_node["items"]; Append(DocHelper{doc_helper.root, items_node}, std::type_identity{}); } + +template +void Append(DocHelper doc_helper, std::type_identity>) +{ + auto& field_node = doc_helper.cur_place; + if (!field_node.IsObject()) + field_node = userver::formats::common::Type::kObject; + field_node["type"] = "array"; + auto items_node = field_node["items"]; + Append(DocHelper{doc_helper.root, items_node}, std::type_identity{}); +} } // namespace openapi diff --git a/src/openapi/doc/base.hpp b/src/openapi/doc/base.hpp index 78bfccee..c0cfd094 100644 --- a/src/openapi/doc/base.hpp +++ b/src/openapi/doc/base.hpp @@ -132,4 +132,10 @@ inline void log_dock_helper_impl(DocHelper doc_helper, std::clog << ToString(root.ExtractValue()) << '\n'; } +template +concept HasAppend = requires(DocHelper doc_helper, std::type_identity t) +{ + Append(doc_helper, t); +}; + } // namespace openapi diff --git a/src/openapi/doc/int.hpp b/src/openapi/doc/int.hpp index 60461133..6226b7d6 100644 --- a/src/openapi/doc/int.hpp +++ b/src/openapi/doc/int.hpp @@ -1,9 +1,13 @@ #pragma once +#include +#include #include +#include namespace openapi { -inline void Append(DocHelper doc_helper, std::type_identity) +inline void Append( + DocHelper doc_helper, std::type_identity) { auto& cur = doc_helper.cur_place; if (cur.IsObject()) @@ -13,4 +17,18 @@ inline void Append(DocHelper doc_helper, std::type_identity) cur["type"] = "integer"; cur["format"] = "int32"; } + +template +requires std::is_integral_v inline void Append( + DocHelper doc_helper, std::type_identity) +{ + auto& cur = doc_helper.cur_place; + if (cur.IsObject()) + { + cur = userver::formats::yaml::Type::kObject; + } + cur["type"] = "integer"; + cur["minimum"] = std::numeric_limits::min(); + cur["maximum"] = std::numeric_limits::max(); +} } // namespace openapi diff --git a/src/openapi/doc/optional.hpp b/src/openapi/doc/optional.hpp index ece089e8..110d5d2e 100644 --- a/src/openapi/doc/optional.hpp +++ b/src/openapi/doc/optional.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include namespace openapi diff --git a/src/openapi/doc/reflective.hpp b/src/openapi/doc/reflective.hpp index 4e044b2d..cec0361e 100644 --- a/src/openapi/doc/reflective.hpp +++ b/src/openapi/doc/reflective.hpp @@ -8,7 +8,7 @@ namespace openapi { template -void AppendField(DocHelper doc_helper, std::type_identity type = {}) +void AppendField(DocHelper doc_helper, std::type_identity type) { using Traits = typename T::traits; constexpr auto name_ce = traits::GetName(); diff --git a/src/openapi/postgres/mapping.hpp b/src/openapi/postgres/mapping.hpp index 9b087aa8..0ddc753f 100644 --- a/src/openapi/postgres/mapping.hpp +++ b/src/openapi/postgres/mapping.hpp @@ -5,26 +5,28 @@ #include #include #include +#include #include +#include +#include #include namespace openapi { template -concept IsPgUserProperty = IsProperty&& utils::is_complete_type< - userver::storages::postgres::io::CppToUserPg>; +concept IsPgProperty = + IsProperty&& userver::storages::postgres::io::traits::kIsMappedToPg< + typename T::value_type>; -template -concept IsPgSystemProperty = IsProperty&& utils::is_complete_type< - userver::storages::postgres::io::CppToSystemPg>; } // namespace openapi namespace userver::storages::postgres::io { namespace detail { -template -struct OpenapiPropertyFormatter : BufferFormatterBase +template +requires openapi::IsProperty struct OpenapiPropertyFormatter + : BufferFormatterBase { using Inner = typename T::value_type; using BaseType = BufferFormatterBase; @@ -39,8 +41,9 @@ struct OpenapiPropertyFormatter : BufferFormatterBase } }; -template -struct OpenapiPropertyParser : BufferParserBase +template +requires openapi::IsProperty struct OpenapiPropertyParser + : BufferParserBase { using BaseType = BufferParserBase; using Inner = typename T::value_type; @@ -60,9 +63,9 @@ struct OpenapiPropertyParser : BufferParserBase /* Formatter specialization for openapi::Property */ -template -struct BufferFormatter< - T, std::enable_if_t>> +template +requires openapi::IsProperty&& + traits::kHasFormatter struct BufferFormatter : detail::OpenapiPropertyFormatter { using BaseType = detail::OpenapiPropertyFormatter; @@ -72,9 +75,9 @@ struct BufferFormatter< /* Parser specialization for openapi::Property */ -template -struct BufferParser< - T, std::enable_if_t>> +template +requires openapi::IsProperty&& + traits::kHasParser struct BufferParser : detail::OpenapiPropertyParser { using BaseType = detail::OpenapiPropertyParser; @@ -82,24 +85,47 @@ struct BufferParser< }; template -requires openapi::IsPgUserProperty struct CppToUserPg +requires openapi::IsProperty&& + traits::kIsNullable struct traits::IsNullable + : traits::IsNullable { - private: - using Inner = typename T::value_type; +}; - public: - static constexpr DBTypeName postgres_name = - CppToUserPg::postgres_name; +template +requires openapi::IsProperty&& + traits::kIsNullable struct traits::GetSetNull +{ + using inner_get_set = traits::GetSetNull; + inline static bool IsNull(const T& v) + { + return inner_get_set::IsNull(v()); + } + inline static void SetNull(T& v) + { + inner_get_set::SetNull(v()); + } + inline static void SetDefault(T& v) + { + inner_get_set::SetDefault(v()); + } }; template -requires openapi::IsPgSystemProperty struct CppToSystemPg +requires openapi::IsPgProperty struct CppToPg + : CppToPg { - private: - using Inner = typename T::value_type; +}; - public: - static constexpr auto value = CppToSystemPg::value; +template +requires openapi::IsPgProperty struct traits::IsMappedToPg + : traits::IsMappedToPg +{ +}; + +template +requires openapi::IsPgProperty struct traits::IsSpecialMapping + : traits::IsMappedToPg +{ }; } // namespace userver::storages::postgres::io diff --git a/src/openapi/types/all.hpp b/src/openapi/types/all.hpp index 379a75d6..52c5c703 100644 --- a/src/openapi/types/all.hpp +++ b/src/openapi/types/all.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include #include #include diff --git a/src/openapi/types/field.hpp b/src/openapi/types/field.hpp new file mode 100644 index 00000000..5bd1590b --- /dev/null +++ b/src/openapi/types/field.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include +#include +namespace openapi::types +{ +template +using Field = Property>; +} diff --git a/src/utils/constexpr_string.hpp b/src/utils/constexpr_string.hpp index a401cf46..858cf378 100644 --- a/src/utils/constexpr_string.hpp +++ b/src/utils/constexpr_string.hpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace utils { diff --git a/src/utils/initialize_dependents.hpp b/src/utils/initialize_dependents.hpp new file mode 100644 index 00000000..4bd8e5d3 --- /dev/null +++ b/src/utils/initialize_dependents.hpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include +#include +#include + +namespace utils +{ +namespace details +{ +template +decltype(auto) initialize_field( + const userver::components::ComponentContext& ctx) +{ + using FieldType = boost::pfr::tuple_element_t; + if constexpr (std::is_pointer_v) + { + return ctx.FindComponentOptional>(); + } + else + { + return ctx.FindComponent>(); + } +} +template +T initialize_dependends(const userver::components::ComponentContext& ctx, + std::integer_sequence) +{ + return T{initialize_field(ctx)...}; +} +} // namespace details +template +T initialize_dependends(const userver::components::ComponentContext& ctx) +{ + constexpr size_t N = boost::pfr::tuple_size_v; + auto seq = std::make_index_sequence{}; + return details::initialize_dependends(ctx, seq); +} +} // namespace utils diff --git a/src/views/timetable/declarations.hpp b/src/views/timetable/declarations.hpp new file mode 100644 index 00000000..b886b0e4 --- /dev/null +++ b/src/views/timetable/declarations.hpp @@ -0,0 +1,49 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include + +#include "legacy/models/substring/doc.hpp" +#include "legacy/models/substring/parse.hpp" +#include "legacy/models/substring/serialize.hpp" +#include "legacy/models/substring/type.hpp" +#include "legacy/models/user_type/postgre.hpp" +#include "models/lesson_filter/type.hpp" +#include "models/lesson_v1/type.hpp" +#include "models/user/type.hpp" +#include "models/user_credentials/type.hpp" + +using namespace openapi::types; +using namespace openapi::http; +using namespace openapi::preferences; +namespace views::timetable +{ +struct RequestBody +{ + Optional> filter; + auto operator<=>(const RequestBody&) const = default; +}; + +struct Request +{ + Body body; + auto operator<=>(const Request&) const = default; +}; + +struct ResponseBody +{ + Array> lessons; + auto operator<=>(const ResponseBody&) const = default; +}; + +struct Response +{ + Body body; + auto operator<=>(const Response&) const = default; +}; + +} // namespace views::timetable diff --git a/src/views/timetable/view.cpp b/src/views/timetable/view.cpp new file mode 100644 index 00000000..e9e9dfa6 --- /dev/null +++ b/src/views/timetable/view.cpp @@ -0,0 +1,93 @@ +#include "view.hpp" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "controllers/lesson/controller.hpp" +#include "controllers/token/controller.hpp" +#include "controllers/user/controller.hpp" +#include "declarations.hpp" + +namespace views::timetable +{ +namespace +{ +using Resp200 = Resp; +using Base = openapi::http::OpenApiHandler<"timetable-view", Request, Resp200>; + +struct Dependends +{ + controllers::lesson::Controller& lesson_controller; +}; +struct View final : Base +{ + View(const userver::components::ComponentConfig& cfg, + const userver::components::ComponentContext& ctx) + : Base(cfg, ctx), + dependends_(utils::initialize_dependends(ctx)) + { + } + static void LogLessondIds(const RequestBody& body) + { + if (!body.filter().has_value()) + { + LOG_DEBUG() << "lesson_ids : null"; + return; + } + if (!body.filter()->lesson_ids().has_value()) + { + LOG_DEBUG() << "lesson_ids : null"; + return; + } + if (body.filter()->lesson_ids().value().empty()) + { + LOG_DEBUG() << "lesson_ids : []"; + return; + } + std::string log_str = "["; + log_str.append( + body.filter()->lesson_ids().value().front().GetUnderlying()); + for (auto it = body.filter()->lesson_ids().value().begin() + 1, + end = body.filter()->lesson_ids().value().end(); + it != end; it++) + { + log_str.append(it->GetUnderlying()); + } + log_str.append("]"); + LOG_DEBUG() << log_str; + } + Resps Handle(Request&& req) const override + { + auto& filter = req.body().filter(); + LOG_DEBUG() << "parsed: " + << ToString(userver::formats::json::ValueBuilder(filter) + .ExtractValue()); + LogLessondIds(req.body()); + Resp200 resp200; + resp200().body().lessons() = + dependends_.lesson_controller.FindLessons(filter); + return resp200; + } + + protected: + Dependends dependends_; +}; +} // namespace + +void Append(userver::components::ComponentList& component_list) +{ + component_list.Append(); +} + +} // namespace views::timetable diff --git a/src/views/timetable/view.hpp b/src/views/timetable/view.hpp new file mode 100644 index 00000000..c3fbf532 --- /dev/null +++ b/src/views/timetable/view.hpp @@ -0,0 +1,7 @@ +#pragma once +#include +namespace views::timetable +{ +void Append(userver::components::ComponentList& component_list); + +} diff --git a/tests/timetable/get/timetable_get_data.py b/tests/timetable/get/timetable_get_data.py index 90e9f43c..94fd2896 100644 --- a/tests/timetable/get/timetable_get_data.py +++ b/tests/timetable/get/timetable_get_data.py @@ -1,7 +1,7 @@ K_LESSON = { "id": "3d04fc36-ab71-42db-9e38-efd792afa7ba", # + - "begin": "2023-04-01T05:30:00+0000", # + - "end": "2023-05-01T07:05:00+0000", # + + "begin": "2023-04-01T05:30:00+00:00", # + + "end": "2023-05-01T07:05:00+00:00", # + "number": 1, # + "type": "lection", # + "week_type": "all", # +