mirror of
https://github.com/atuinsh/atuin.git
synced 2024-11-29 11:44:44 +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 history;
|
||||||
pub mod import;
|
pub mod import;
|
||||||
pub mod ordering;
|
pub mod ordering;
|
||||||
|
pub mod record;
|
||||||
pub mod settings;
|
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)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
pub mod api;
|
pub mod api;
|
||||||
|
pub mod record;
|
||||||
pub mod utils;
|
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