aboutsummaryrefslogtreecommitdiff
path: root/database
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2026-02-18 16:08:34 +0100
committermetamuffin <metamuffin@disroot.org>2026-02-18 16:08:34 +0100
commit70169924b611b9b68587bd9169f991e3770b7dc7 (patch)
tree83268ed2da5526d50ef111f8d7217b908221da6d /database
parent45a485431df0638396f0175de59275b3b5538022 (diff)
downloadjellything-70169924b611b9b68587bd9169f991e3770b7dc7.tar
jellything-70169924b611b9b68587bd9169f991e3770b7dc7.tar.bz2
jellything-70169924b611b9b68587bd9169f991e3770b7dc7.tar.zst
show database debug info
Diffstat (limited to 'database')
-rw-r--r--database/src/kv/index_key.rs48
-rw-r--r--database/src/kv/mod.rs13
-rw-r--r--database/src/lib.rs1
-rw-r--r--database/src/query_ser.rs27
4 files changed, 71 insertions, 18 deletions
diff --git a/database/src/kv/index_key.rs b/database/src/kv/index_key.rs
index eab46c4..fae7d4a 100644
--- a/database/src/kv/index_key.rs
+++ b/database/src/kv/index_key.rs
@@ -1,3 +1,5 @@
+use std::fmt::Display;
+
/*
This file is part of jellything (https://codeberg.org/metamuffin/jellything)
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
@@ -128,6 +130,52 @@ impl SortKey {
}
}
+impl Display for IndexKey {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ write!(f, "{} | {}", self.0, self.1)
+ }
+}
+impl Display for Binning {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ for (i, b) in self.0.iter().enumerate() {
+ if i > 0 {
+ write!(f, " ")?;
+ }
+ write!(f, "{b}")?;
+ }
+ Ok(())
+ }
+}
+impl Display for BinningComponent {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ BinningComponent::Has(path) => write!(f, "H({path})"),
+ BinningComponent::Match(path) => write!(f, "M({path})"),
+ }
+ }
+}
+impl Display for SortKey {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ SortKey::None => write!(f, "none"),
+ SortKey::Count => write!(f, "count"),
+ SortKey::Value(path, multi) => write!(f, "value({path}, {multi})"),
+ SortKey::Text(path) => write!(f, "text({path})"),
+ }
+ }
+}
+impl Display for MultiBehaviour {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.write_str(match self {
+ MultiBehaviour::First => "first",
+ MultiBehaviour::ForEach => "for_each",
+ MultiBehaviour::Max => "max",
+ MultiBehaviour::Min => "min",
+ MultiBehaviour::Count => "count",
+ })
+ }
+}
+
fn write_path(path: &Path, out: &mut Vec<u8>) {
assert!(path.0.len() < 256);
out.push(path.0.len() as u8);
diff --git a/database/src/kv/mod.rs b/database/src/kv/mod.rs
index f90f07e..257eec4 100644
--- a/database/src/kv/mod.rs
+++ b/database/src/kv/mod.rs
@@ -27,7 +27,7 @@ use crate::{
use anyhow::{Result, anyhow};
use jellyobject::ObjectBuffer;
use log::{debug, info};
-use std::borrow::Cow;
+use std::{borrow::Cow, fmt::Write};
pub type SubtreeNum = u32;
@@ -132,6 +132,17 @@ impl Transaction for &mut dyn jellykv::Transaction {
}
Ok(total)
}
+
+ fn debug_info(&self) -> Result<String> {
+ let mut o = String::new();
+ let rc = read_counter(*self, &T_ROW_COUNTER.to_be_bytes(), 0)?;
+ writeln!(o, "Row Counter: {rc}")?;
+ writeln!(o, "Indices:")?;
+ for (is, ik) in list_indices(*self)? {
+ writeln!(o, "\tIS={is} IK={ik}")?;
+ }
+ Ok(o)
+ }
}
fn get_or_create_index(txn: &mut dyn jellykv::Transaction, ik: &IndexKey) -> Result<SubtreeNum> {
diff --git a/database/src/lib.rs b/database/src/lib.rs
index ed9dc47..2ecf3c6 100644
--- a/database/src/lib.rs
+++ b/database/src/lib.rs
@@ -29,6 +29,7 @@ pub trait Transaction {
) -> Result<Box<dyn Iterator<Item = Result<(RowNum, Vec<u8>)>> + 'a>>;
fn query_single(&mut self, query: Query) -> Result<Option<RowNum>>;
fn count(&mut self, query: Query) -> Result<u64>;
+ fn debug_info(&self) -> Result<String>;
}
#[derive(Default, Clone)]
diff --git a/database/src/query_ser.rs b/database/src/query_ser.rs
index de62a72..d51ef64 100644
--- a/database/src/query_ser.rs
+++ b/database/src/query_ser.rs
@@ -4,8 +4,7 @@
Copyright (C) 2026 metamuffin <metamuffin.org>
*/
-use crate::{Filter, MultiBehaviour, Query, Sort, SortOrder, Value};
-use jellyobject::Path;
+use crate::{Filter, MultiBehaviour, Query, Sort, SortOrder, Value, ValueSort};
impl Query {
pub fn show(&self) -> String {
@@ -40,9 +39,9 @@ impl Filter {
.join(" OR ")
),
Filter::Match(path, value) => {
- format!("{} = {}", show_path(path), show_value(value))
+ format!("{path} = {}", show_value(value))
}
- Filter::Has(path) => show_path(path),
+ Filter::Has(path) => format!("{path}"),
}
}
}
@@ -50,37 +49,31 @@ impl Sort {
pub fn show(&self) -> String {
match self {
Sort::None => "NONE".to_string(),
- Sort::Value(vs) => {
+ Sort::Value(ValueSort {
+ multi, order, path, ..
+ }) => {
format!(
- "{} BY {} {}",
- match vs.order {
+ "{} BY {} {path}",
+ match order {
SortOrder::Ascending => "ASCENDING",
SortOrder::Descending => "DESCENDING",
},
- match vs.multi {
+ match multi {
MultiBehaviour::Count => "COUNT",
MultiBehaviour::First => "FIRST",
MultiBehaviour::ForEach => "EACH",
MultiBehaviour::Max => "MAX",
MultiBehaviour::Min => "MIN",
},
- show_path(&vs.path),
)
}
Sort::TextSearch(path, value) => {
- format!("TEXT SEARCH {} = {value:?}", show_path(path),)
+ format!("TEXT SEARCH {path} = {value:?}")
}
}
}
}
-fn show_path(path: &Path) -> String {
- path.0
- .iter()
- .map(|s| str::from_utf8(&s.0.to_be_bytes()).unwrap().to_string())
- .collect::<Vec<_>>()
- .join(".")
-}
fn show_value(value: &Value) -> String {
match value {
Value::Tag(tag) => format!("{tag}"),