Leosac  0.8.0
Open Source Access Control
STDTimePointODB.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #pragma once
21 
22 #include "tools/MyTime.hpp"
23 #include <cassert>
24 #include <chrono>
25 #include <date/date.h>
26 #include <iomanip>
27 #include <odb/pgsql/traits.hxx>
28 #include <odb/sqlite/traits.hxx>
29 
30 namespace odb
31 {
32 
33 // For PGSql
34 
35 namespace pgsql
36 {
44 template <>
45 class value_traits<std::chrono::system_clock::time_point, id_timestamp>
46 {
47  public:
48  using TimePoint = std::chrono::system_clock::time_point;
51  typedef long long image_type;
52 
53  // Could somewhat map to std::time_point::min()
54  static const long long neg_inf = -0x7fffffffffffffffLL - 1;
55 
56  // Could somewhat map to std::time_point::max()
57  static const long long pos_inf = 0x7fffffffffffffffLL;
58 
59  static void set_value(TimePoint &v, image_type i, bool is_null)
60  {
61  // We cannot (AFAIK) support null date time.
62  assert(!is_null);
63 
64  i = details::endian_traits::ntoh(i);
65  if (i == neg_inf)
66  v = TimePoint::min();
67  else if (i == pos_inf)
68  v = TimePoint::max();
69  else
70  {
71  // todo we probably need to check for overflow.
72  std::chrono::microseconds us(i);
73  TimePoint epoch = pg_epoch();
74  TimePoint ts = epoch + us;
75 
76  v = ts;
77  }
78  }
79 
80  static void set_image(image_type &i, bool &is_null, const TimePoint &v)
81  {
82  is_null = false;
83  if (v == TimePoint::max())
84  i = pos_inf;
85  else if (v == TimePoint::min())
86  i = neg_inf;
87  else
88  {
89  // todo we probably need to check for overflow.
90  TimePoint epoch = pg_epoch();
91  std::chrono::microseconds us =
92  std::chrono::duration_cast<std::chrono::microseconds>(v - epoch);
93  i = us.count();
94  }
95  i = details::endian_traits::hton(i);
96  }
97 
98  private:
103  {
104  TimePoint pg_epoch;
105  std::tm tm;
106  bzero(&tm, sizeof(tm));
107  std::string epoch = "2000-01-01T00:00:00Z";
108 
109  std::chrono::system_clock::time_point tp;
110  auto x = date::parse("%FT%T%Z", tp);
111  std::istringstream iss(epoch);
112  iss >> x;
113  return tp;
114  }
115 };
116 }
117 
118 
119 // For SQLite
120 
121 namespace sqlite
122 {
126 template <>
127 class value_traits<std::chrono::system_clock::time_point, id_text>
128 {
129  public:
130  using TimePoint = std::chrono::system_clock::time_point;
133  typedef details::buffer image_type;
134 
135  static constexpr const char *const TIME_POINT_MIN = "TIME_POINT_MIN";
136  static constexpr const char *const TIME_POINT_MAX = "TIME_POINT_MAX";
137 
138  static void set_value(TimePoint &v, const details::buffer &b, std::size_t n,
139  bool is_null)
140  {
141  assert(!is_null);
142  std::string str_rep(b.data(), n);
143 
144  if (str_rep == TIME_POINT_MAX)
145  v = TimePoint::max();
146  else if (str_rep == TIME_POINT_MIN)
147  v = TimePoint::min();
148  else
149  {
150  auto x = date::parse("%FT%T%z", v);
151  std::istringstream iss(str_rep);
152  iss >> x;
153  assert(iss.good());
154  }
155  }
156 
157  static void set_image(details::buffer &b, std::size_t &n, bool &is_null,
158  const TimePoint &v)
159  {
160  is_null = false;
161  std::string str_rep;
162 
163  if (v == TimePoint::max())
164  str_rep = TIME_POINT_MAX;
165  else if (v == TimePoint::min())
166  str_rep = TIME_POINT_MIN;
167  else
168  str_rep = date::format("%FT%T%z", v);
169 
170  n = str_rep.size();
171  if (str_rep.size() > b.capacity())
172  b.capacity(str_rep.length());
173  std::memcpy(b.data(), str_rep.data(), str_rep.length());
174  }
175 };
176 }
177 }
odb::pgsql::value_traits< std::chrono::system_clock::time_point, id_timestamp >::query_type
value_type query_type
Definition: STDTimePointODB.hpp:50
odb::sqlite::value_traits< std::chrono::system_clock::time_point, id_text >::image_type
details::buffer image_type
Definition: STDTimePointODB.hpp:133
odb::pgsql::value_traits< std::chrono::system_clock::time_point, id_timestamp >::image_type
long long image_type
Definition: STDTimePointODB.hpp:51
odb::sqlite::value_traits< std::chrono::system_clock::time_point, id_text >::value_type
TimePoint value_type
Definition: STDTimePointODB.hpp:131
odb
Provide ODB magic to be able to store an Leosac::Audit::EventType (FlagSet) object.
Definition: AuditEventMaskODB.hpp:31
odb::pgsql::value_traits< std::chrono::system_clock::time_point, id_timestamp >::set_image
static void set_image(image_type &i, bool &is_null, const TimePoint &v)
Definition: STDTimePointODB.hpp:80
odb::sqlite::value_traits< std::chrono::system_clock::time_point, id_text >::query_type
value_type query_type
Definition: STDTimePointODB.hpp:132
odb::sqlite::value_traits< std::chrono::system_clock::time_point, id_text >::set_value
static void set_value(TimePoint &v, const details::buffer &b, std::size_t n, bool is_null)
Definition: STDTimePointODB.hpp:138
odb::pgsql::value_traits< std::chrono::system_clock::time_point, id_timestamp >::set_value
static void set_value(TimePoint &v, image_type i, bool is_null)
Definition: STDTimePointODB.hpp:59
odb::pgsql::value_traits< std::chrono::system_clock::time_point, id_timestamp >::TimePoint
std::chrono::system_clock::time_point TimePoint
Definition: STDTimePointODB.hpp:48
odb::pgsql::value_traits< std::chrono::system_clock::time_point, id_timestamp >::value_type
TimePoint value_type
Definition: STDTimePointODB.hpp:49
Leosac::Colorize::detail::format
std::string format(const std::string &escape_code, const T &in)
Return a string containing the escape code, a string representation of T and the clear escape string.
Definition: Colorize.hpp:49
odb::sqlite::value_traits< std::chrono::system_clock::time_point, id_text >::TimePoint
std::chrono::system_clock::time_point TimePoint
Definition: STDTimePointODB.hpp:130
odb::pgsql::value_traits< std::chrono::system_clock::time_point, id_timestamp >::pg_epoch
static TimePoint pg_epoch()
Return a timepoint that represents the PGSQL TIMESTAMP epoch.
Definition: STDTimePointODB.hpp:102
MyTime.hpp
odb::sqlite::value_traits< std::chrono::system_clock::time_point, id_text >::set_image
static void set_image(details::buffer &b, std::size_t &n, bool &is_null, const TimePoint &v)
Definition: STDTimePointODB.hpp:157