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) : value{value} {}
43
44 template <typename Buffer>
45 void operator()(const UserTypes& types, Buffer& buffer) {
46 static const auto kPgEpoch = PostgresEpochDate();
47 if (value == kDatePositiveInfinity) {
48 WriteBuffer(types, buffer, std::numeric_limits<Integer>::max());
49 } else if (value == kDateNegativeInfinity) {
50 WriteBuffer(types, buffer, std::numeric_limits<Integer>::min());
51 } else {
52 auto pg_days = static_cast<Integer>((value.GetSysDays() - kPgEpoch.GetSysDays()).count());
53 WriteBuffer(types, buffer, pg_days);
54 }
55 }
56};
57
58/// @brief Binary parser for utils::datetime::Date
59template <>
60struct BufferParser<Date> : detail::BufferParserBase<Date> {
61 using BaseType = detail::BufferParserBase<Date>;
62
63 using BaseType::BaseType;
64
65 void operator()(const FieldBuffer& buffer) {
66 static const auto kPgEpoch = PostgresEpochDate();
67 Integer pg_days{0};
68 ReadBuffer(buffer, pg_days);
69 if (pg_days == std::numeric_limits<Integer>::max()) {
70 this->value = kDatePositiveInfinity;
71 } else if (pg_days == std::numeric_limits<Integer>::min()) {
72 this->value = kDateNegativeInfinity;
73 } else {
74 this->value = kPgEpoch.GetSysDays() + Date::Days{pg_days};
75 }
76 }
77};
78
79template <>
80struct CppToSystemPg<Date> : PredefinedOid<PredefinedOids::kDate> {};
81
82} // namespace io
83} // namespace storages::postgres
84
85USERVER_NAMESPACE_END