types: unify all epoch timestamps to i64
All epoch timestamp fields (timestamp, last_replayed, created_at on nodes; timestamp on relations) are now i64. Previously a mix of f64 and i64 which caused type seams and required unnecessary casts. - Kill now_epoch() -> f64 and now_epoch_i64(), replace with single now_epoch() -> i64 - All formatting functions take i64 - new_node() sets created_at automatically - journal-ts-migrate handles all nodes, with valid_range check to detect garbage from f64->i64 bit reinterpretation - capnp schema: Float64 -> Int64 for all timestamp fields
This commit is contained in:
parent
b4bbafdf1c
commit
4747004b36
4 changed files with 232 additions and 56 deletions
|
|
@ -120,18 +120,18 @@ impl StoreLock {
|
|||
// Lock released automatically when _file is dropped (flock semantics)
|
||||
}
|
||||
|
||||
pub fn now_epoch() -> f64 {
|
||||
pub fn now_epoch() -> i64 {
|
||||
SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs_f64()
|
||||
.as_secs() as i64
|
||||
}
|
||||
|
||||
/// Convert epoch seconds to broken-down local time components.
|
||||
/// Returns (year, month, day, hour, minute, second).
|
||||
pub fn epoch_to_local(epoch: f64) -> (i32, u32, u32, u32, u32, u32) {
|
||||
pub fn epoch_to_local(epoch: i64) -> (i32, u32, u32, u32, u32, u32) {
|
||||
use chrono::{Datelike, Local, TimeZone, Timelike};
|
||||
let dt = Local.timestamp_opt(epoch as i64, 0).unwrap();
|
||||
let dt = Local.timestamp_opt(epoch, 0).unwrap();
|
||||
(
|
||||
dt.year(),
|
||||
dt.month(),
|
||||
|
|
@ -143,19 +143,19 @@ pub fn epoch_to_local(epoch: f64) -> (i32, u32, u32, u32, u32, u32) {
|
|||
}
|
||||
|
||||
/// Format epoch as "YYYY-MM-DD"
|
||||
pub fn format_date(epoch: f64) -> String {
|
||||
pub fn format_date(epoch: i64) -> String {
|
||||
let (y, m, d, _, _, _) = epoch_to_local(epoch);
|
||||
format!("{:04}-{:02}-{:02}", y, m, d)
|
||||
}
|
||||
|
||||
/// Format epoch as "YYYY-MM-DDTHH:MM"
|
||||
pub fn format_datetime(epoch: f64) -> String {
|
||||
pub fn format_datetime(epoch: i64) -> String {
|
||||
let (y, m, d, h, min, _) = epoch_to_local(epoch);
|
||||
format!("{:04}-{:02}-{:02}T{:02}:{:02}", y, m, d, h, min)
|
||||
}
|
||||
|
||||
/// Format epoch as "YYYY-MM-DD HH:MM"
|
||||
pub fn format_datetime_space(epoch: f64) -> String {
|
||||
pub fn format_datetime_space(epoch: i64) -> String {
|
||||
let (y, m, d, h, min, _) = epoch_to_local(epoch);
|
||||
format!("{:04}-{:02}-{:02} {:02}:{:02}", y, m, d, h, min)
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ pub fn today() -> String {
|
|||
pub struct Node {
|
||||
pub uuid: [u8; 16],
|
||||
pub version: u32,
|
||||
pub timestamp: f64,
|
||||
pub timestamp: i64,
|
||||
pub node_type: NodeType,
|
||||
pub provenance: Provenance,
|
||||
pub key: String,
|
||||
|
|
@ -185,13 +185,18 @@ pub struct Node {
|
|||
pub uses: u32,
|
||||
pub wrongs: u32,
|
||||
pub state_tag: String,
|
||||
pub last_replayed: f64,
|
||||
pub last_replayed: i64,
|
||||
pub spaced_repetition_interval: u32,
|
||||
|
||||
// Position within file (section index, for export ordering)
|
||||
#[serde(default)]
|
||||
pub position: u32,
|
||||
|
||||
// Stable creation timestamp (unix epoch seconds). Set once at creation;
|
||||
// never updated on rename or content update. Zero for legacy nodes.
|
||||
#[serde(default)]
|
||||
pub created_at: i64,
|
||||
|
||||
// Derived fields (not in capnp, computed from graph)
|
||||
#[serde(default)]
|
||||
pub community_id: Option<u32>,
|
||||
|
|
@ -206,7 +211,7 @@ pub struct Node {
|
|||
pub struct Relation {
|
||||
pub uuid: [u8; 16],
|
||||
pub version: u32,
|
||||
pub timestamp: f64,
|
||||
pub timestamp: i64,
|
||||
pub source: [u8; 16],
|
||||
pub target: [u8; 16],
|
||||
pub rel_type: RelationType,
|
||||
|
|
@ -306,7 +311,7 @@ capnp_message!(Node,
|
|||
uuid: [uuid],
|
||||
prim: [version, timestamp, weight, emotion, deleted,
|
||||
retrievals, uses, wrongs, last_replayed,
|
||||
spaced_repetition_interval, position],
|
||||
spaced_repetition_interval, position, created_at],
|
||||
enm: [node_type: NodeType, provenance: Provenance, category: Category],
|
||||
skip: [community_id, clustering_coefficient, degree],
|
||||
);
|
||||
|
|
@ -444,9 +449,10 @@ pub fn new_node(key: &str, content: &str) -> Node {
|
|||
uses: 0,
|
||||
wrongs: 0,
|
||||
state_tag: String::new(),
|
||||
last_replayed: 0.0,
|
||||
last_replayed: 0,
|
||||
spaced_repetition_interval: 1,
|
||||
position: 0,
|
||||
created_at: now_epoch(),
|
||||
community_id: None,
|
||||
clustering_coefficient: None,
|
||||
degree: None,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue