use newtypes for distinguishing between second and millisecond stamps

This commit is contained in:
Damien Elmes 2020-03-26 12:59:51 +10:00
parent 65b8988817
commit eb89a2db3f
7 changed files with 71 additions and 16 deletions

View file

@ -28,5 +28,5 @@ pub mod storage;
pub mod template;
pub mod template_filters;
pub mod text;
pub mod time;
pub mod timestamp;
pub mod types;

View file

@ -5,10 +5,10 @@
/// the media DB check.
use crate::err::{AnkiError, DBErrorKind, Result};
use crate::text::strip_html_preserving_image_filenames;
use crate::time::i64_unix_secs;
use crate::timestamp::TimestampSecs;
use crate::{
notetypes::NoteType,
types::{ObjID, Timestamp, Usn},
types::{ObjID, Usn},
};
use rusqlite::{params, Connection, Row, NO_PARAMS};
use std::convert::TryInto;
@ -17,7 +17,7 @@ use std::convert::TryInto;
pub(super) struct Note {
pub id: ObjID,
pub mid: ObjID,
pub mtime_secs: Timestamp,
pub mtime: TimestampSecs,
pub usn: Usn,
fields: Vec<String>,
}
@ -73,7 +73,7 @@ fn row_to_note(row: &Row) -> Result<Note> {
Ok(Note {
id: row.get(0)?,
mid: row.get(1)?,
mtime_secs: row.get(2)?,
mtime: row.get(2)?,
usn: row.get(3)?,
fields: row
.get_raw(4)
@ -85,7 +85,7 @@ fn row_to_note(row: &Row) -> Result<Note> {
}
pub(super) fn set_note(db: &Connection, note: &mut Note, note_type: &NoteType) -> Result<()> {
note.mtime_secs = i64_unix_secs();
note.mtime = TimestampSecs::now();
// hard-coded for now
note.usn = -1;
let field1_nohtml = strip_html_preserving_image_filenames(&note.fields()[0]);
@ -106,7 +106,7 @@ pub(super) fn set_note(db: &Connection, note: &mut Note, note_type: &NoteType) -
let mut stmt =
db.prepare_cached("update notes set mod=?,usn=?,flds=?,sfld=?,csum=? where id=?")?;
stmt.execute(params![
note.mtime_secs,
note.mtime,
note.usn,
note.fields().join("\x1f"),
sort_field,

View file

@ -1,3 +1,4 @@
mod sqlite;
mod timestamp;
pub(crate) use sqlite::{SqliteStorage, StorageContext};

View file

@ -5,7 +5,7 @@ use crate::collection::CollectionOp;
use crate::config::Config;
use crate::err::Result;
use crate::err::{AnkiError, DBErrorKind};
use crate::time::{i64_unix_millis, i64_unix_secs};
use crate::timestamp::{TimestampMillis, TimestampSecs};
use crate::{
decks::Deck,
notetypes::NoteType,
@ -168,7 +168,10 @@ impl SqliteStorage {
if create {
db.prepare_cached("begin exclusive")?.execute(NO_PARAMS)?;
db.execute_batch(include_str!("schema11.sql"))?;
db.execute("update col set crt=?, ver=?", params![i64_unix_secs(), ver])?;
db.execute(
"update col set crt=?, ver=?",
params![TimestampSecs::now(), ver],
)?;
db.prepare_cached("commit")?.execute(NO_PARAMS)?;
} else {
if ver > SCHEMA_MAX_VERSION {
@ -278,7 +281,7 @@ impl StorageContext<'_> {
pub(crate) fn mark_modified(&self) -> Result<()> {
self.db
.prepare_cached("update col set mod=?")?
.execute(params![i64_unix_millis()])?;
.execute(params![TimestampMillis::now()])?;
Ok(())
}
@ -339,7 +342,7 @@ impl StorageContext<'_> {
self.timing_today = Some(sched_timing_today(
crt,
i64_unix_secs(),
TimestampSecs::now().0,
conf.creation_offset,
now_offset,
conf.rollover,

View file

@ -0,0 +1,40 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
use crate::timestamp::{TimestampMillis, TimestampSecs};
use rusqlite::{
types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef},
ToSql,
};
impl FromSql for TimestampSecs {
fn column_result(value: ValueRef<'_>) -> std::result::Result<Self, FromSqlError> {
if let ValueRef::Integer(i) = value {
Ok(TimestampSecs(i))
} else {
Err(FromSqlError::InvalidType)
}
}
}
impl ToSql for TimestampSecs {
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
Ok(ToSqlOutput::Owned(Value::Integer(self.0)))
}
}
impl FromSql for TimestampMillis {
fn column_result(value: ValueRef<'_>) -> std::result::Result<Self, FromSqlError> {
if let ValueRef::Integer(i) = value {
Ok(TimestampMillis(i))
} else {
Err(FromSqlError::InvalidType)
}
}
}
impl ToSql for TimestampMillis {
fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
Ok(ToSqlOutput::Owned(Value::Integer(self.0)))
}
}

View file

@ -3,12 +3,24 @@
use std::time;
pub(crate) fn i64_unix_secs() -> i64 {
elapsed().as_secs() as i64
#[repr(transparent)]
#[derive(Debug, Clone)]
pub struct TimestampSecs(pub i64);
impl TimestampSecs {
pub fn now() -> Self {
Self(elapsed().as_secs() as i64)
}
}
pub(crate) fn i64_unix_millis() -> i64 {
elapsed().as_millis() as i64
#[repr(transparent)]
#[derive(Debug, Clone)]
pub struct TimestampMillis(pub i64);
impl TimestampMillis {
pub fn now() -> Self {
Self(elapsed().as_millis() as i64)
}
}
#[cfg(not(test))]

View file

@ -6,4 +6,3 @@
pub type ObjID = i64;
pub type Usn = i32;
pub type Timestamp = i64;