userver: userver/storages/postgres/io/date.hpp Source File
Loading...
Searching...
No Matches
date.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/postgres/io/date.hpp
4/// @brief utils::datetime::Date I/O support
5/// @ingroup userver_postgres_parse_and_format
6
7#include <limits>
8
9#include <userver/storages/postgres/io/buffer_io.hpp>
10#include <userver/storages/postgres/io/buffer_io_base.hpp>
11#include <userver/storages/postgres/io/integral_types.hpp>
12#include <userver/storages/postgres/io/type_mapping.hpp>
13#include <userver/utils/datetime/date.hpp>
14
15USERVER_NAMESPACE_BEGIN
16
17namespace storages::postgres {
18
19/// Corresponds to DATE
20using Date = USERVER_NAMESPACE::utils::datetime::Date;
21
22/// Postgres epoch date (2000-01-01)
24
25/// Constant equivalent to PostgreSQL 'infinity'::date, a date that is later
26/// than all other dates.
27/// https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-TABLE
28inline constexpr Date kDatePositiveInfinity = Date::SysDays::max();
29
30/// Constant equivalent to PostgreSQL '-infinity'::date, a date that is earlier
31/// than all other dates.
32/// https://www.postgresql.org/docs/current/datatype-datetime.html#DATATYPE-DATETIME-SPECIAL-TABLE
33inline constexpr Date kDateNegativeInfinity = Date::SysDays::min();
34
35namespace io {
36
37/// @brief Binary formatter for utils::datetime::Date
38template <>
39struct BufferFormatter<Date> {
40 const Date value;
41
42 explicit BufferFormatter(Date value)
43 : value{value}
44 {}
45
46 template <typename Buffer>
47 void operator()(const UserTypes& types, Buffer& buffer) {
48 static const auto kPgEpoch = PostgresEpochDate();
49 if (value == kDatePositiveInfinity) {
50 WriteBuffer(types, buffer, std::numeric_limits<Integer>::max());
51 } else if (value == kDateNegativeInfinity) {
52 WriteBuffer(types, buffer, std::numeric_limits<Integer>::min());
53 } else {
54 auto pg_days = static_cast<Integer>((value.GetSysDays() - kPgEpoch.GetSysDays()).count());
55 WriteBuffer(types, buffer, pg_days);
56 }
57 }
58};
59
60/// @brief Binary parser for utils::datetime::Date
61template <>
62struct BufferParser<Date> : detail::BufferParserBase<Date> {
63 using BaseType = detail::BufferParserBase<Date>;
64
65 using BaseType::BaseType;
66
67 void operator()(const FieldBuffer& buffer) {
68 static const auto kPgEpoch = PostgresEpochDate();
69 Integer pg_days{0};
70 ReadBuffer(buffer, pg_days);
71 if (pg_days == std::numeric_limits<Integer>::max()) {
72 this->value = kDatePositiveInfinity;
73 } else if (pg_days == std::numeric_limits<Integer>::min()) {
74 this->value = kDateNegativeInfinity;
75 } else {
76 this->value = kPgEpoch.GetSysDays() + Date::Days{pg_days};
77 }
78 }
79};
80
81template <>
82struct CppToSystemPg<Date> : PredefinedOid<PredefinedOids::kDate> {};
83
84} // namespace io
85} // namespace storages::postgres
86
87USERVER_NAMESPACE_END