userver: userver/storages/postgres/io/type_mapping.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
type_mapping.hpp
1#pragma once
2
3#include <string>
4#include <type_traits>
5
6#include <userver/compiler/demangle.hpp>
7#include <userver/storages/postgres/detail/is_decl_complete.hpp>
8#include <userver/storages/postgres/io/pg_types.hpp>
9#include <userver/storages/postgres/io/traits.hpp>
10#include <userver/storages/postgres/io/type_traits.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14namespace storages::postgres::io {
15
16/// @brief Detect mapping of a C++ type to Postgres type.
17template <typename T, typename Enable = USERVER_NAMESPACE::utils::void_t<>>
18struct CppToPg;
19
20template <PredefinedOids oid, typename T>
21struct PgToCpp;
22
23/// Find out if a parser for a predefined Postgres type was registered.
25/// Find out if predefined Postgres types are mapped to the same cpp type
27/// Get array element oid for a predefined type
29/// Get the buffer category for a predefined type
31
32bool HasParser(DBTypeName);
33
34namespace detail {
35
36/// Works as boost::ignore_unused, but returning a value.
37template <typename... T>
38inline bool ForceReference(const T&...) {
39 return true;
40}
41
42struct RegisterPredefinedOidParser {
43 static RegisterPredefinedOidParser Register(PredefinedOids type_oid,
44 PredefinedOids array_oid,
45 BufferCategory category,
46 std::string cpp_name);
47};
48
49// note: implementation is in user_types.cpp
50struct RegisterUserTypeParser {
51 static RegisterUserTypeParser Register(const DBTypeName&,
52 std::string cpp_name);
53 const DBTypeName postgres_name;
54};
55
56/// @brief Declare a mapping of a C++ type to a PostgreSQL type oid.
57/// Also mark available parsers
58template <typename T>
59struct CppToSystemPgImpl {
60 using Type = T;
61 using Mapping = CppToSystemPg<T>;
62 static constexpr auto type_oid = Mapping::value;
63 static_assert(type_oid != PredefinedOids::kInvalid, "Type oid is invalid");
64
65 using ArrayMapping = ArrayType<type_oid>;
66 static constexpr auto array_oid = ArrayMapping::value;
67 static_assert(array_oid != PredefinedOids::kInvalid,
68 "Array type oid is invalid");
69
70 // We cannot perform a static check for parser presence here as there are
71 // types that should not have one, e.g. char[N]. All parser checks will be
72 // performed at runtime.
73
74 static const inline RegisterPredefinedOidParser init_ =
75 RegisterPredefinedOidParser::Register(type_oid, array_oid,
76 io::traits::kTypeBufferCategory<T>,
77 compiler::GetTypeName<T>());
78
79 static constexpr Oid GetOid(const UserTypes&) {
80 ForceReference(init_);
81 return static_cast<Oid>(type_oid);
82 }
83 static constexpr Oid GetArrayOid(const UserTypes&) {
84 ForceReference(init_);
85 return static_cast<Oid>(array_oid);
86 }
87};
88
89template <typename T>
90struct CppToUserPgImpl;
91
92/// @brief Declare a mapping of a PostgreSQL predefined type oid to a C++ type.
93/// Available parsers will be marked after referencing the init_
94/// somewhere in the code.
95template <PredefinedOids TypeOid, typename T>
96struct PgToCppPredefined {
97 static constexpr auto type_oid = TypeOid;
98 static_assert(type_oid != PredefinedOids::kInvalid, "Type oid is invalid");
99
100 using ArrayMapping = ArrayType<type_oid>;
101 static constexpr auto array_oid = ArrayMapping::value;
102 static_assert(array_oid != PredefinedOids::kInvalid,
103 "Array type oid is invalid");
104
105 // See above on parser presence checks.
106
107 static const inline RegisterPredefinedOidParser init_ =
108 RegisterPredefinedOidParser::Register(type_oid, array_oid,
109 io::traits::kTypeBufferCategory<T>,
110 compiler::GetTypeName<T>());
111};
112
113} // namespace detail
114
115template <typename T>
122
123template <typename T>
124constexpr bool IsTypeMappedToSystem() {
125 return traits::kIsMappedToPg<T> &&
126 std::is_same<typename CppToPg<T>::Mapping,
127 CppToSystemPg<typename CppToPg<T>::Type>>::value;
128}
129
130void LogRegisteredTypes();
131
132} // namespace storages::postgres::io
133
134USERVER_NAMESPACE_END