mirror of
https://github.com/atuinsh/atuin.git
synced 2025-02-17 19:01:22 +01:00
wip
This commit is contained in:
parent
eadce83a57
commit
b99de3c4d7
@ -312,9 +312,8 @@ impl History {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use atuin_common::record::DecryptedData;
|
||||
use regex::RegexSet;
|
||||
use time::{macros::datetime, OffsetDateTime};
|
||||
use time::macros::datetime;
|
||||
|
||||
use crate::{history::HISTORY_VERSION, settings::Settings};
|
||||
|
||||
|
@ -151,11 +151,30 @@ impl KvStore {
|
||||
// use as a write-through cache to avoid constant rebuilds.
|
||||
pub async fn build_kv(
|
||||
&self,
|
||||
_store: &impl Store,
|
||||
_encryption_key: &[u8; 32],
|
||||
store: &impl Store,
|
||||
encryption_key: &[u8; 32],
|
||||
) -> Result<BTreeMap<String, BTreeMap<String, String>>> {
|
||||
let map = BTreeMap::new();
|
||||
// TODO: implement
|
||||
|
||||
// get the status of all stores
|
||||
let mut tagged = store.all_tagged(KV_TAG).await?;
|
||||
|
||||
// iterate through all tags and play each KV record at a time
|
||||
for (host, record) in tagged {
|
||||
let decrypted = match record.version.as_str() {
|
||||
KV_VERSION => record.decrypt::<PASETO_V4>(encryption_key)?,
|
||||
version => bail!("unknown version {version:?}"),
|
||||
};
|
||||
|
||||
let kv = KvRecord::deserialize(&decrypted.data, &decrypted.version)?;
|
||||
|
||||
let next = store.next(host, KV_TAG, decrypted.idx, 1).await?;
|
||||
|
||||
write a function that iterates the kv records in order and builds a map
|
||||
maybe next_record(tag) that returns the next of that tag in time, ignoring host?
|
||||
then write some tests for this new sync
|
||||
also see what happens if we run the new server but try and sync with v17 client. I imagine `atuin sync` breaks, but auto sync is fine. maybe version the api now.
|
||||
}
|
||||
|
||||
Ok(map)
|
||||
}
|
||||
|
@ -2,8 +2,8 @@
|
||||
// Multiple stores of multiple types are all stored in one chonky table (for now), and we just index
|
||||
// by tag/host
|
||||
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
use std::{collections::HashMap, path::Path};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use eyre::{eyre, Result};
|
||||
@ -190,7 +190,7 @@ impl Store for SqliteStore {
|
||||
) -> Result<Option<Record<EncryptedData>>> {
|
||||
let res = sqlx::query("select * from store where idx = ?1 and host = ?2 and tag = ?3")
|
||||
.bind(idx as i64)
|
||||
.bind(host)
|
||||
.bind(host.0.as_hyphenated().to_string())
|
||||
.bind(tag)
|
||||
.map(Self::query_row)
|
||||
.fetch_one(&self.pool)
|
||||
@ -227,14 +227,22 @@ impl Store for SqliteStore {
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
async fn all_tagged(&self, tag: &str) -> Result<Vec<Record<EncryptedData>>> {
|
||||
async fn all_tagged(&self, tag: &str) -> Result<HashMap<HostId, Record<EncryptedData>>> {
|
||||
let res = sqlx::query("select * from store where idx = 0 and tag = ?1")
|
||||
.bind(tag)
|
||||
.map(Self::query_row)
|
||||
.fetch_all(&self.pool)
|
||||
.await?;
|
||||
|
||||
Ok(res)
|
||||
let mut ret = HashMap::new();
|
||||
|
||||
for i in res {
|
||||
assert!(ret.get(&i.host.id).is_none());
|
||||
|
||||
ret.insert(i.host.id, i);
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
@ -307,6 +315,24 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn first() {
|
||||
let db = SqliteStore::new(":memory:").await.unwrap();
|
||||
let record = test_record();
|
||||
db.push(&record).await.unwrap();
|
||||
|
||||
let first = db
|
||||
.first(record.host.id, record.tag.as_str())
|
||||
.await
|
||||
.expect("failed to get store len");
|
||||
|
||||
assert_eq!(
|
||||
first.unwrap().id,
|
||||
record.id,
|
||||
"expected to get back the same record that was inserted"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn len() {
|
||||
let db = SqliteStore::new(":memory:").await.unwrap();
|
||||
|
@ -1,3 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use eyre::Result;
|
||||
|
||||
@ -48,5 +50,5 @@ pub trait Store {
|
||||
/// Get every start record for a given tag, regardless of host.
|
||||
/// Useful when actually operating on synchronized data, and will often have conflict
|
||||
/// resolution applied.
|
||||
async fn all_tagged(&self, tag: &str) -> Result<Vec<Record<EncryptedData>>>;
|
||||
async fn all_tagged(&self, tag: &str) -> Result<HashMap<HostId, Record<EncryptedData>>>;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use clap::Subcommand;
|
||||
use eyre::Result;
|
||||
|
||||
use atuin_client::{record::store::Store, settings::Settings};
|
||||
use time::OffsetDateTime;
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
#[command(infer_subcommands = true)]
|
||||
@ -19,7 +20,8 @@ impl Cmd {
|
||||
|
||||
let status = store.status().await?;
|
||||
|
||||
for (host, store) in &status.hosts {
|
||||
// TODO: should probs build some data structure and then pretty-print it or smth
|
||||
for (host, st) in &status.hosts {
|
||||
let host_string = if host == &host_id {
|
||||
format!("host: {} <- CURRENT HOST", host.0.as_hyphenated())
|
||||
} else {
|
||||
@ -28,8 +30,27 @@ impl Cmd {
|
||||
|
||||
println!("{host_string}");
|
||||
|
||||
for (tag, idx) in store {
|
||||
println!("\tstore: {tag} at {idx}");
|
||||
for (tag, idx) in st {
|
||||
println!("\tstore: {tag}");
|
||||
|
||||
let first = store.first(*host, tag).await?;
|
||||
let last = store.last(*host, tag).await?;
|
||||
|
||||
println!("\t\tidx: {idx}");
|
||||
|
||||
if let Some(first) = first {
|
||||
println!("\t\tfirst: {}", first.id.0.as_hyphenated().to_string());
|
||||
|
||||
let time = OffsetDateTime::from_unix_timestamp_nanos(first.timestamp as i128)?;
|
||||
println!("\t\t\tcreated: {}", time.to_string());
|
||||
}
|
||||
|
||||
if let Some(last) = last {
|
||||
println!("\t\tlast: {}", last.id.0.as_hyphenated().to_string());
|
||||
|
||||
let time = OffsetDateTime::from_unix_timestamp_nanos(last.timestamp as i128)?;
|
||||
println!("\t\t\tcreated: {:?}", time.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
println!();
|
||||
|
Loading…
Reference in New Issue
Block a user