From ae1709dafd22ac3c64441472e90df8799253292e Mon Sep 17 00:00:00 2001 From: Ellie Huxtable Date: Wed, 14 Jun 2023 21:18:24 +0100 Subject: Key values (#1038) * wip * Start testing * Store host IDs, not hostnames Why? Hostnames can change a lot, and therefore host filtering can be funky. Really, all we want is a unique ID per machine + do not care what it might be. * Mostly just write a fuckload of tests * Add a v0 kv store I can push to * Appending works * Add next() and iterate, test the pointer chain * Fix sig * Make clippy happy and thaw the ICE * Fix tests' * Fix tests * typed builder and cleaner db trait --------- Co-authored-by: Conrad Ludgate --- atuin-common/src/lib.rs | 1 + atuin-common/src/record.rs | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 atuin-common/src/record.rs (limited to 'atuin-common/src') diff --git a/atuin-common/src/lib.rs b/atuin-common/src/lib.rs index e76a7abb..b332e234 100644 --- a/atuin-common/src/lib.rs +++ b/atuin-common/src/lib.rs @@ -1,4 +1,5 @@ #![forbid(unsafe_code)] pub mod api; +pub mod record; pub mod utils; diff --git a/atuin-common/src/record.rs b/atuin-common/src/record.rs new file mode 100644 index 00000000..1fb60e55 --- /dev/null +++ b/atuin-common/src/record.rs @@ -0,0 +1,49 @@ +use serde::{Deserialize, Serialize}; +use typed_builder::TypedBuilder; + +/// A single record stored inside of our local database +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, TypedBuilder)] +pub struct Record { + /// a unique ID + #[builder(default = crate::utils::uuid_v7().as_simple().to_string())] + pub id: String, + + /// The unique ID of the host. + // TODO(ellie): Optimize the storage here. We use a bunch of IDs, and currently store + // as strings. I would rather avoid normalization, so store as UUID binary instead of + // encoding to a string and wasting much more storage. + pub host: String, + + /// The ID of the parent entry + // A store is technically just a double linked list + // We can do some cheating with the timestamps, but should not rely upon them. + // Clocks are tricksy. + #[builder(default)] + pub parent: Option, + + /// The creation time in nanoseconds since unix epoch + #[builder(default = chrono::Utc::now().timestamp_nanos() as u64)] + pub timestamp: u64, + + /// The version the data in the entry conforms to + // However we want to track versions for this tag, eg v2 + pub version: String, + + /// The type of data we are storing here. Eg, "history" + pub tag: String, + + /// Some data. This can be anything you wish to store. Use the tag field to know how to handle it. + pub data: Vec, +} + +impl Record { + pub fn new_child(&self, data: Vec) -> Record { + Record::builder() + .host(self.host.clone()) + .version(self.version.clone()) + .parent(Some(self.id.clone())) + .tag(self.tag.clone()) + .data(data) + .build() + } +} -- cgit v1.3.1