aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2015-12-16 18:18:22 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2015-12-17 14:13:45 +0200
commit25933a55455b2a0927769b29d06e3b2779e3efb6 (patch)
tree767385d94932033ed4bf0e46d58159518b66e596
parent1d8aef3dc44cb4e793a3c69426cd726e0ba622db (diff)
Bugfix: accuracy loss in ODB mapping for butl:timestamp
-rw-r--r--brep/package24
1 files changed, 20 insertions, 4 deletions
diff --git a/brep/package b/brep/package
index 056e2a8..8a9dcb2 100644
--- a/brep/package
+++ b/brep/package
@@ -6,8 +6,10 @@
#define BREP_PACKAGE
#include <map>
+#include <ratio>
#include <chrono>
-#include <iosfwd> // ostream
+#include <iosfwd> // ostream
+#include <type_traits> // static_assert
#include <odb/core.hxx>
#include <odb/forward.hxx> // database
@@ -90,9 +92,23 @@ namespace brep
#pragma db map type(dir_path) as(string) \
to((?).string ()) from(brep::dir_path (?))
- #pragma db map type(timestamp) as(uint64_t) \
- to(std::chrono::system_clock::to_time_t (?)) \
- from(std::chrono::system_clock::from_time_t (?))
+ // Ensure that timestamp can be represented in nonoseconds without loss of
+ // accuracy, so the following ODB mapping is adequate.
+ //
+ static_assert(
+ std::ratio_greater_equal<timestamp::period,
+ std::chrono::nanoseconds::period>::value,
+ "The following timestamp ODB mapping is invalid");
+
+ // As it pointed out in butl/timestamp we will overflow in year 2262 but
+ // by that time some larger basic type will be available for mapping.
+ //
+ #pragma db map type(timestamp) as(uint64_t) \
+ to(std::chrono::duration_cast<std::chrono::nanoseconds> ( \
+ (?).time_since_epoch ()).count ()) \
+ from(brep::timestamp ( \
+ std::chrono::duration_cast<brep::timestamp::duration> ( \
+ std::chrono::nanoseconds (?))))
// version
//