mirror of
https://github.com/atuinsh/atuin.git
synced 2024-11-25 17:54:55 +01:00
wip
This commit is contained in:
parent
f499ae84ed
commit
5e79c02f78
@ -0,0 +1,10 @@
|
||||
-- Add migration script here
|
||||
create table if not exists records (
|
||||
id text primary key,
|
||||
host text not null,
|
||||
timestamp integer not null,
|
||||
|
||||
tag text not null,
|
||||
version text not null,
|
||||
data blob not null,
|
||||
);
|
@ -14,4 +14,5 @@ pub mod database;
|
||||
pub mod history;
|
||||
pub mod import;
|
||||
pub mod ordering;
|
||||
pub mod record;
|
||||
pub mod settings;
|
||||
|
2
atuin-client/src/record/mod.rs
Normal file
2
atuin-client/src/record/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod sqlite_store;
|
||||
pub mod store;
|
70
atuin-client/src/record/sqlite_store.rs
Normal file
70
atuin-client/src/record/sqlite_store.rs
Normal file
@ -0,0 +1,70 @@
|
||||
// Here we are using sqlite as a pretty dumb store, and will not be running any complex queries.
|
||||
// Multiple stores of multiple types are all stored in one chonky table (for now), and we just index
|
||||
// by tag/host
|
||||
|
||||
yo tomorrow morning me
|
||||
drink that coffee
|
||||
then wrap up this interface
|
||||
|
||||
you will need to
|
||||
- make sure the records use string IDs
|
||||
- add the version in
|
||||
- write some tests with a memory sqlite
|
||||
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use fs_err as fs;
|
||||
use sqlx::{
|
||||
sqlite::{SqliteConnectOptions, SqliteJournalMode, SqlitePool, SqlitePoolOptions, SqliteRow},
|
||||
Result, Row,
|
||||
};
|
||||
|
||||
use atuin_common::record::Record;
|
||||
|
||||
use super::store::Store;
|
||||
|
||||
pub struct SqliteStore {
|
||||
pool: SqlitePool,
|
||||
}
|
||||
|
||||
impl SqliteStore {
|
||||
pub async fn new(path: impl AsRef<Path>) -> Result<Self> {
|
||||
let path = path.as_ref();
|
||||
|
||||
debug!("opening sqlite database at {:?}", path);
|
||||
|
||||
let create = !path.exists();
|
||||
if create {
|
||||
if let Some(dir) = path.parent() {
|
||||
fs::create_dir_all(dir)?;
|
||||
}
|
||||
}
|
||||
|
||||
let opts = SqliteConnectOptions::from_str(path.as_os_str().to_str().unwrap())?
|
||||
.journal_mode(SqliteJournalMode::Wal)
|
||||
.create_if_missing(true);
|
||||
|
||||
let pool = SqlitePoolOptions::new().connect_with(opts).await?;
|
||||
|
||||
Self::setup_db(&pool).await?;
|
||||
|
||||
Ok(Self { pool })
|
||||
}
|
||||
|
||||
async fn setup_db(pool: &SqlitePool) -> Result<()> {
|
||||
debug!("running sqlite database setup");
|
||||
|
||||
sqlx::migrate!("./record-migrations").run(pool).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Store for SqliteStore {
|
||||
async fn push(record: Record) -> Result<Record> {
|
||||
Ok(record)
|
||||
}
|
||||
}
|
15
atuin-client/src/record/store.rs
Normal file
15
atuin-client/src/record/store.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use async_trait::async_trait;
|
||||
use eyre::Result;
|
||||
|
||||
use atuin_common::record::Record;
|
||||
|
||||
/// A record store stores records
|
||||
/// In more detail - we tend to need to process this into _another_ format to actually query it.
|
||||
/// As is, the record store is intended as the source of truth for arbitratry data, which could
|
||||
/// be shell history, kvs, etc.
|
||||
#[async_trait]
|
||||
pub trait Store {
|
||||
async fn push(record: Record) -> Result<Record>;
|
||||
async fn get(id: String) -> Result<Record>;
|
||||
async fn len(host: String, tag: String) -> Result<usize>;
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
pub mod api;
|
||||
pub mod record;
|
||||
pub mod utils;
|
||||
|
15
atuin-common/src/record.rs
Normal file
15
atuin-common/src/record.rs
Normal file
@ -0,0 +1,15 @@
|
||||
/// A single record stored inside of our local database
|
||||
pub struct Record {
|
||||
pub id: i64,
|
||||
|
||||
pub host: String,
|
||||
|
||||
pub timestamp: u64,
|
||||
|
||||
/// The type of data we are storing here. It is probably useful to also
|
||||
/// include some sort of version. For example, history.v2
|
||||
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<u8>,
|
||||
}
|
Loading…
Reference in New Issue
Block a user