From b6e55b40fb899d7784cecdc2440be2c51311cb3a Mon Sep 17 00:00:00 2001 From: Nicole Tietz-Sokolskaya Date: Thu, 30 May 2024 22:24:04 -0400 Subject: [PATCH] Backup where I am --- src/store.rs | 147 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 117 insertions(+), 30 deletions(-) diff --git a/src/store.rs b/src/store.rs index 9826c2f..e1651bd 100644 --- a/src/store.rs +++ b/src/store.rs @@ -1,89 +1,176 @@ -use std::{collections::{HashMap, HashSet}, path::Path, sync::Arc}; +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(&Item) -> bool; -pub trait Map = Fn(&Item) -> T; +pub trait Filter = Fn(&Row) -> bool; +pub trait Map = Fn(&Row) -> T; -pub enum Item { +pub enum Row { Project(Box), Document(Box), + //User(Box), } #[derive(Clone, Debug, Eq, Hash, PartialEq)] -pub struct ItemId(Uuid); +pub struct RowId(Uuid); +// supports comparison operators #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct IndexId(String); -pub type Index = HashSet; +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct IndexValue(String); + +pub enum Index { + BTree(BTreeMap>), + Unique(HashMap), +} pub struct Store { - items: HashMap>, + rows: HashMap>, indexes: HashMap, keyspace: fjall::Keyspace, - persistent_items: fjall::PartitionHandle, + data_partition: fjall::PartitionHandle, + permissions_partition: fjall::PartitionHandle, } impl Store { pub fn new>(path: P) -> Result { - let items = HashMap::new(); + 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 persistent_items = - keyspace.open_partition("items", fjall::PartitionCreateOptions::default())?; + let data_partition = + keyspace.open_partition("data", fjall::PartitionCreateOptions::default())?; + let permissions_partition = + keyspace.open_partition("permissions", fjall::PartitionCreateOptions::default())?; Ok(Store { - items, + rows, indexes, keyspace, - persistent_items, + data_partition, + permissions_partition, }) } - pub fn set(&mut self, _item: &Item) -> Result<()> { + 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: ItemId) -> Option> { - self.items.get(&id).cloned() + pub fn get(&self, id: RowId) -> Option> { + 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, +} + +impl Query { + pub fn new() -> Query { + Query { + operations: Vec::new(), + } } - pub fn filter(&self, _filter: F) -> Result> { - todo!() + pub fn all(&mut self) -> &mut Self { + self.operations.push(QueryOperation::All); + self } - pub fn map>(&self, _transform: M) -> Result> { + /// 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!() } } -// TODO: can filter and map be done in terms of an iterator? -// like, the real Rust iterator trait? +/// The results of a Query, this will contain the concrete Rows which have been +/// retrieved. +pub struct QuerySet {} - -pub struct QuerySet { - indexes: Vec, // TODO: but use a ref, once this is figured out - -} - -impl QuerySet { -} +impl QuerySet {} impl Iterator for QuerySet { - type Item = Item; + type Item = Row; fn next(&mut self) -> Option { todo!() } } + +// How I'd like to do queries: +// +// store.query().via(OnlyProjects). +// +// +//