Move 'now' into core, implement microsecond truncation.

This is so we don't return a more granular -- and thus subtly different --
timestamp in a TxReport than we put into the store.
This commit is contained in:
Richard Newman 2018-01-29 16:37:36 -08:00
parent 55d196094a
commit a8dcad65da
3 changed files with 25 additions and 14 deletions

View file

@ -233,6 +233,28 @@ impl TypedValue {
} }
} }
trait MicrosecondPrecision {
/// Truncate the provided `DateTime` to microsecond precision.
fn microsecond_precision(self) -> Self;
}
impl MicrosecondPrecision for DateTime<Utc> {
fn microsecond_precision(self) -> DateTime<Utc> {
let nanoseconds = self.nanosecond();
if nanoseconds % 1000 == 0 {
return self;
}
let microseconds = nanoseconds / 1000;
let truncated = microseconds * 1000;
self.with_nanosecond(truncated).expect("valid timestamp")
}
}
/// Return the current time as a UTC `DateTime` instance with microsecond precision.
pub fn now() -> DateTime<Utc> {
Utc::now().microsecond_precision()
}
// We don't do From<i64> or From<Entid> 'cos it's ambiguous. // We don't do From<i64> or From<Entid> 'cos it's ambiguous.
impl From<bool> for TypedValue { impl From<bool> for TypedValue {
@ -245,9 +267,7 @@ impl From<bool> for TypedValue {
/// `TypedValue::Instant`. /// `TypedValue::Instant`.
impl From<DateTime<Utc>> for TypedValue { impl From<DateTime<Utc>> for TypedValue {
fn from(value: DateTime<Utc>) -> TypedValue { fn from(value: DateTime<Utc>) -> TypedValue {
let microseconds = value.nanosecond() / 1000; TypedValue::Instant(value.microsecond_precision())
let truncated = microseconds * 1000;
TypedValue::Instant(value.with_nanosecond(truncated).expect("valid timestamp"))
} }
} }

View file

@ -28,11 +28,6 @@ use std::iter::repeat;
use itertools::Itertools; use itertools::Itertools;
use mentat_core::{
DateTime,
Utc,
};
pub use errors::{Error, ErrorKind, ResultExt, Result}; pub use errors::{Error, ErrorKind, ResultExt, Result};
pub mod db; pub mod db;
@ -116,8 +111,3 @@ pub fn repeat_values(values_per_tuple: usize, tuples: usize) -> String {
let values: String = repeat(inner).take(tuples).join(", "); let values: String = repeat(inner).take(tuples).join(", ");
values values
} }
/// Return the current time as a UTC `DateTime` instance.
pub fn now() -> DateTime<Utc> {
Utc::now()
}

View file

@ -85,6 +85,7 @@ use mentat_core::{
Schema, Schema,
Utc, Utc,
attribute, attribute,
now,
}; };
use mentat_core::intern_set::InternSet; use mentat_core::intern_set::InternSet;
@ -654,7 +655,7 @@ impl<'conn, 'a> Tx<'conn, 'a> {
} }
} }
tx_instant = self.tx_instant.unwrap_or(::now()); tx_instant = self.tx_instant.unwrap_or_else(now);
// Transact [:db/add :db/txInstant NOW :db/tx] if it doesn't exist. // Transact [:db/add :db/txInstant NOW :db/tx] if it doesn't exist.
if self.tx_instant == None { if self.tx_instant == None {