176 lines
3.9 KiB
Rust
176 lines
3.9 KiB
Rust
use std::{
|
|
collections::{BTreeMap, HashMap, HashSet},
|
|
path::Path,
|
|
sync::Arc,
|
|
};
|
|
|
|
use anyhow::Result;
|
|
use uuid::Uuid;
|
|
|
|
use crate::models::{Document, Project};
|
|
|
|
pub trait Filter = Fn(&Row) -> bool;
|
|
pub trait Map<T> = Fn(&Row) -> T;
|
|
|
|
pub enum Row {
|
|
Project(Box<Project>),
|
|
Document(Box<Document>),
|
|
//User(Box<User>),
|
|
}
|
|
|
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
|
pub struct RowId(Uuid);
|
|
|
|
// supports comparison operators
|
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
|
pub struct IndexId(String);
|
|
|
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
|
pub struct IndexValue(String);
|
|
|
|
pub enum Index {
|
|
BTree(BTreeMap<IndexValue, HashSet<RowId>>),
|
|
Unique(HashMap<IndexValue, RowId>),
|
|
}
|
|
|
|
pub struct Store {
|
|
rows: HashMap<RowId, Arc<Row>>,
|
|
indexes: HashMap<IndexId, Index>,
|
|
|
|
keyspace: fjall::Keyspace,
|
|
data_partition: fjall::PartitionHandle,
|
|
permissions_partition: fjall::PartitionHandle,
|
|
}
|
|
|
|
impl Store {
|
|
pub fn new<P: AsRef<Path>>(path: P) -> Result<Store> {
|
|
let rows = HashMap::new();
|
|
let indexes = HashMap::new();
|
|
|
|
let kv_config = fjall::Config::new(path)
|
|
.flush_workers(4)
|
|
.compaction_workers(4);
|
|
let keyspace = fjall::Keyspace::open(kv_config)?;
|
|
let data_partition =
|
|
keyspace.open_partition("data", fjall::PartitionCreateOptions::default())?;
|
|
let permissions_partition =
|
|
keyspace.open_partition("permissions", fjall::PartitionCreateOptions::default())?;
|
|
|
|
Ok(Store {
|
|
rows,
|
|
indexes,
|
|
keyspace,
|
|
data_partition,
|
|
permissions_partition,
|
|
})
|
|
}
|
|
|
|
pub fn set(&mut self, _item: &Row) -> Result<()> {
|
|
todo!()
|
|
}
|
|
|
|
/// Retrieves an item from the store by id. This is always an in-memory
|
|
/// operation and cannot fail.
|
|
pub fn get(&self, id: RowId) -> Option<Arc<Row>> {
|
|
self.rows.get(&id).cloned()
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
|
pub struct Comparison {
|
|
index: IndexId,
|
|
value: IndexValue,
|
|
operator: ComparisonOperator,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
|
pub enum ComparisonOperator {
|
|
Eq,
|
|
Gt,
|
|
Gte,
|
|
Lt,
|
|
Lte,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
|
pub enum QueryOperation {
|
|
All,
|
|
Where(Comparison),
|
|
Limit(usize),
|
|
Offset(usize),
|
|
OrderBy(IndexId),
|
|
}
|
|
|
|
/// Describes a set of operations to query for data in the database. To read the
|
|
/// data, this gets transformed into a QuerySet, which contains the results.
|
|
pub struct Query {
|
|
operations: Vec<QueryOperation>,
|
|
}
|
|
|
|
impl Query {
|
|
pub fn new() -> Query {
|
|
Query {
|
|
operations: Vec::new(),
|
|
}
|
|
}
|
|
|
|
pub fn all(&mut self) -> &mut Self {
|
|
self.operations.push(QueryOperation::All);
|
|
self
|
|
}
|
|
|
|
/// Filters down the set of rows via comparison operators
|
|
pub fn restrict(
|
|
&mut self,
|
|
index: IndexId,
|
|
value: IndexValue,
|
|
operator: ComparisonOperator,
|
|
) -> &mut Self {
|
|
self.operations.push(QueryOperation::Where(Comparison {
|
|
index,
|
|
value,
|
|
operator,
|
|
}));
|
|
self
|
|
}
|
|
|
|
pub fn limit(&mut self, limit: usize) -> &mut Self {
|
|
self.operations.push(QueryOperation::Limit(limit));
|
|
self
|
|
}
|
|
|
|
pub fn offset(&mut self, offset: usize) -> &mut Self {
|
|
self.operations.push(QueryOperation::Offset(offset));
|
|
self
|
|
}
|
|
|
|
pub fn order_by(&mut self, index: IndexId) -> &mut Self {
|
|
self.operations.push(QueryOperation::OrderBy(index));
|
|
self
|
|
}
|
|
|
|
pub fn execute(&self) -> QuerySet {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
/// The results of a Query, this will contain the concrete Rows which have been
|
|
/// retrieved.
|
|
pub struct QuerySet {}
|
|
|
|
impl QuerySet {}
|
|
|
|
impl Iterator for QuerySet {
|
|
type Item = Row;
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
// How I'd like to do queries:
|
|
//
|
|
// store.query().via(OnlyProjects).
|
|
//
|
|
//
|
|
//
|