aboutsummaryrefslogtreecommitdiff
path: root/database
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-02-18 13:24:44 +0100
committermetamuffin <metamuffin@disroot.org>2026-02-18 13:24:44 +0100
commit3bbedf5ab337d8c6d608ed0b24b9c656b0ee1004 (patch)
treebf0cda90ed493af37569a7b3f27374decfcddb10 /database
parentb176a9f7c36bf26f0e42d8b1bc30e214de9f14c9 (diff)
downloadjellything-3bbedf5ab337d8c6d608ed0b24b9c656b0ee1004.tar
jellything-3bbedf5ab337d8c6d608ed0b24b9c656b0ee1004.tar.bz2
jellything-3bbedf5ab337d8c6d608ed0b24b9c656b0ee1004.tar.zst
dynamic typed db match values
Diffstat (limited to 'database')
-rw-r--r--database/src/kv/binning.rs36
-rw-r--r--database/src/kv/mod.rs3
-rw-r--r--database/src/kv/tests.rs10
-rw-r--r--database/src/lib.rs45
-rw-r--r--database/src/query_ser.rs21
5 files changed, 94 insertions, 21 deletions
diff --git a/database/src/kv/binning.rs b/database/src/kv/binning.rs
index 42e58fc..c41d6e9 100644
--- a/database/src/kv/binning.rs
+++ b/database/src/kv/binning.rs
@@ -4,7 +4,7 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::Filter;
+use crate::{Filter, Value};
use jellyobject::{Object, Path};
/// Sorted list of components to bin objects by filtered values.
@@ -88,8 +88,7 @@ impl Filter {
Filter::Match(path, value) => {
vec![vec![(BinningComponent::Match(path.to_owned()), {
let mut co = Vec::new();
- co.extend((value.len() as u32).to_be_bytes());
- co.extend(value);
+ value.write_with_len(&mut co);
co
})]]
}
@@ -100,6 +99,37 @@ impl Filter {
}
}
+impl Value {
+ pub fn write_with_len(&self, out: &mut Vec<u8>) {
+ match self {
+ Value::Tag(tag) => {
+ out.extend(4u32.to_be_bytes());
+ out.extend(tag.0.to_be_bytes());
+ }
+ Value::U32(x) => {
+ out.extend(4u32.to_be_bytes());
+ out.extend(x.to_be_bytes());
+ }
+ Value::U64(x) => {
+ out.extend(8u32.to_be_bytes());
+ out.extend(x.to_be_bytes());
+ }
+ Value::I64(x) => {
+ out.extend(8u32.to_be_bytes());
+ out.extend(x.to_be_bytes());
+ }
+ Value::String(s) => {
+ out.extend((s.len() as u32).to_be_bytes());
+ out.extend(s.as_bytes());
+ }
+ Value::Binary(s) => {
+ out.extend((s.len() as u32).to_be_bytes());
+ out.extend(s);
+ }
+ }
+ }
+}
+
#[cfg(test)]
mod test {
use jellyobject::{Path, Tag};
diff --git a/database/src/kv/mod.rs b/database/src/kv/mod.rs
index f5dcc72..f90f07e 100644
--- a/database/src/kv/mod.rs
+++ b/database/src/kv/mod.rs
@@ -14,8 +14,6 @@ pub mod sort;
#[cfg(test)]
pub mod tests;
-use std::borrow::Cow;
-
use crate::{
Database, Query, RowNum, Transaction,
kv::{
@@ -29,6 +27,7 @@ use crate::{
use anyhow::{Result, anyhow};
use jellyobject::ObjectBuffer;
use log::{debug, info};
+use std::borrow::Cow;
pub type SubtreeNum = u32;
diff --git a/database/src/kv/tests.rs b/database/src/kv/tests.rs
index 5b587ed..85ee5d7 100644
--- a/database/src/kv/tests.rs
+++ b/database/src/kv/tests.rs
@@ -1,5 +1,5 @@
use crate::{
- Database, Filter, Query, Sort,
+ Database, Filter, Query, Sort, Value,
test_shared::{AGE, NAME, new_alice, new_bob, new_charlie},
};
use anyhow::Result;
@@ -67,7 +67,7 @@ pub fn query_match_int() -> Result<()> {
})?;
db.transaction(&mut |txn| {
result = txn.query_single(Query {
- filter: Filter::Match(Path(vec![AGE.0]), 35_u32.to_be_bytes().to_vec()),
+ filter: Filter::Match(Path(vec![AGE.0]), Value::U32(35)),
sort: Sort::None,
})?;
Ok(())
@@ -94,7 +94,7 @@ pub fn query_match_str() -> Result<()> {
})?;
db.transaction(&mut |txn| {
result = txn.query_single(Query {
- filter: Filter::Match(Path(vec![NAME.0]), "Alice".as_bytes().to_vec()),
+ filter: Filter::Match(Path(vec![NAME.0]), "Alice".into()),
sort: Sort::None,
})?;
Ok(())
@@ -113,7 +113,7 @@ pub fn query_match_str_after() -> Result<()> {
db.transaction(&mut |txn| {
result = txn.query_single(Query {
- filter: Filter::Match(Path(vec![NAME.0]), "Alice".as_bytes().to_vec()),
+ filter: Filter::Match(Path(vec![NAME.0]), "Alice".into()),
sort: Sort::None,
})?;
Ok(())
@@ -131,7 +131,7 @@ pub fn query_match_str_after() -> Result<()> {
db.transaction(&mut |txn| {
result = txn.query_single(Query {
- filter: Filter::Match(Path(vec![NAME.0]), "Alice".as_bytes().to_vec()),
+ filter: Filter::Match(Path(vec![NAME.0]), "Alice".into()),
sort: Sort::None,
})?;
Ok(())
diff --git a/database/src/lib.rs b/database/src/lib.rs
index 9b76c58..ed9dc47 100644
--- a/database/src/lib.rs
+++ b/database/src/lib.rs
@@ -9,7 +9,7 @@ pub mod query_ser;
pub mod test_shared;
use anyhow::Result;
-use jellyobject::{ObjectBuffer, Path};
+use jellyobject::{ObjectBuffer, Path, Tag};
pub type RowNum = u64;
pub type RowIter = Box<dyn Iterator<Item = Result<(RowNum, Vec<u8>)>>>;
@@ -74,6 +74,47 @@ pub enum Filter {
True,
All(Vec<Filter>),
Any(Vec<Filter>),
- Match(Path, Vec<u8>),
+ Match(Path, Value),
Has(Path),
}
+
+#[derive(Debug, Clone)]
+pub enum Value {
+ Tag(Tag),
+ U32(u32),
+ U64(u64),
+ I64(i64),
+ String(String),
+ Binary(Vec<u8>),
+}
+
+impl From<&str> for Value {
+ fn from(value: &str) -> Self {
+ Self::String(value.to_owned())
+ }
+}
+impl From<String> for Value {
+ fn from(value: String) -> Self {
+ Self::String(value)
+ }
+}
+impl From<u32> for Value {
+ fn from(value: u32) -> Self {
+ Self::U32(value)
+ }
+}
+impl From<u64> for Value {
+ fn from(value: u64) -> Self {
+ Self::U64(value)
+ }
+}
+impl From<i64> for Value {
+ fn from(value: i64) -> Self {
+ Self::I64(value)
+ }
+}
+impl From<Tag> for Value {
+ fn from(value: Tag) -> Self {
+ Self::Tag(value)
+ }
+}
diff --git a/database/src/query_ser.rs b/database/src/query_ser.rs
index d76dea7..de62a72 100644
--- a/database/src/query_ser.rs
+++ b/database/src/query_ser.rs
@@ -4,8 +4,8 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::{Filter, MultiBehaviour, Query, Sort, SortOrder};
-use jellyobject::{Path, Tag};
+use crate::{Filter, MultiBehaviour, Query, Sort, SortOrder, Value};
+use jellyobject::Path;
impl Query {
pub fn show(&self) -> String {
@@ -40,11 +40,7 @@ impl Filter {
.join(" OR ")
),
Filter::Match(path, value) => {
- format!(
- "{} = {}",
- show_path(path),
- show_value(*path.0.last().unwrap(), value)
- )
+ format!("{} = {}", show_path(path), show_value(value))
}
Filter::Has(path) => show_path(path),
}
@@ -85,6 +81,13 @@ fn show_path(path: &Path) -> String {
.collect::<Vec<_>>()
.join(".")
}
-fn show_value(_tag: Tag, value: &[u8]) -> String {
- format!("{value:?}") // TODO
+fn show_value(value: &Value) -> String {
+ match value {
+ Value::Tag(tag) => format!("{tag}"),
+ Value::U32(x) => format!("{x}"),
+ Value::U64(x) => format!("{x}"),
+ Value::I64(x) => format!("{x}"),
+ Value::String(x) => format!("{x:?}"),
+ Value::Binary(x) => format!("{x:?}"),
+ }
}