in memory store

This commit is contained in:
tezlm 2024-02-10 19:13:29 -08:00
parent 7c2575990e
commit 79748b7074
Signed by: tezlm
GPG key ID: 649733FCD94AFBBA
5 changed files with 106 additions and 6 deletions

View file

@ -10,7 +10,7 @@ use std::{collections::HashMap, fmt::Debug};
use crate::event::EventId;
#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq)]
// TODO: actually implement Text
pub struct Text(pub String);
@ -75,12 +75,12 @@ pub struct IndexConfig {
pub column: String,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct TableRow {
pub values: HashMap<String, ColumnValue>,
}
#[derive(Debug)]
#[derive(Debug, Clone, PartialEq)]
pub enum ColumnValue {
/// An arbitrary utf8 string
String(String),
@ -154,7 +154,7 @@ pub trait Table {
/// Insert a row. Should only be called by the resolver
// TODO: enforce by types/traits
fn insert(&self, row: TableRow) -> Result<(), Self::Err>;
fn insert(&mut self, row: TableRow) -> Result<(), Self::Err>;
// fn insert_bulk(&self, rows: Vec<TableRow>) -> Result<(), Self::Err>;
// TODO: add a way to interact with Reference and ReferenceUnique columns

View file

@ -29,7 +29,7 @@ impl Resolver for KVResolver {
fn resolve<S: State>(&self, state: &mut S, event: &Event<KVEventContent>) {
dbg!(event);
let table = match state.table("kv") {
let mut table = match state.table("kv") {
Ok(t) => t,
Err(_) => panic!("no table exists"),
};

99
src/store/memory.rs Normal file
View file

@ -0,0 +1,99 @@
use std::{collections::HashMap, convert::Infallible, rc::Rc, sync::RwLock};
use crate::proto::table::{ColumnValue, Paginate, State, StateConfig, Table, TableRow};
#[derive(Debug, Default)]
pub struct MemoryStore {
tables: HashMap<String, MemoryTable>,
}
#[derive(Debug, Default, Clone)]
pub struct MemoryTable {
map: Rc<RwLock<Vec<TableRow>>>,
}
impl MemoryStore {
pub fn new() -> Self {
Self::default()
}
pub fn init(mut self, config: StateConfig) -> Result<Box<Self>, Infallible> {
for (table_name, _table_column) in config.tables {
self.tables.insert(table_name, MemoryTable::new());
}
Ok(Box::new(self))
}
}
impl MemoryTable {
pub fn new() -> Self {
Self::default()
}
}
impl State for MemoryStore {
type Err = ();
type Table = MemoryTable;
fn table(&self, name: &str) -> Result<Self::Table, Self::Err> {
self.tables.get(name).cloned().ok_or(())
}
}
impl Table for MemoryTable {
type Err = ();
fn lookup(
&self,
column: &str,
value: impl Into<ColumnValue>,
) -> Result<Vec<TableRow>, Self::Err> {
let value = value.into();
let map = self.map.read().unwrap();
Ok(map
.iter()
.filter(|r| r.values.get(column).is_some_and(|v| v == &value))
.cloned()
.collect())
}
fn lookup_one(
&self,
column: &str,
value: impl Into<ColumnValue>,
) -> Result<TableRow, Self::Err> {
self.lookup(column, value)
.and_then(|a| a.into_iter().next().ok_or(()))
}
fn lookup_optional(
&self,
column: &str,
value: impl Into<ColumnValue>,
) -> Result<Option<TableRow>, Self::Err> {
self.lookup(column, value).map(|a| a.into_iter().next())
}
fn range(
&self,
_column: &str,
_paginate: Paginate,
_limit: u64,
) -> Result<Vec<TableRow>, Self::Err> {
todo!()
}
fn search_text(
&self,
_column: &str,
_search: &str,
_limit: u64,
_after: u64,
) -> Result<Vec<TableRow>, Self::Err> {
todo!()
}
fn insert(&mut self, row: TableRow) -> Result<(), Self::Err> {
Ok(self.map.write().unwrap().push(row))
}
}

View file

@ -1 +1,2 @@
pub mod memory;
pub mod sqlite;

View file

@ -186,7 +186,7 @@ impl table::Table for Table {
todo!()
}
fn insert(&self, mut row: table::TableRow) -> Result<(), Self::Err> {
fn insert(&mut self, mut row: table::TableRow) -> Result<(), Self::Err> {
let mut sql = String::from("INSERT INTO ");
sql.push_str(&self.name.replace('\'', "''"));
sql.push_str(" (");