userver: userver/storages/postgres/io/user_types.hpp Source File
Loading...
Searching...
No Matches
user_types.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/postgres/io/user_types.hpp
4/// @brief User types I/O support
5/// @ingroup userver_postgres_parse_and_format
6
7#include <unordered_map>
8#include <unordered_set>
9
10#include <userver/storages/postgres/exceptions.hpp>
11#include <userver/storages/postgres/io/pg_types.hpp>
12#include <userver/storages/postgres/io/type_mapping.hpp>
13
14USERVER_NAMESPACE_BEGIN
15
16namespace storages::postgres {
17
18/// @brief PostgreSQL composite type description
20public:
22 CompositeTypeDescription(CompositeFieldDefs::const_iterator begin, CompositeFieldDefs::const_iterator end)
23 : attributes_{begin, end} {}
24 std::size_t Size() const { return attributes_.size(); }
25 bool Empty() const { return attributes_.empty(); }
26 const CompositeFieldDef& operator[](std::size_t index) const {
27 if (index >= Size()) {
28 throw FieldIndexOutOfBounds{index};
29 }
30 return attributes_[index];
31 }
32
33private:
34 CompositeFieldDefs attributes_;
35};
36
37/// @brief Container for connection-specific user data types.
38class UserTypes {
39public:
41
42 UserTypes() = default;
43 UserTypes(const UserTypes&) = delete;
44 UserTypes(UserTypes&&) noexcept = default;
45
46 UserTypes& operator=(const UserTypes&) = delete;
47 UserTypes& operator=(UserTypes&&) noexcept = default;
48
49 void Reset();
50
51 Oid FindOid(DBTypeName) const;
52 Oid FindArrayOid(DBTypeName) const;
53 /// Find element type oid for an array type.
54 /// Returns invalid oid if the type is not an array or the type is not found
55 Oid FindElementOid(Oid) const;
56 DBTypeName FindName(Oid) const;
57 /// Find name of the base type for a domain or element type for an array.
58 /// For the rest of types returns the name for the oid if found.
60 /// Find base oid for a domain or element type for an array.
61 /// For the rest of types returns the oid itself.
62 Oid FindBaseOid(Oid) const;
63 Oid FindBaseOid(DBTypeName) const;
64 /// Find base oid for a domain.
65 /// For the rest of types returns the oid itself.
66 Oid FindDomainBaseOid(Oid) const;
67
68 bool HasParser(Oid) const;
69 io::BufferCategory GetBufferCategory(Oid) const;
70 const io::TypeBufferCategory& GetTypeBufferCategories() const;
71
72 void AddType(DBTypeDescription&& desc);
73 void AddCompositeFields(CompositeFieldDefs&& defs);
74
75 const CompositeTypeDescription& GetCompositeDescription(Oid) const;
76 /// Get type description by oid.
77 /// May return nullptr if the type was not loaded from the database
79
80 /// @throws UserTypeError if not all registered cpp types are added
82
83private:
84 using DescriptionSet =
90
91 DescriptionSet types_;
92 MapByOid by_oid_;
93 MapByName by_name_;
94 io::TypeBufferCategory buffer_categories_;
95 CompositeTypes composite_types_;
96};
97
98namespace io::detail {
99
100template <typename T>
101inline constexpr DBTypeName kPgUserTypeName = CppToUserPg<T>::postgres_name;
102
103template <typename T>
104struct CppToUserPgImpl {
105 static_assert(io::traits::CheckParser<T>());
106
107 using Type = T;
108 using Mapping = CppToUserPg<T>;
109 static constexpr DBTypeName postgres_name = kPgUserTypeName<T>;
110 static const detail::RegisterUserTypeParser init_;
111 static Oid GetOid(const UserTypes& user_types) {
112 // TODO Handle oid not found
113 return user_types.FindOid(init_.postgres_name);
114 }
115 static Oid GetArrayOid(const UserTypes& user_types) {
116 // TODO Handle oid not found
117 return user_types.FindArrayOid(init_.postgres_name);
118 }
119};
120
121template <typename T>
122const RegisterUserTypeParser CppToUserPgImpl<T>::init_ =
123 RegisterUserTypeParser::Register(kPgUserTypeName<T>, compiler::GetTypeName<T>());
124} // namespace io::detail
125
126void LogRegisteredTypesOnce();
127
128} // namespace storages::postgres
129
130USERVER_NAMESPACE_END