diff --git a/.gen/objs.txt b/.gen/objs.txt index 70a8c07e..859b8293 100644 --- a/.gen/objs.txt +++ b/.gen/objs.txt @@ -1,12 +1,16 @@ -src/views/test-openapi-view/view.hpp -src/views/test-openapi-view/view.cpp -src/views/test-openapi-view/declarations.hpp +src/views/register/view.hpp +src/views/register/view.cpp +src/views/register/declarations.hpp +src/views/login/view.hpp +src/views/login/view.cpp +src/views/login/declarations.hpp src/utils/type_holder.hpp src/utils/tests_macros.hpp src/utils/shared_transaction.hpp src/utils/serialize/uuid/string.hpp src/utils/serialize/uuid/string.cpp src/utils/postgres_helper.hpp +src/utils/pg_controller.hpp src/utils/perform_common_errors.hpp src/utils/perform_common_errors.cpp src/utils/parse/uuid/string.hpp @@ -14,6 +18,7 @@ src/utils/parse/uuid/string.cpp src/utils/meta.hpp src/utils/json_type.hpp src/utils/json_type.cpp +src/utils/is_complete_type.hpp src/utils/formated_exception.hpp src/utils/convert/json_serialize.hpp src/utils/convert/json_parse.hpp @@ -32,6 +37,7 @@ src/utils/convert/additional_properties.hpp src/utils/constexpr_string.hpp src/utils/constexpr_optional.hpp src/utils/component_list_fwd.hpp +src/utils/component.hpp src/utils/compilers_macros.hpp src/utils/common_errors.hpp src/openapi/types/uuid_type.hpp @@ -88,18 +94,20 @@ src/openapi/from_tuple/property.hpp src/openapi/from_tuple/optional.hpp src/openapi/from_tuple/default.hpp src/openapi/from_tuple/all.hpp -src/openapi/doc/serialize/uuid.hpp -src/openapi/doc/serialize/response.hpp -src/openapi/doc/serialize/request.hpp -src/openapi/doc/serialize/remove_requests.hpp -src/openapi/doc/serialize/reflective.hpp -src/openapi/doc/serialize/path.hpp -src/openapi/doc/serialize/header.hpp -src/openapi/doc/serialize/cookie.hpp -src/openapi/doc/serialize/body.hpp -src/openapi/doc/serialize/base.hpp -src/openapi/doc/serialize/array.hpp -src/openapi/doc/serialize/all.hpp +src/openapi/doc/uuid.hpp +src/openapi/doc/string.hpp +src/openapi/doc/response.hpp +src/openapi/doc/request.hpp +src/openapi/doc/reflective.hpp +src/openapi/doc/property.hpp +src/openapi/doc/path.hpp +src/openapi/doc/int.hpp +src/openapi/doc/header.hpp +src/openapi/doc/cookie.hpp +src/openapi/doc/body.hpp +src/openapi/doc/base.hpp +src/openapi/doc/array.hpp +src/openapi/doc/all.hpp src/openapi/base/uuid_traits.hpp src/openapi/base/uuid_property.hpp src/openapi/base/string_traits.hpp @@ -129,6 +137,11 @@ src/openapi/as_tuple/optional.hpp src/openapi/as_tuple/default.hpp src/openapi/as_tuple/all.hpp src/openapi/all.hpp +src/models/user_credentials/type.hpp +src/models/user_credentials/postgres.hpp +src/models/user/type.hpp +src/models/user/postgres.hpp +src/models/error_v1/type.hpp src/legacy/views/timetable/get/view.hpp src/legacy/views/timetable/get/view.cpp src/legacy/views/timetable/get/Responses.hpp @@ -185,6 +198,7 @@ src/legacy/models/user_type/serialize.cpp src/legacy/models/user_type/postgre.hpp src/legacy/models/user_type/parse.hpp src/legacy/models/user_type/parse.cpp +src/legacy/models/user_type/doc.hpp src/legacy/models/user_credentials/type.hpp src/legacy/models/user_credentials/postgre.hpp src/legacy/models/user_credentials/fwd.hpp @@ -323,3 +337,11 @@ src/legacy/components/controllers/postgres/admin/controller.cpp src/http/legacy_handler_parsed.hpp src/http/handler_parsed.hpp src/http/ErrorV1.hpp +src/controllers/user/controller_fwd.hpp +src/controllers/user/controller.hpp +src/controllers/user/controller.cpp +src/controllers/token/controller_fwd.hpp +src/controllers/token/controller.hpp +src/controllers/token/controller.cpp +src/codegen/sql.hpp +src/codegen/sql.cpp diff --git a/Makefile b/Makefile index d878cb2e..98afdfdf 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,8 @@ CMAKE_COMMON_FLAGS ?= -DCMAKE_EXPORT_COMPILE_COMMANDS=ON CMAKE_DEBUG_FLAGS ?= -DUSERVER_SANITIZE='addr ub' CMAKE_RELEASE_FLAGS ?= CMAKE_OS_FLAGS ?= -DUSERVER_FEATURE_CRYPTOPP_BLAKE2=0 -DUSERVER_FEATURE_REDIS_HI_MALLOC=1 -FORMAT_INCLUDES_FLAGS ?= userver boost gtest openapi utils +FORMAT_INCLUDES_FLAGS ?= userver boost gtest openapi utils codegen +GENERATE_SQL_QUERIES_FLAGS ?= src/sql src/codegen sql sql NPROCS ?= $(shell nproc) CLANG_FORMAT ?= clang-format-11 @@ -161,8 +162,9 @@ check-format-cpp: @find service -name '*pp' -type f | xargs $(CLANG_FORMAT) -i --dry-run --Werror @find src -name '*pp' -type f | xargs $(CLANG_FORMAT) -i --dry-run --Werror @find utests -name '*pp' -type f | xargs $(CLANG_FORMAT) -i --dry-run --Werror -.PHONY: gen -gen: + +.PHONY: gen-sources +gen-sources: @rm -rf .gen @mkdir -p .gen @@ -183,6 +185,15 @@ gen: unite-api: @python3 scripts/merge_yaml.py api/api.yaml united_api.yaml +.PHONY: gen-queries +gen-queries: + @python3 scripts/generate_sql_queries.py $(GENERATE_SQL_QUERIES_FLAGS) + +.PHONY: gen +gen: + $(MAKE) gen-queries + $(MAKE) gen-sources + # # Internal hidden targets that are used only in docker environment # --in-docker-start-debug --in-docker-start-release: --in-docker-start-%: install-% # @sed -i 's/config_vars.yaml/config_vars.docker.yaml/g' /home/user/.local/etc/timetable_vsu_backend/static_config.yaml diff --git a/configs/static_config.yaml.in b/configs/static_config.yaml.in index 4712782b..6a093b68 100644 --- a/configs/static_config.yaml.in +++ b/configs/static_config.yaml.in @@ -56,10 +56,12 @@ components_manager: handler-login: path: /login method: POST + load-enabled: false task_processor: main-task-processor handler-register: path: /register - method: POST + method: POST + load-enabled: false task_processor: main-task-processor handler-timetable-get: path: /timetable/get @@ -101,8 +103,12 @@ components_manager: path: /group-stage/list method: POST task_processor: main-task-processor - test-login-view: - path: /test/login + login-view: + path: /login + method: POST + task_processor: main-task-processor + register-view: + path: /register method: POST task_processor: main-task-processor openapi-descriptor: @@ -133,6 +139,12 @@ components_manager: password: $root_password id: $root_id token_controller: {} + new-token-controller: {} + new-user-controller: + root: + login: $root_login + password: $root_password + id: $root_id lesson_details_controller : {} teacher_controller : {} handler-ping: diff --git a/service/main.cpp b/service/main.cpp index a96842ef..13b6e285 100644 --- a/service/main.cpp +++ b/service/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -11,6 +12,9 @@ #include #include +#include "controllers/token/controller_fwd.hpp" +#include "controllers/user/controller.hpp" +#include "controllers/user/controller_fwd.hpp" #include "legacy/components/controllers/postgres/admin/fwd.hpp" #include "legacy/components/controllers/postgres/faculty/fwd.hpp" #include "legacy/components/controllers/postgres/group_stage/fwd.hpp" @@ -31,7 +35,8 @@ #include "legacy/views/teacher/request/approve/new/view.hpp" #include "legacy/views/teacher/request/list/view.hpp" #include "legacy/views/timetable/get/view.hpp" -#include "views/test-openapi-view/view.hpp" +#include "views/login/view.hpp" +#include "views/register/view.hpp" void AppendPgControllers(userver::components::ComponentList& component_list) { @@ -43,12 +48,13 @@ 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 AppendViews(userver::components::ComponentList& component_list) +void AppendLegacyViews(userver::components::ComponentList& component_list) { using namespace legacy::views; - using namespace views; login::Append(component_list); register_::Append(component_list); timetable::get::Append(component_list); @@ -61,7 +67,13 @@ void AppendViews(userver::components::ComponentList& component_list) teacher::requests::approve::new_::Append(component_list); faculty::list::Append(component_list); group::stage::list::Append(component_list); - test::login::Append(component_list); +} + +void AppendViews(userver::components::ComponentList& component_list) +{ + using namespace views; + login::Append(component_list); + Register::Append(component_list); } int main(int argc, char* argv[]) @@ -77,7 +89,7 @@ int main(int argc, char* argv[]) openapi::http::AppendOpenApiDescriptor(component_list); service_template::AppendHello(component_list); AppendPgControllers(component_list); + AppendLegacyViews(component_list); AppendViews(component_list); - return userver::utils::DaemonMain(argc, argv, component_list); } diff --git a/src/openapi/all.hpp b/src/openapi/all.hpp index e030da02..b5916e91 100644 --- a/src/openapi/all.hpp +++ b/src/openapi/all.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/openapi/base/array_property.hpp b/src/openapi/base/array_property.hpp index 6db950bf..d0a2c9a0 100644 --- a/src/openapi/base/array_property.hpp +++ b/src/openapi/base/array_property.hpp @@ -13,7 +13,7 @@ struct ArrayProperty : public PropertyBase, Traits> }; template -struct Property, Traits> : public ArrayProperty +struct types::Property, Traits> : public ArrayProperty { }; diff --git a/src/openapi/base/object_property.hpp b/src/openapi/base/object_property.hpp index 073da2ee..9b33837d 100644 --- a/src/openapi/base/object_property.hpp +++ b/src/openapi/base/object_property.hpp @@ -14,7 +14,7 @@ requires checks::is_reflective_v struct ObjectProperty }; template -requires checks::is_reflective_v struct Property +requires checks::is_reflective_v struct types::Property : public ObjectProperty { }; diff --git a/src/openapi/base/optional_property.hpp b/src/openapi/base/optional_property.hpp index 3b0c905d..1456de49 100644 --- a/src/openapi/base/optional_property.hpp +++ b/src/openapi/base/optional_property.hpp @@ -9,7 +9,8 @@ struct OptionalProperty : public PropertyBase, Traits> }; template -struct Property, Traits> : public OptionalProperty +struct types::Property, Traits> + : public OptionalProperty { }; diff --git a/src/openapi/base/property_base.hpp b/src/openapi/base/property_base.hpp index 0f880e01..67b38e82 100644 --- a/src/openapi/base/property_base.hpp +++ b/src/openapi/base/property_base.hpp @@ -35,11 +35,16 @@ struct PropertyBase } template - value_type& operator=(Arg&& arg) + auto& operator=(Arg&& arg) { value = std::forward(arg); return value; } + auto& operator=(value_type rhs) + { + value = std::move(rhs); + return *this; + } value_type& operator()() { return value; @@ -60,9 +65,13 @@ concept IsProperty = requires T>; }; +namespace types +{ template -struct Property +struct Property : PropertyBase { }; +} // namespace types + } // namespace openapi diff --git a/src/openapi/base/string_property.hpp b/src/openapi/base/string_property.hpp index 2aa8d63e..efb4eedf 100644 --- a/src/openapi/base/string_property.hpp +++ b/src/openapi/base/string_property.hpp @@ -12,7 +12,7 @@ struct StringProperty : public PropertyBase }; template -struct Property : public StringProperty +struct types::Property : public StringProperty { }; diff --git a/src/openapi/base/uuid_property.hpp b/src/openapi/base/uuid_property.hpp index 6e1bac72..0ea8a57b 100644 --- a/src/openapi/base/uuid_property.hpp +++ b/src/openapi/base/uuid_property.hpp @@ -62,7 +62,7 @@ struct UuidProperty : PropertyBase }; template -struct Property : UuidProperty +struct types::Property : UuidProperty { }; } // namespace openapi diff --git a/src/openapi/doc/serialize/all.hpp b/src/openapi/doc/serialize/all.hpp deleted file mode 100644 index 70955de4..00000000 --- a/src/openapi/doc/serialize/all.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include diff --git a/src/openapi/doc/serialize/array.hpp b/src/openapi/doc/serialize/array.hpp deleted file mode 100644 index 9b6d4be1..00000000 --- a/src/openapi/doc/serialize/array.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include - -namespace openapi -{ -template -void Append(DocHelper doc_helper, - std::type_identity> = {}) -{ - constexpr traits::ArrayHelperTraits traits; - auto& field_node = doc_helper.cur_place; - if (!field_node.IsObject()) - field_node = userver::formats::common::Type::kObject; - field_node["type"] = "array"; - if constexpr (traits.min.HasValue()) - { - field_node["minItems"] = traits.min.value(); - } - if constexpr (traits.max.HasValue()) - { - field_node["maxItems"] = traits.max.value(); - } - if constexpr (traits.unique_items.value_or(false)) - { - field_node["uniqueItems"] = true; - } - auto items_node = field_node["items"]; - Append(DocHelper{doc_helper.root, items_node}, std::type_identity{}); -} -} // namespace openapi diff --git a/src/openapi/doc/serialize/base.hpp b/src/openapi/doc/serialize/base.hpp deleted file mode 100644 index 72b28c8d..00000000 --- a/src/openapi/doc/serialize/base.hpp +++ /dev/null @@ -1,212 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace openapi -{ -inline void log_yaml_impl(userver::formats::yaml::ValueBuilder yaml, - std::string_view file_name, int line, - std::string_view function_name) -{ - std::clog << "=======================\n"; - std::clog << file_name << "(" << line << ") " << function_name << "\n"; - std::clog << "====================\n"; - std::clog << ToString(yaml.ExtractValue()) << '\n'; -} - -#define log_yaml(yaml) \ - ::openapi::log_yaml_impl(yaml, __FILE__, __LINE__, __PRETTY_FUNCTION__) - -// some_namespace..some_class -// precondition: string from demangle -inline void RemoveNamespaces(std::string& name_class) -{ - auto read = std::find(name_class.begin(), name_class.end(), ':'); - auto write = read; - while (read != name_class.end()) - { - if (*read == ':') - { - read++; - *read = '.'; - } - *write = *read; - read++; - write++; - } - name_class.erase(write, name_class.end()); -} -/* -это нужно для: - -1) явного переопределения названий классов в рамках опенапи - -2) написания какой-то логики преобразований -*/ -template -std::string GetOpenApiTypeName() -{ - std::string raw_name = userver::compiler::GetTypeName(); - if (raw_name.find_first_of('<') != std::string::npos || - raw_name.find_first_of('>') != std::string::npos) - { - throw std::runtime_error(fmt::format( - "template in name type: {}, overload this function", raw_name)); - } - RemoveNamespaces(raw_name); - return raw_name; -} - -/*не перегружайте эту функцию без необходимости. - -Нужна для проверки, что это действительно один тип.*/ -template -std::string GetRawTypeName() -{ - std::string raw_name = userver::compiler::GetTypeName(); - return raw_name; -} - -template -requires checks::is_reflective_v void PlaceRefToType( - userver::formats::yaml::ValueBuilder& place) -{ - if (!place.IsObject()) - { - place = userver::formats::common::Type::kObject; - } - auto ref_str = - std::string(R"(#/components/schemas/)").append(GetOpenApiTypeName()); - place["$ref"] = std::move(ref_str); -} - -template -requires checks::is_reflective_v void PlaceRefToResponse( - userver::formats::yaml::ValueBuilder& place) -{ - if (!place.IsObject()) - { - place = userver::formats::common::Type::kObject; - } - auto ref_str = std::string(R"(#/components/responses/)") - .append(GetOpenApiTypeName()); - place["$ref"] = std::move(ref_str); -} - -template -requires checks::is_reflective_v void PlaceRefToRequest( - userver::formats::yaml::ValueBuilder& place) -{ - if (!place.IsObject()) - { - place = userver::formats::common::Type::kObject; - } - auto ref_str = - std::string(R"(#/requests/)").append(GetOpenApiTypeName()); - place["$ref"] = std::move(ref_str); -} - -template -consteval bool IsAnyOf() -{ - return (std::same_as || ...); -} - -template -concept IsDefaultOpenApiType = requires -{ - requires IsAnyOf() || std::is_integral_v; -}; -using StringMap = std::unordered_map; - -struct DocHelper -{ - userver::formats::yaml::ValueBuilder& root; - userver::formats::yaml::ValueBuilder& cur_place; -}; - -inline void log_dock_helper_impl(DocHelper doc_helper, - std::string_view file_name, int line, - std::string_view function_name) -{ - std::clog << "=======================\n"; - std::clog << file_name << "(" << line << ") " << function_name << "\n"; - std::clog << "====================\n"; - auto [cur_place, root] = doc_helper; - - std::clog << ToString(root.ExtractValue()) << '\n'; -} - -template -void Append(DocHelper doc_helper, - std::type_identity> = {}) -{ - Append(doc_helper, std::type_identity{}); -} - -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["format"] = "int32"; -} - -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"] = "string"; -} - -template -void Append(DocHelper doc_helper, - std::type_identity> = {}) -{ - constexpr traits::StringHelperTraits traits; - auto& field_node = doc_helper.cur_place; - if (!field_node.IsObject()) - field_node = userver::formats::common::Type::kObject; - field_node["type"] = "string"; - if constexpr (!traits.pattern.empty()) - { - field_node["pattern"] = std::string{traits.pattern.AsStringView()}; - } -} - -} // namespace openapi diff --git a/src/openapi/doc/serialize/body.hpp b/src/openapi/doc/serialize/body.hpp deleted file mode 100644 index 46a283c2..00000000 --- a/src/openapi/doc/serialize/body.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include -#include - -namespace openapi -{ -template -void AppendRequestField(DocHelper doc_helper, - std::type_identity>) -{ - auto& [root, cur] = doc_helper; - auto request_body_node = cur["requestBody"]; - if (!request_body_node.IsObject()) - { - request_body_node = userver::formats::yaml::Type::kObject; - } - request_body_node["required"] = !userver::meta::kIsOptional; - auto content = request_body_node["content"]; - if (!content.IsObject()) - { - content = userver::formats::yaml::Type::kObject; - } - auto application_json_node = content["application/json"]; - if (application_json_node.IsObject()) - { - application_json_node = userver::formats::yaml::Type::kObject; - } - auto schema = application_json_node["schema"]; - Append(DocHelper{doc_helper.root, schema}, std::type_identity{}); -} - -template -void AppendResponseField(DocHelper doc_helper, - std::type_identity>) -{ - auto& [root, cur] = doc_helper; - auto schema = cur["content"]["application/json"]["schema"]; - Append(DocHelper{doc_helper.root, schema}, std::type_identity{}); -} -} // namespace openapi diff --git a/src/openapi/doc/serialize/cookie.hpp b/src/openapi/doc/serialize/cookie.hpp deleted file mode 100644 index 04397ec1..00000000 --- a/src/openapi/doc/serialize/cookie.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace openapi -{ -template -void AppendRequestField(DocHelper doc_helper, - std::type_identity>) -{ - auto& [root, cur] = doc_helper; - auto parameters_node = cur["parameters"]; - if (!parameters_node.IsArray()) - { - parameters_node = userver::formats::yaml::Type::kArray; - } - static_assert(!traits::GetName().empty(), "Cookie must have name"); - userver::formats::yaml::ValueBuilder parameter_node = - userver::formats::yaml::Type::kObject; - parameter_node["in"] = "cookie"; - parameter_node["name"] = traits::GetName().AsString(); - parameter_node["required"] = userver::meta::kIsOptional; - auto schema = parameter_node["schema"]; - Append(DocHelper{doc_helper.root, schema}, std::type_identity{}); - parameters_node.PushBack(std::move(parameter_node)); -} - -template -void AppendResponseField(DocHelper, - std::type_identity>) -{ - STATIC_ASSERT_FALSE( - "OpenApi 3.0 doesnt support cookie in reponse. Sorry :("); -} - -} // namespace openapi diff --git a/src/openapi/doc/serialize/header.hpp b/src/openapi/doc/serialize/header.hpp deleted file mode 100644 index 54923582..00000000 --- a/src/openapi/doc/serialize/header.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include - -namespace openapi -{ -template -void AppendRequestField(DocHelper doc_helper, - std::type_identity>) -{ - auto& [root, cur] = doc_helper; - auto parameters_node = cur["parameters"]; - if (!parameters_node.IsArray()) - { - parameters_node = userver::formats::yaml::Type::kArray; - } - static_assert(!traits::GetName().empty(), "Header must have name"); - userver::formats::yaml::ValueBuilder parameter_node = - userver::formats::yaml::Type::kObject; - parameter_node["in"] = "header"; - parameter_node["name"] = traits::GetName().AsString(); - parameter_node["required"] = userver::meta::kIsOptional; - auto schema = parameter_node["schema"]; - if constexpr (userver::meta::kIsOptional) - { - Append(DocHelper{doc_helper.root, schema}, - std::type_identity{}); - } - else - { - Append(DocHelper{doc_helper.root, schema}, std::type_identity{}); - } - parameters_node.PushBack(std::move(parameter_node)); -} - -template -void AppendResponseField(DocHelper doc_helper, - std::type_identity>) -{ - auto& [root, cur] = doc_helper; - constexpr auto name = traits::GetName(); - static_assert(!name.empty(), "Header must have name"); - auto name_s = name.AsString(); - auto header = cur["headers"][name_s]["schema"]; - Append(DocHelper{doc_helper.root, header}, std::type_identity{}); -} -} // namespace openapi diff --git a/src/openapi/doc/serialize/path.hpp b/src/openapi/doc/serialize/path.hpp deleted file mode 100644 index 591ffae7..00000000 --- a/src/openapi/doc/serialize/path.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -namespace openapi -{ -struct HandlerInfo -{ - const std::string& path; - const std::string& method; -}; - -template -void AppendPathResponse( - Doc& doc, userver::formats::yaml::ValueBuilder& view, - std::type_identity>) -{ - auto status_code = static_cast(Traits::code); - std::string code_str = std::to_string(status_code); - auto resp = view[code_str]; - AppendResponse(doc, std::type_identity{}); - PlaceRefToResponse(resp); -} - -namespace impl -{ -inline std::vector split_methods(HandlerInfo handler_info) -{ - std::string method_low; - std::vector methods; - for (auto ch : handler_info.method) - { - if (ch != ',') - { - method_low.append(1, tolower(ch)); - } - else - { - methods.emplace_back(std::move(method_low)); - } - } - if (!method_low.empty()) - { - methods.emplace_back(std::move(method_low)); - } - return methods; -} -} // namespace impl - -template -void AppendPath(Doc& doc, HandlerInfo handler_info, std::type_identity req, - std::type_identity... resp) -{ - auto& root = doc(); - auto& [path, method_raw] = handler_info; - auto methods = impl::split_methods(handler_info); - for (auto& method : methods) - { - auto view = root["paths"][path][method]; - AppendRequest(DocHelper{doc(), view}, req); - auto responses = view["responses"]; - (AppendPathResponse(doc, responses, resp), ...); - } -} -} // namespace openapi diff --git a/src/openapi/doc/serialize/reflective.hpp b/src/openapi/doc/serialize/reflective.hpp deleted file mode 100644 index d73158e2..00000000 --- a/src/openapi/doc/serialize/reflective.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once -#include -#include -#include - -namespace openapi -{ -template -void AppendField(DocHelper doc_helper, std::type_identity type = {}) -{ - using Traits = typename T::traits; - constexpr auto name_ce = traits::GetName(); - constexpr auto name_ce_empty = name_ce.empty(); - static_assert(!name_ce_empty, "Field must have name"); - std::string name{name_ce.AsStringView()}; - auto field_node = doc_helper.cur_place["properties"][name]; - auto matcher = userver::utils::Overloaded{ - [&](std::type_identity) { - auto required = doc_helper.cur_place["required"]; - if (!required.IsArray()) - required = userver::formats::common::Type::kArray; - required.PushBack(name); - }, - []( - std::type_identity>) {}}; - matcher(type); - Append(DocHelper{doc_helper.root, field_node}, std::type_identity{}); -} - -// noop, пропускаем -template <> -inline void AppendField(DocHelper, std::type_identity) -{ -} - -template -requires checks::is_reflective_v void Append(DocHelper doc_helper, - std::type_identity, - bool append_cur_place = true) -{ - std::string name_type = GetOpenApiTypeName(); - if (append_cur_place) - { - PlaceRefToType(doc_helper.cur_place); - } - auto type_node = doc_helper.root["components"]["schemas"][name_type]; - if (!type_node.IsObject()) - { - type_node = userver::formats::common::Type::kObject; - type_node["type"] = "object"; - constexpr checks::ReflectivePreferences pref{}; - bool additional_properties = (pref.additional_properties_status == - checks::AdditionalPropertiesStatus::True); - type_node["additionalProperties"] = additional_properties; - auto dock_helper = DocHelper{doc_helper.root, type_node}; - auto visiter_fields = [dock_helper](auto field) { - AppendField(dock_helper, field); - }; - CallAllFields(visiter_fields); - } -} - -template -requires checks::is_reflective_v void Append(Doc& doc, std::type_identity) -{ - auto& root = doc.value_; - Append(DocHelper{root, root}, std::type_identity{}, false); -} - -} // namespace openapi diff --git a/src/openapi/doc/serialize/remove_requests.hpp b/src/openapi/doc/serialize/remove_requests.hpp deleted file mode 100644 index 63a361d0..00000000 --- a/src/openapi/doc/serialize/remove_requests.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include -#include -#include -namespace openapi -{ -inline void RemoveRequests(Doc& doc) -{ - auto root = doc().ExtractValue(); -} -} // namespace openapi diff --git a/src/openapi/doc/serialize/request.hpp b/src/openapi/doc/serialize/request.hpp deleted file mode 100644 index 87573db2..00000000 --- a/src/openapi/doc/serialize/request.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace openapi -{ -template -requires checks::is_reflective_v void AppendRequest(DocHelper doc_helper, - std::type_identity) -{ - auto& [root, cur] = doc_helper; - if (cur.IsObject()) - { - return; - } - cur["description"] = GetOpenApiTypeName(); - CallAllFields( - [doc_helper](auto field) { AppendRequestField(doc_helper, field); }); -} -} // namespace openapi diff --git a/src/openapi/doc/serialize/response.hpp b/src/openapi/doc/serialize/response.hpp deleted file mode 100644 index 30d30652..00000000 --- a/src/openapi/doc/serialize/response.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace openapi -{ -template -requires checks::is_reflective_v void AppendResponse(Doc& doc, - std::type_identity) -{ - auto& root = doc.value_; - userver::formats::yaml::ValueBuilder response = - root["components"]["responses"][GetOpenApiTypeName()]; - if (response.IsObject()) - { - return; - } - auto description = response["description"]; - description = ""; - auto doc_helper = DocHelper{root, response}; - CallAllFields( - [doc_helper](auto field) { AppendResponseField(doc_helper, field); }); -} -} // namespace openapi diff --git a/src/openapi/doc/serialize/uuid.hpp b/src/openapi/doc/serialize/uuid.hpp deleted file mode 100644 index 8ac9f41e..00000000 --- a/src/openapi/doc/serialize/uuid.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include -#include -#include - -namespace openapi -{ -template -void Append(DocHelper doc_helper, std::type_identity> = {}) -{ - constexpr traits::UuidHelperTraits traits; - auto& field_node = doc_helper.cur_place; - if (!field_node.IsObject()) - field_node = userver::formats::common::Type::kObject; - field_node["type"] = "string"; - field_node["format"] = "uuid"; -} -} // namespace openapi diff --git a/src/openapi/http/handler.hpp b/src/openapi/http/handler.hpp index 42ecd27c..9e20da8e 100644 --- a/src/openapi/http/handler.hpp +++ b/src/openapi/http/handler.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include #include #include @@ -20,13 +20,16 @@ #include #include #include +#include #include namespace openapi::http { -template +template struct OpenApiHandler : public userver::server::handlers::HttpHandlerBase { + [[maybe_unused]] static constexpr auto kName = Name; using Resps = std::variant; OpenApiHandler(const userver::components::ComponentConfig& cfg, const userver::components::ComponentContext& ctx) diff --git a/src/openapi/postgres/mapping.hpp b/src/openapi/postgres/mapping.hpp index 0b12484d..36b41656 100644 --- a/src/openapi/postgres/mapping.hpp +++ b/src/openapi/postgres/mapping.hpp @@ -2,9 +2,23 @@ #include #include +#include #include #include #include +#include + +namespace openapi +{ +template +concept IsPgUserProperty = IsProperty&& utils::is_complete_type< + userver::storages::postgres::io::CppToUserPg>; + +template +concept IsPgSystemProperty = IsProperty&& utils::is_complete_type< + userver::storages::postgres::io::CppToSystemPg>; +} // namespace openapi + namespace userver::storages::postgres::io { namespace detail @@ -68,7 +82,7 @@ struct BufferParser< }; template -requires openapi::checks::is_reflective_property_v struct CppToUserPg +requires openapi::IsPgUserProperty struct CppToUserPg { private: using Inner = typename T::value_type; @@ -79,8 +93,7 @@ requires openapi::checks::is_reflective_property_v struct CppToUserPg }; template -requires openapi::checks::is_not_reflective_property_v struct CppToSystemPg< - T> +requires openapi::IsPgSystemProperty struct CppToSystemPg { private: using Inner = typename T::value_type; diff --git a/src/utils/shared_transaction.hpp b/src/utils/shared_transaction.hpp index cdbf9381..c738d949 100644 --- a/src/utils/shared_transaction.hpp +++ b/src/utils/shared_transaction.hpp @@ -1,24 +1,129 @@ #pragma once +#include #include +#include #include #include +#include #include #include namespace utils { +namespace details +{ +template +consteval bool IsRowType() +{ + auto value = + userver::storages::postgres::io::traits::kRowCategory != + userver::storages::postgres::io::traits::RowCategoryType::kNonRow; + return value; +} +template +T AsSingleRow(const userver::storages::postgres::ResultSet& pg_res) +{ + if constexpr (IsRowType()) + { + return pg_res.AsSingleRow(userver::storages::postgres::kRowTag); + } + else + { + return pg_res.AsSingleRow(); + } +} + +template +Result AsContainer(const userver::storages::postgres::ResultSet& pg_res) +{ + if constexpr (IsRowType()) + { + return pg_res.AsContainer(userver::storages::postgres::kRowTag); + } + else + { + return pg_res.AsContainer(); + } +} +} // namespace details + // thread unsafe // count owners struct SafeTranscaction { + enum class ActionOnDeath + { + kCommit, + kRollback, + kNone + }; userver::storages::postgres::Transaction transaction_; + template + userver::storages::postgres::ResultSet Execute( + const userver::storages::postgres::Query& query, const Args&... args) + { + return transaction_.Execute( + userver::storages::postgres::OptionalCommandControl{}, query, + args...); + } + + template + Result Execute_R(const userver::storages::postgres::Query& query, + const Args&... args) + { + using namespace details; + userver::storages::postgres::ResultSet pg_res = Execute(query, args...); + if constexpr (userver::meta::kIsOptional) + { + if (pg_res.IsEmpty()) + { + return std::nullopt; + } + return AsSingleRow(pg_res); + } + else if constexpr (userver::meta::kIsRange && + !std::is_same_v) + { + return AsContainer(pg_res); + } + else + { + return AsSingleRow(pg_res); + } + } 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) + name, userver::storages::postgres::ClusterHostType::kMaster, {})) + { + if (auto_commit) + { + action_on_death = ActionOnDeath::kCommit; + } + else + { + action_on_death = ActionOnDeath::kNone; + } + } + + SafeTranscaction(userver::storages::postgres::Transaction transction, + ActionOnDeath action_on_death) + : transaction_(std::move(transction)), action_on_death(action_on_death) { } + + void Commit() + { + action_on_death = ActionOnDeath::kNone; + transaction_.Commit(); + } + + void RollBack() + { + action_on_death = ActionOnDeath::kNone; + transaction_.Commit(); + } + friend void intrusive_ptr_add_ref(SafeTranscaction* transaction) { transaction->counter++; @@ -32,14 +137,21 @@ struct SafeTranscaction } ~SafeTranscaction() { - if (auto_commit_) + switch (action_on_death) { - transaction_.Commit(); + case ActionOnDeath::kCommit: + transaction_.Commit(); + return; + case ActionOnDeath::kRollback: + transaction_.Rollback(); + return; + case ActionOnDeath::kNone: + return; } } private: - bool auto_commit_; + ActionOnDeath action_on_death; size_t counter = 0; }; @@ -79,4 +191,25 @@ inline void FillSharedTransaction( transaction = ::utils::MakeSharedTransaction(ptr, name, auto_commit); } } + +inline auto MakeSharedTransaction( + const userver::storages::postgres::ClusterPtr& ptr, + SafeTranscaction::ActionOnDeath action_on_death) +{ + return userver::utils::make_intrusive_ptr( + ptr->Begin("", userver::storages::postgres::ClusterHostType::kMaster, + {}), + action_on_death); +} + +inline void FillSharedTransaction( + SharedTransaction& transaction, + const userver::storages::postgres::ClusterPtr& ptr, + SafeTranscaction::ActionOnDeath action_on_death) +{ + if (!transaction) + { + transaction = ::utils::MakeSharedTransaction(ptr, action_on_death); + } +} } // namespace utils diff --git a/src/views/test-openapi-view/declarations.hpp b/src/views/test-openapi-view/declarations.hpp deleted file mode 100644 index 55559092..00000000 --- a/src/views/test-openapi-view/declarations.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#include -#include -#include -#include - -using namespace openapi::types; -using namespace openapi::http; -using namespace openapi::preferences; -namespace views::test::login -{ -struct RequestBody -{ - String> login; - String> password; - auto operator<=>(const RequestBody&) const = default; -}; - -struct Request -{ - Body body; - auto operator<=>(const Request&) const = default; -}; - -struct ResponseBody -{ - String> some_string; - auto operator<=>(const ResponseBody&) const = default; -}; - -struct Response -{ - Body body; - Header> some_header; - auto operator<=>(const Response&) const = default; -}; - -} // namespace views::test::login diff --git a/src/views/test-openapi-view/view.cpp b/src/views/test-openapi-view/view.cpp deleted file mode 100644 index 6e9de4f7..00000000 --- a/src/views/test-openapi-view/view.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "view.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "declarations.hpp" - -namespace views::test::login -{ -namespace -{ -using Resp200 = Resp; -using Resp400 = Resp; -struct View final - : public openapi::http::OpenApiHandler -{ - static constexpr std::string_view kName = "test-login-view"; - using Base = openapi::http::OpenApiHandler; - View(const userver::components::ComponentConfig& cfg, - const userver::components::ComponentContext& ctx) - : Base(cfg, ctx) - { - } - Resps Handle(Request&&) const override - { - Resp200 resp200; - return resp200; - } -}; -} // namespace - -void Append(userver::components::ComponentList& component_list) -{ - component_list.Append(); -} - -} // namespace views::test::login diff --git a/src/views/test-openapi-view/view.hpp b/src/views/test-openapi-view/view.hpp deleted file mode 100644 index fb2710ef..00000000 --- a/src/views/test-openapi-view/view.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once -#include -namespace views::test::login -{ -void Append(userver::components::ComponentList& component_list); - -} diff --git a/utests/openapi/doc/serialize/basic_request.cpp b/utests/openapi/doc/serialize/basic_request.cpp index c99df0a0..4c557f2e 100644 --- a/utests/openapi/doc/serialize/basic_request.cpp +++ b/utests/openapi/doc/serialize/basic_request.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include diff --git a/utests/openapi/json/parse/basic_array.cpp b/utests/openapi/json/parse/basic_array.cpp index 561037de..3bd472c3 100644 --- a/utests/openapi/json/parse/basic_array.cpp +++ b/utests/openapi/json/parse/basic_array.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/utests/remove_namespace.cpp b/utests/remove_namespace.cpp index b14218db..095482bf 100644 --- a/utests/remove_namespace.cpp +++ b/utests/remove_namespace.cpp @@ -1,4 +1,4 @@ -#include +#include #include UTEST(RemoveNamespace, Basic) diff --git a/vsu_timetable.code-workspace b/vsu_timetable.code-workspace index ff2e24f9..6c36a952 100644 --- a/vsu_timetable.code-workspace +++ b/vsu_timetable.code-workspace @@ -23,7 +23,8 @@ "build*": true, ".*" : true, "dependencies" : true, - "compile_commands.json" : true + "compile_commands.json" : true, + "configs/static_config.yaml" : true }, "C_Cpp.codeAnalysis.clangTidy.useBuildPath": true, },