migrate from anyhow to miette

main
Ziyang Hu 2 years ago
parent 904279b50a
commit 4956b3ffd0

@ -12,7 +12,7 @@ casey = "0.3.3"
tempfile = "3.3.0"
either = "1.7.0"
rand = "0.8.5"
anyhow = "1.0"
miette = "5.3.0"
lazy_static = "1.4.0"
log = "0.4.16"
env_logger = "0.9.0"

@ -12,7 +12,7 @@ static-files = "0.2.3"
clap = { version = "3.2.8", features = ["derive"] }
actix-cors = "0.6.1"
log = "0.4.16"
anyhow = "1.0.62"
miette = "5.3.0"
env_logger = "0.9.0"
serde_json = "1.0.81"
rust-argon2 = "1.0.0"

@ -11,7 +11,7 @@ use actix_web::http::header::HeaderName;
use actix_web::rt::task::spawn_blocking;
use actix_web::{post, web, App, HttpRequest, HttpResponse, HttpServer, Responder};
use actix_web_static_files::ResourceFiles;
use anyhow::{anyhow, bail};
use miette::{miette, bail, IntoDiagnostic};
use clap::Parser;
use env_logger::Env;
use log::debug;
@ -24,7 +24,7 @@ use cozo::{Db, DbBuilder};
type Result<T> = std::result::Result<T, RespError>;
struct RespError {
err: anyhow::Error,
err: miette::Error,
}
impl Debug for RespError {
@ -72,17 +72,17 @@ struct AppStateWithDb {
const PASSWORD_KEY: &str = "WEB_USER_PASSWORD";
impl AppStateWithDb {
async fn verify_password(&self, req: &HttpRequest) -> anyhow::Result<()> {
async fn verify_password(&self, req: &HttpRequest) -> miette::Result<()> {
let username = req
.headers()
.get(&HeaderName::from_static("x-cozo-username"))
.ok_or_else(|| anyhow!("not authenticated"))?
.to_str()?;
.ok_or_else(|| miette!("not authenticated"))?
.to_str().into_diagnostic()?;
let password = req
.headers()
.get(&HeaderName::from_static("x-cozo-password"))
.ok_or_else(|| anyhow!("not authenticated"))?
.to_str()?;
.ok_or_else(|| miette!("not authenticated"))?
.to_str().into_diagnostic()?;
if let Some(stored) = self.pass_cache.read().unwrap().get(username).cloned() {
let mut seed = self.seed.to_vec();
seed.extend_from_slice(password.as_bytes());
@ -99,10 +99,10 @@ impl AppStateWithDb {
let db = self.db.new_session()?;
let password = password.to_string();
let username = username.to_string();
spawn_blocking(move || -> anyhow::Result<()> {
spawn_blocking(move || -> miette::Result<()> {
if let Some(hashed) = db.get_meta_kv(&[PASSWORD_KEY, &username])? {
let hashed = from_utf8(&hashed)?;
if argon2::verify_encoded(&hashed, password.as_bytes())? {
let hashed = from_utf8(&hashed).into_diagnostic()?;
if argon2::verify_encoded(&hashed, password.as_bytes()).into_diagnostic()? {
seed.extend_from_slice(password.as_bytes());
let easy_digest: &[u8] = &sha3::Sha3_256::digest(&seed);
pass_cache
@ -115,26 +115,26 @@ impl AppStateWithDb {
thread::sleep(Duration::from_millis(1234));
bail!("invalid password")
})
.await?
.await.into_diagnostic()?
}
async fn reset_password(&self, user: &str, new_pass: &str) -> anyhow::Result<()> {
async fn reset_password(&self, user: &str, new_pass: &str) -> miette::Result<()> {
let pass_cache = self.pass_cache.clone();
let db = self.db.new_session()?;
let username = user.to_string();
let new_pass = new_pass.to_string();
spawn_blocking(move || -> anyhow::Result<()> {
spawn_blocking(move || -> miette::Result<()> {
pass_cache.write().unwrap().remove(&username);
let salt = rand::thread_rng().gen::<[u8; 32]>();
let config = argon2config();
let hash = argon2::hash_encoded(new_pass.as_bytes(), &salt, &config)?;
let hash = argon2::hash_encoded(new_pass.as_bytes(), &salt, &config).into_diagnostic()?;
db.put_meta_kv(&[PASSWORD_KEY, &username], hash.as_bytes())?;
Ok(())
})
.await?
.await.into_diagnostic()?
}
async fn remove_user(&self, user: &str) -> anyhow::Result<()> {
async fn remove_user(&self, user: &str) -> miette::Result<()> {
self.pass_cache.write().unwrap().remove(user);
self.db.remove_meta_kv(&[PASSWORD_KEY, &user])?;
Ok(())
@ -159,12 +159,12 @@ async fn query(
data.verify_password(&req).await?;
let text = std::str::from_utf8(&body)
.map_err(|e| anyhow!(e))?
.map_err(|e| miette!(e))?
.to_string();
let db = data.db.new_session()?;
let start = Instant::now();
let task = spawn_blocking(move || db.run_script(&text));
let mut result = task.await.map_err(|e| anyhow!(e))??;
let mut result = task.await.map_err(|e| miette!(e))??;
if let Some(obj) = result.as_object_mut() {
obj.insert(
"time_taken".to_string(),
@ -184,14 +184,14 @@ async fn change_password(
let username = req
.headers()
.get(&HeaderName::from_static("x-cozo-username"))
.ok_or_else(|| anyhow!("not authenticated"))?
.ok_or_else(|| miette!("not authenticated"))?
.to_str()
.map_err(|e| anyhow!(e))?;
.map_err(|e| miette!(e))?;
let new_pass = body
.get("new_pass")
.ok_or_else(|| anyhow!("required 'new_pass' field"))?
.ok_or_else(|| miette!("required 'new_pass' field"))?
.as_str()
.ok_or_else(|| anyhow!("'new_pass' field required to be a string"))?;
.ok_or_else(|| miette!("'new_pass' field required to be a string"))?;
data.reset_password(username, new_pass).await?;
Ok(HttpResponse::Ok().json(json!({"status": "OK"})))
}
@ -205,14 +205,14 @@ async fn assert_user(
data.verify_password(&req).await?;
let new_user = body
.get("username")
.ok_or_else(|| anyhow!("required 'username' field"))?
.ok_or_else(|| miette!("required 'username' field"))?
.as_str()
.ok_or_else(|| anyhow!("'username' field required to be a string"))?;
.ok_or_else(|| miette!("'username' field required to be a string"))?;
let new_pass = body
.get("new_pass")
.ok_or_else(|| anyhow!("required 'new_pass' field"))?
.ok_or_else(|| miette!("required 'new_pass' field"))?
.as_str()
.ok_or_else(|| anyhow!("'new_pass' field required to be a string"))?;
.ok_or_else(|| miette!("'new_pass' field required to be a string"))?;
data.reset_password(new_user, new_pass).await?;
Ok(HttpResponse::Ok().json(json!({"status": "OK"})))
}
@ -226,9 +226,9 @@ async fn remove_user(
data.verify_password(&req).await?;
let user = body
.get("username")
.ok_or_else(|| anyhow!("required 'username' field"))?
.ok_or_else(|| miette!("required 'username' field"))?
.as_str()
.ok_or_else(|| anyhow!("'username' field required to be a string"))?;
.ok_or_else(|| miette!("'username' field required to be a string"))?;
data.remove_user(&user).await?;
Ok(HttpResponse::Ok().json(json!({"status": "OK"})))
}
@ -244,7 +244,7 @@ async fn json_query(
let db = data.db.new_session()?;
let start = Instant::now();
let task = spawn_blocking(move || db.run_json_query(&body));
let mut result = task.await.map_err(|e| anyhow!(e))??;
let mut result = task.await.map_err(|e| miette!(e))??;
if let Some(obj) = result.as_object_mut() {
obj.insert(
"time_taken".to_string(),
@ -263,7 +263,7 @@ async fn to_json_query(
data.verify_password(&req).await?;
let text = std::str::from_utf8(&body)
.map_err(|e| anyhow!(e))?
.map_err(|e| miette!(e))?
.to_string();
let db = data.db.new_session()?;
let res = db.convert_to_json_query(&text)?;

@ -1,8 +1,8 @@
use std::cmp::Reverse;
use std::collections::BTreeMap;
use anyhow::anyhow;
use anyhow::Result;
use miette::miette;
use miette::Result;
use itertools::Itertools;
use ordered_float::OrderedFloat;
use priority_queue::PriorityQueue;
@ -30,10 +30,10 @@ impl AlgoImpl for BetweennessCentrality {
stores: &BTreeMap<MagicSymbol, DerivedRelStore>,
out: &DerivedRelStore,
poison: Poison,
) -> anyhow::Result<()> {
) -> miette::Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'betweenness_centrality' requires edges relation"))?;
.ok_or_else(|| miette!("'betweenness_centrality' requires edges relation"))?;
let undirected =
get_bool_option_required("undirected", opts, Some(false), "betweenness_centrality")?;
@ -96,10 +96,10 @@ impl AlgoImpl for ClosenessCentrality {
stores: &BTreeMap<MagicSymbol, DerivedRelStore>,
out: &DerivedRelStore,
poison: Poison,
) -> anyhow::Result<()> {
) -> miette::Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'closeness_centrality' requires edges relation"))?;
.ok_or_else(|| miette!("'closeness_centrality' requires edges relation"))?;
let undirected =
get_bool_option_required("undirected", opts, Some(false), "closeness_centrality")?;

@ -1,7 +1,7 @@
use std::cmp::Reverse;
use std::collections::BTreeMap;
use anyhow::{anyhow, ensure, Result};
use miette::{miette, ensure, Result};
use ordered_float::OrderedFloat;
use priority_queue::PriorityQueue;
use smartstring::{LazyCompact, SmartString};
@ -29,19 +29,19 @@ impl AlgoImpl for ShortestPathAStar {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'shortest_path_astar' requires edges relation"))?;
.ok_or_else(|| miette!("'shortest_path_astar' requires edges relation"))?;
let nodes = rels.get(1).ok_or_else(|| {
anyhow!("'shortest_path_astar' requires nodes relation as second argument")
miette!("'shortest_path_astar' requires nodes relation as second argument")
})?;
let starting = rels.get(2).ok_or_else(|| {
anyhow!("'shortest_path_astar' requires starting relation as third argument")
miette!("'shortest_path_astar' requires starting relation as third argument")
})?;
let goals = rels.get(3).ok_or_else(|| {
anyhow!("'shortest_path_astar' requires goal relation as fourth argument")
miette!("'shortest_path_astar' requires goal relation as fourth argument")
})?;
let mut heuristic = opts
.get("heuristic")
.ok_or_else(|| anyhow!("'heuristic' option required for 'shortest_path_astar'"))?
.ok_or_else(|| miette!("'heuristic' option required for 'shortest_path_astar'"))?
.clone();
let mut binding_map = nodes.get_binding_map(0);
@ -82,17 +82,17 @@ fn astar(
let start_node = starting
.0
.get(0)
.ok_or_else(|| anyhow!("starting node too short"))?;
.ok_or_else(|| miette!("starting node too short"))?;
let goal_node = goal
.0
.get(0)
.ok_or_else(|| anyhow!("goal node too short"))?;
.ok_or_else(|| miette!("goal node too short"))?;
let eval_heuristic = |node: &Tuple| -> Result<f64> {
let mut v = node.0.clone();
v.extend_from_slice(&goal.0);
let t = Tuple(v);
let cost = heuristic.eval(&t)?.get_float().ok_or_else(|| {
anyhow!("heuristic function of 'shortest_path_astar' must return a float")
miette!("heuristic function of 'shortest_path_astar' must return a float")
})?;
ensure!(
!cost.is_nan(),
@ -131,7 +131,7 @@ fn astar(
let edge_dst = &edge.0[1];
let edge_cost = edge.0[2]
.get_float()
.ok_or_else(|| anyhow!("cost on edge for 'astar' must be a number"))?;
.ok_or_else(|| miette!("cost on edge for 'astar' must be a number"))?;
ensure!(
!edge_cost.is_nan(),
"got cost NaN for edge of 'shortest_path_astar'"
@ -148,7 +148,7 @@ fn astar(
.prefix_iter(edge_dst, tx, stores)?
.next()
.ok_or_else(|| {
anyhow!(
miette!(
"node {:?} not found in nodes relation of 'shortest_path_astar'",
edge_dst
)

@ -1,6 +1,6 @@
use std::collections::{BTreeMap, BTreeSet, VecDeque};
use anyhow::{anyhow, ensure, Result};
use miette::{miette, ensure, Result};
use smartstring::{LazyCompact, SmartString};
use crate::algo::AlgoImpl;
@ -39,14 +39,14 @@ impl AlgoImpl for Bfs {
let l = expr
.get_const()
.ok_or_else(|| {
anyhow!(
miette!(
"argument 'limit' to 'bfs' must be a constant, got {:?}",
expr
)
})?
.get_int()
.ok_or_else(|| {
anyhow!(
miette!(
"argument 'limit' to 'bfs' must be an integer, got {:?}",
expr
)
@ -62,7 +62,7 @@ impl AlgoImpl for Bfs {
};
let mut condition = opts
.get("condition")
.ok_or_else(|| anyhow!("terminating 'condition' required for 'bfs'"))?
.ok_or_else(|| miette!("terminating 'condition' required for 'bfs'"))?
.clone();
let binding_map = nodes.get_binding_map(0);
condition.fill_binding_indices(&binding_map)?;
@ -78,7 +78,7 @@ impl AlgoImpl for Bfs {
let starting_node = node_tuple
.0
.get(0)
.ok_or_else(|| anyhow!("node tuple is empty"))?;
.ok_or_else(|| miette!("node tuple is empty"))?;
if visited.contains(starting_node) {
continue;
}
@ -93,7 +93,7 @@ impl AlgoImpl for Bfs {
let to_node = edge
.0
.get(1)
.ok_or_else(|| anyhow!("'edges' relation too short"))?;
.ok_or_else(|| miette!("'edges' relation too short"))?;
if visited.contains(to_node) {
continue;
}
@ -107,7 +107,7 @@ impl AlgoImpl for Bfs {
nodes
.prefix_iter(to_node, tx, stores)?
.next()
.ok_or_else(|| anyhow!("node with id {:?} not found", candidate))??
.ok_or_else(|| miette!("node with id {:?} not found", candidate))??
};
if condition.eval_pred(&cand_tuple)? {

@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use anyhow::{anyhow, ensure};
use miette::{miette, ensure};
use smartstring::{LazyCompact, SmartString};
use crate::algo::AlgoImpl;
@ -23,10 +23,10 @@ impl AlgoImpl for DegreeCentrality {
stores: &BTreeMap<MagicSymbol, DerivedRelStore>,
out: &DerivedRelStore,
poison: Poison,
) -> anyhow::Result<()> {
) -> miette::Result<()> {
let it = rels
.get(0)
.ok_or_else(|| anyhow!(
.ok_or_else(|| miette!(
"'degree_centrality' requires at least an edge relation to proceed"
))?
.iter(tx, stores)?;
@ -54,7 +54,7 @@ impl AlgoImpl for DegreeCentrality {
let id = tuple
.0
.get(0)
.ok_or_else(|| anyhow!("nodes relation to 'degree_centrality' too short"))?;
.ok_or_else(|| miette!("nodes relation to 'degree_centrality' too short"))?;
if !counter.contains_key(id) {
counter.insert(id.clone(), (0, 0, 0));
}

@ -1,6 +1,6 @@
use std::collections::{BTreeMap, BTreeSet};
use anyhow::{anyhow, ensure, Result};
use miette::{miette, ensure, Result};
use smartstring::{LazyCompact, SmartString};
use crate::algo::AlgoImpl;
@ -39,14 +39,14 @@ impl AlgoImpl for Dfs {
let l = expr
.get_const()
.ok_or_else(|| {
anyhow!(
miette!(
"argument 'limit' to 'dfs' must be a constant, got {:?}",
expr
)
})?
.get_int()
.ok_or_else(|| {
anyhow!(
miette!(
"argument 'limit' to 'dfs' must be an integer, got {:?}",
expr
)
@ -62,7 +62,7 @@ impl AlgoImpl for Dfs {
};
let mut condition = opts
.get("condition")
.ok_or_else(|| anyhow!("terminating 'condition' required for 'dfs'"))?
.ok_or_else(|| miette!("terminating 'condition' required for 'dfs'"))?
.clone();
let binding_map = nodes.get_binding_map(0);
condition.fill_binding_indices(&binding_map)?;
@ -78,7 +78,7 @@ impl AlgoImpl for Dfs {
let starting_node = node_tuple
.0
.get(0)
.ok_or_else(|| anyhow!("node tuple is empty"))?;
.ok_or_else(|| miette!("node tuple is empty"))?;
if visited.contains(starting_node) {
continue;
}
@ -97,7 +97,7 @@ impl AlgoImpl for Dfs {
nodes
.prefix_iter(&candidate, tx, stores)?
.next()
.ok_or_else(|| anyhow!("node with id {:?} not found", candidate))??
.ok_or_else(|| miette!("node with id {:?} not found", candidate))??
};
if condition.eval_pred(&cand_tuple)? {
@ -114,7 +114,7 @@ impl AlgoImpl for Dfs {
let to_node = edge
.0
.get(1)
.ok_or_else(|| anyhow!("'edges' relation too short"))?;
.ok_or_else(|| miette!("'edges' relation too short"))?;
if visited.contains(to_node) {
continue;
}

@ -1,7 +1,7 @@
use std::cmp::Reverse;
use std::collections::BTreeMap;
use anyhow::{anyhow, Result};
use miette::{miette, Result};
use itertools::Itertools;
use ordered_float::OrderedFloat;
use priority_queue::PriorityQueue;
@ -30,7 +30,7 @@ impl AlgoImpl for MinimumSpanningTreeKruskal {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'minimum_spanning_tree_kruskal' requires edge relation"))?;
.ok_or_else(|| miette!("'minimum_spanning_tree_kruskal' requires edge relation"))?;
let (graph, indices, _, _) =
edges.convert_edge_to_weighted_graph(true, true, tx, stores)?;
if graph.is_empty() {

@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result};
use itertools::Itertools;
use rand::prelude::*;
use smartstring::{LazyCompact, SmartString};
@ -28,14 +28,14 @@ impl AlgoImpl for LabelPropagation {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'label_propagation' requires edges relation"))?;
.ok_or_else(|| miette!("'label_propagation' requires edges relation"))?;
let undirected =
get_bool_option_required("undirected", opts, Some(false), "label_propagation")?;
let max_iter = match opts.get("max_iter") {
None => 10,
Some(Expr::Const(DataValue::Num(n))) => {
let i = n.get_int().ok_or_else(|| {
anyhow!(
miette!(
"'max_iter' for 'label_propagation' requires an integer, got {:?}",
n
)

@ -1,6 +1,6 @@
use std::collections::{BTreeMap, BTreeSet};
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result};
use itertools::Itertools;
use log::debug;
use smartstring::{LazyCompact, SmartString};
@ -28,7 +28,7 @@ impl AlgoImpl for CommunityDetectionLouvain {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'community_detection_louvain' requires edges relation"))?;
.ok_or_else(|| miette!("'community_detection_louvain' requires edges relation"))?;
let undirected = get_bool_option_required(
"undirected",
opts,
@ -39,7 +39,7 @@ impl AlgoImpl for CommunityDetectionLouvain {
None => 10,
Some(Expr::Const(DataValue::Num(n))) => {
let i = n.get_int().ok_or_else(|| {
anyhow!(
miette!(
"'max_iter' for 'community_detection_louvain' requires an integer, got {:?}",
n
)
@ -76,7 +76,7 @@ impl AlgoImpl for CommunityDetectionLouvain {
None => None,
Some(Expr::Const(DataValue::Num(n))) => Some({
let i = n.get_int().ok_or_else(|| {
anyhow!(
miette!(
"'keep_depth' for 'community_detection_louvain' requires an integer, got {:?}",
n
)

@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result};
use either::Either;
use itertools::Itertools;
use smartstring::{LazyCompact, SmartString};
@ -103,7 +103,7 @@ impl AlgoHandle {
"reorder_sort" => {
let out_opts = opts
.get("out")
.ok_or_else(|| anyhow!("'reorder_sort' requires the option 'out'"))?;
.ok_or_else(|| miette!("'reorder_sort' requires the option 'out'"))?;
match out_opts {
Expr::Const(DataValue::List(l)) => l.len() + 1,
Expr::Apply(op, args) if **op == OP_LIST => args.len() + 1,
@ -166,10 +166,10 @@ impl MagicAlgoRuleArg {
let mut tuple = tuple?.0.into_iter();
let from = tuple
.next()
.ok_or_else(|| anyhow!("edges relation too short"))?;
.ok_or_else(|| miette!("edges relation too short"))?;
let to = tuple
.next()
.ok_or_else(|| anyhow!("edges relation too short"))?;
.ok_or_else(|| miette!("edges relation too short"))?;
let weight = match tuple.next() {
None => 1.0,
Some(d) => match d.get_float() {
@ -225,10 +225,10 @@ impl MagicAlgoRuleArg {
let mut tuple = tuple?.0.into_iter();
let from = tuple
.next()
.ok_or_else(|| anyhow!("edges relation too short"))?;
.ok_or_else(|| miette!("edges relation too short"))?;
let to = tuple
.next()
.ok_or_else(|| anyhow!("edges relation too short"))?;
.ok_or_else(|| miette!("edges relation too short"))?;
let from_idx = if let Some(idx) = inv_indices.get(&from) {
*idx
} else {
@ -265,7 +265,7 @@ impl MagicAlgoRuleArg {
MagicAlgoRuleArg::InMem(s, _) => {
let store = stores
.get(s)
.ok_or_else(|| anyhow!("rule not found: {:?}", s))?;
.ok_or_else(|| miette!("rule not found: {:?}", s))?;
let t = Tuple(vec![prefix.clone()]);
Box::new(store.scan_prefix(&t))
}
@ -294,7 +294,7 @@ impl MagicAlgoRuleArg {
}
} else {
let id = prefix.get_int().ok_or_else(|| {
anyhow!(
miette!(
"prefix scanning of triple requires integer id, got {:?}",
prefix
)
@ -342,7 +342,7 @@ impl MagicAlgoRuleArg {
MagicAlgoRuleArg::InMem(s, _) => {
let store = stores
.get(s)
.ok_or_else(|| anyhow!("rule not found: {:?}", s))?;
.ok_or_else(|| miette!("rule not found: {:?}", s))?;
store.arity
}
MagicAlgoRuleArg::Stored(s, _) => {
@ -361,7 +361,7 @@ impl MagicAlgoRuleArg {
MagicAlgoRuleArg::InMem(s, _) => {
let store = stores
.get(s)
.ok_or_else(|| anyhow!("rule not found: {:?}", s))?;
.ok_or_else(|| miette!("rule not found: {:?}", s))?;
Box::new(store.scan_all())
}
MagicAlgoRuleArg::Stored(s, _) => {
@ -427,7 +427,7 @@ pub(crate) fn get_bool_option_required(
algo_name: &str,
) -> Result<bool> {
get_bool_option(name, opts, default, algo_name)?.ok_or_else(|| {
anyhow!(
miette!(
"boolean option '{}' required for algorithm '{}'",
name,
algo_name

@ -1,7 +1,7 @@
use std::collections::BTreeMap;
use std::mem;
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result};
use approx::AbsDiffEq;
use nalgebra::{Dynamic, OMatrix, U1};
use smartstring::{LazyCompact, SmartString};
@ -29,7 +29,7 @@ impl AlgoImpl for PageRank {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'pagerank' requires edges relation"))?;
.ok_or_else(|| miette!("'pagerank' requires edges relation"))?;
let undirected = get_bool_option_required("undirected", opts, Some(false), "pagerank")?;
let theta = match opts.get("theta") {
None => 0.8f32,

@ -1,7 +1,7 @@
use std::cmp::Reverse;
use std::collections::BTreeMap;
use anyhow::{anyhow, Result};
use miette::{miette, Result};
use ordered_float::OrderedFloat;
use priority_queue::PriorityQueue;
use smartstring::{LazyCompact, SmartString};
@ -29,7 +29,7 @@ impl AlgoImpl for MinimumSpanningTreePrim {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'minimum_spanning_tree_prim' requires edge relation"))?;
.ok_or_else(|| miette!("'minimum_spanning_tree_prim' requires edge relation"))?;
let (graph, indices, _, _) =
edges.convert_edge_to_weighted_graph(true, true, tx, stores)?;
if graph.is_empty() {

@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result};
use itertools::Itertools;
use rand::distributions::WeightedIndex;
use rand::prelude::*;
@ -29,18 +29,18 @@ impl AlgoImpl for RandomWalk {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'random_walk' requires edges relation as first argument"))?;
.ok_or_else(|| miette!("'random_walk' requires edges relation as first argument"))?;
let nodes = rels
.get(1)
.ok_or_else(|| anyhow!("'random_walk' requires nodes relation as second argument"))?;
.ok_or_else(|| miette!("'random_walk' requires nodes relation as second argument"))?;
let starting = rels
.get(2)
.ok_or_else(|| anyhow!("'random_walk' requires starting relation as third argument"))?;
.ok_or_else(|| miette!("'random_walk' requires starting relation as third argument"))?;
let iterations = match opts.get("iterations") {
None => 1usize,
Some(Expr::Const(DataValue::Num(n))) => {
let n = n.get_int().ok_or_else(|| {
anyhow!(
miette!(
"'iterations' for 'random_walk' requires an integer, got {}",
n
)
@ -59,11 +59,11 @@ impl AlgoImpl for RandomWalk {
};
let steps = match opts
.get("steps")
.ok_or_else(|| anyhow!("'random_walk' requires option 'steps'"))?
.ok_or_else(|| miette!("'random_walk' requires option 'steps'"))?
{
Expr::Const(DataValue::Num(n)) => {
let n = n.get_int().ok_or_else(|| {
anyhow!("'steps' for 'random_walk' requires an integer, got {}", n)
miette!("'steps' for 'random_walk' requires an integer, got {}", n)
})?;
ensure!(
n > 0,
@ -94,11 +94,11 @@ impl AlgoImpl for RandomWalk {
let start_node_key = start_node
.0
.get(0)
.ok_or_else(|| anyhow!("starting node relation too short"))?;
.ok_or_else(|| miette!("starting node relation too short"))?;
let starting_tuple = nodes
.prefix_iter(start_node_key, tx, stores)?
.next()
.ok_or_else(|| anyhow!("node with key '{:?}' not found", start_node_key))??;
.ok_or_else(|| miette!("node with key '{:?}' not found", start_node_key))??;
for _ in 0..iterations {
counter += 1;
let mut current_tuple = starting_tuple.clone();
@ -107,7 +107,7 @@ impl AlgoImpl for RandomWalk {
let cur_node_key = current_tuple
.0
.get(0)
.ok_or_else(|| anyhow!("node tuple too short"))?;
.ok_or_else(|| miette!("node tuple too short"))?;
let candidate_steps: Vec<_> =
edges.prefix_iter(cur_node_key, tx, stores)?.try_collect()?;
if candidate_steps.is_empty() {
@ -134,13 +134,13 @@ impl AlgoImpl for RandomWalk {
let next_node = next_step
.0
.get(1)
.ok_or_else(|| anyhow!("edges relation for 'random_walk' too short"))?;
.ok_or_else(|| miette!("edges relation for 'random_walk' too short"))?;
path.push(next_node.clone());
current_tuple = nodes
.prefix_iter(next_node, tx, stores)?
.next()
.ok_or_else(|| {
anyhow!("node with key '{:?}' not found", start_node_key)
miette!("node with key '{:?}' not found", start_node_key)
})??;
poison.check()?;
}

@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result};
use itertools::Itertools;
use smartstring::{LazyCompact, SmartString};
@ -28,11 +28,11 @@ impl AlgoImpl for ReorderSort {
) -> Result<()> {
let in_rel = rels
.get(0)
.ok_or_else(|| anyhow!("'reorder_sort' requires an input relation"))?;
.ok_or_else(|| miette!("'reorder_sort' requires an input relation"))?;
let mut out_list = match opts
.get("out")
.ok_or_else(|| anyhow!("'reorder_sort' requires the option 'out'"))?
.ok_or_else(|| miette!("'reorder_sort' requires the option 'out'"))?
{
Expr::Const(DataValue::List(l)) => {
l.iter().map(|d| Expr::Const(d.clone())).collect_vec()
@ -53,7 +53,7 @@ impl AlgoImpl for ReorderSort {
let skip = match opts.get("skip") {
None => 0,
Some(Expr::Const(v)) => v.get_int().ok_or_else(|| {
anyhow!(
miette!(
"option 'skip' of 'reorder_sort' must be an integer, got {:?}",
v
)
@ -71,7 +71,7 @@ impl AlgoImpl for ReorderSort {
let take = match opts.get("take") {
None => i64::MAX,
Some(Expr::Const(v)) => v.get_int().ok_or_else(|| {
anyhow!(
miette!(
"option 'take' of 'reorder_sort' must be an integer, got {:?}",
v
)

@ -2,7 +2,7 @@ use std::cmp::{Ordering, Reverse};
use std::collections::{BTreeMap, BTreeSet};
use std::iter;
use anyhow::{anyhow, Result};
use miette::{miette, Result};
use itertools::Itertools;
use ordered_float::OrderedFloat;
use priority_queue::PriorityQueue;
@ -33,9 +33,9 @@ impl AlgoImpl for ShortestPathDijkstra {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'shortest_path_dijkstra' requires edges relation"))?;
.ok_or_else(|| miette!("'shortest_path_dijkstra' requires edges relation"))?;
let starting = rels.get(1).ok_or_else(|| {
anyhow!("'shortest_path_dijkstra' requires starting relation as second argument")
miette!("'shortest_path_dijkstra' requires starting relation as second argument")
})?;
let termination = rels.get(2);
let undirected =
@ -52,7 +52,7 @@ impl AlgoImpl for ShortestPathDijkstra {
let node = tuple
.0
.get(0)
.ok_or_else(|| anyhow!("node relation too short"))?;
.ok_or_else(|| miette!("node relation too short"))?;
if let Some(idx) = inv_indices.get(node) {
starting_nodes.insert(*idx);
}
@ -66,7 +66,7 @@ impl AlgoImpl for ShortestPathDijkstra {
let node = tuple
.0
.get(0)
.ok_or_else(|| anyhow!("node relation too short"))?;
.ok_or_else(|| miette!("node relation too short"))?;
if let Some(idx) = inv_indices.get(node) {
tn.insert(*idx);
}

@ -1,7 +1,7 @@
use std::cmp::min;
use std::collections::BTreeMap;
use anyhow::{anyhow, bail, Result};
use miette::{miette, bail, Result};
use itertools::Itertools;
use smartstring::{LazyCompact, SmartString};
@ -36,7 +36,7 @@ impl AlgoImpl for StronglyConnectedComponent {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'strongly_connected_components' missing edges relation"))?;
.ok_or_else(|| miette!("'strongly_connected_components' missing edges relation"))?;
let reverse_mode = match opts.get("mode") {
None => false,
@ -76,7 +76,7 @@ impl AlgoImpl for StronglyConnectedComponent {
for tuple in nodes.iter(tx, stores)? {
let tuple = tuple?;
let node = tuple.0.into_iter().next().ok_or_else(|| {
anyhow!("nodes relation for 'strongly_connected_components' too short")
miette!("nodes relation for 'strongly_connected_components' too short")
})?;
if !inv_indices.contains_key(&node) {
inv_indices.insert(node.clone(), usize::MAX);

@ -1,6 +1,6 @@
use std::collections::BTreeMap;
use anyhow::{anyhow, Result};
use miette::{miette, Result};
use smartstring::{LazyCompact, SmartString};
use crate::algo::AlgoImpl;
@ -26,7 +26,7 @@ impl AlgoImpl for TopSort {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'top_sort' missing edges relation"))?;
.ok_or_else(|| miette!("'top_sort' missing edges relation"))?;
let (graph, indices, _) = edges.convert_edge_to_graph(false, tx, stores)?;

@ -1,6 +1,6 @@
use std::collections::{BTreeMap, BTreeSet};
use anyhow::{anyhow, Result};
use miette::{miette, Result};
use rayon::prelude::*;
use smartstring::{LazyCompact, SmartString};
@ -27,7 +27,7 @@ impl AlgoImpl for ClusteringCoefficients {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'clustering_coefficients' requires edges relation"))?;
.ok_or_else(|| miette!("'clustering_coefficients' requires edges relation"))?;
let (graph, indices, _) = edges.convert_edge_to_graph(true, tx, stores)?;
let graph: Vec<BTreeSet<usize>> =
graph.into_iter().map(|e| e.into_iter().collect()).collect();

@ -1,6 +1,6 @@
use std::collections::{BTreeMap, BTreeSet};
use anyhow::{anyhow, ensure, Result};
use miette::{miette, ensure, Result};
use itertools::Itertools;
use rayon::prelude::*;
use smartstring::{LazyCompact, SmartString};
@ -29,22 +29,22 @@ impl AlgoImpl for KShortestPathYen {
) -> Result<()> {
let edges = rels
.get(0)
.ok_or_else(|| anyhow!("'k_shortest_path_yen' requires edges relation"))?;
.ok_or_else(|| miette!("'k_shortest_path_yen' requires edges relation"))?;
let starting = rels.get(1).ok_or_else(|| {
anyhow!("'k_shortest_path_yen' requires starting relation as second argument")
miette!("'k_shortest_path_yen' requires starting relation as second argument")
})?;
let termination = rels.get(2).ok_or_else(|| {
anyhow!("'k_shortest_path_yen' requires termination relation as third argument")
miette!("'k_shortest_path_yen' requires termination relation as third argument")
})?;
let undirected =
get_bool_option_required("undirected", opts, Some(false), "k_shortest_path_yen")?;
let k = opts
.get("k")
.ok_or_else(|| anyhow!("option 'k' required for 'k_shortest_path_yen'"))?
.ok_or_else(|| miette!("option 'k' required for 'k_shortest_path_yen'"))?
.get_const()
.ok_or_else(|| anyhow!("option 'k' for 'k_shortest_path_yen' must be a constant"))?
.ok_or_else(|| miette!("option 'k' for 'k_shortest_path_yen' must be a constant"))?
.get_int()
.ok_or_else(|| anyhow!("option 'k' for 'k_shortest_path_yen' must be an integer"))?;
.ok_or_else(|| miette!("option 'k' for 'k_shortest_path_yen' must be an integer"))?;
ensure!(
k > 1,
"option 'k' for 'k_shortest_path_yen' must be greater than 1"
@ -59,7 +59,7 @@ impl AlgoImpl for KShortestPathYen {
let node = tuple
.0
.get(0)
.ok_or_else(|| anyhow!("node relation too short"))?;
.ok_or_else(|| miette!("node relation too short"))?;
if let Some(idx) = inv_indices.get(node) {
starting_nodes.insert(*idx);
}
@ -70,7 +70,7 @@ impl AlgoImpl for KShortestPathYen {
let node = tuple
.0
.get(0)
.ok_or_else(|| anyhow!("node relation too short"))?;
.ok_or_else(|| miette!("node relation too short"))?;
if let Some(idx) = inv_indices.get(node) {
termination_nodes.insert(*idx);
}

@ -1,7 +1,7 @@
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::{Debug, Formatter};
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result};
use crate::data::value::DataValue;
@ -620,7 +620,7 @@ impl NormalAggrObj for AggrChoice {
}
fn get(&self) -> Result<DataValue> {
self.found.clone().ok_or_else(|| anyhow!("empty choice"))
self.found.clone().ok_or_else(|| miette!("empty choice"))
}
}
@ -1124,7 +1124,7 @@ impl Aggregation {
AggrStrJoin::default()
} else {
let arg = args[0].get_string().ok_or_else(|| {
anyhow!(
miette!(
"the argument to 'str_join' must be a string, got {:?}",
args[0]
)
@ -1137,7 +1137,7 @@ impl Aggregation {
AggrCollect::default()
} else {
let arg = args[0].get_int().ok_or_else(|| {
anyhow!(
miette!(
"the argument to 'collect' must be an integer, got {:?}",
args[0]
)

@ -1,6 +1,6 @@
use std::fmt::{Display, Formatter};
use anyhow::{anyhow, bail, Result};
use miette::{miette, bail, Result, IntoDiagnostic};
use rmp_serde::Serializer;
use serde::Serialize;
use smallvec::SmallVec;
@ -48,7 +48,7 @@ impl Display for AttributeCardinality {
}
impl TryFrom<&'_ str> for AttributeCardinality {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ str) -> std::result::Result<Self, Self::Error> {
Ok(match value {
"one" => AttributeCardinality::One,
@ -103,7 +103,7 @@ impl Display for AttributeTyping {
}
impl TryFrom<&'_ str> for AttributeTyping {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ str) -> std::result::Result<Self, Self::Error> {
use AttributeTyping::*;
Ok(match value {
@ -121,8 +121,8 @@ impl TryFrom<&'_ str> for AttributeTyping {
}
impl AttributeTyping {
fn type_err(&self, val: DataValue) -> anyhow::Error {
anyhow!("cannot coerce {:?} to {:?}", val, self)
fn type_err(&self, val: DataValue) -> miette::Error {
miette!("cannot coerce {:?} to {:?}", val, self)
}
pub(crate) fn coerce_value(&self, val: DataValue) -> Result<DataValue> {
match self {
@ -206,7 +206,7 @@ impl Display for AttributeIndex {
}
impl TryFrom<&'_ str> for AttributeIndex {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ str) -> std::result::Result<Self, Self::Error> {
use AttributeIndex::*;
Ok(match value {
@ -246,7 +246,7 @@ impl Attribute {
EncodedVec { inner }
}
pub(crate) fn decode(data: &[u8]) -> Result<Self> {
Ok(rmp_serde::from_slice(data)?)
Ok(rmp_serde::from_slice(data).into_diagnostic()?)
}
pub(crate) fn coerce_value(&self, value: DataValue, ctx: &mut TempIdCtx) -> Result<DataValue> {
if self.val_type.is_ref_type() {

@ -1,7 +1,7 @@
use std::fmt::{Debug, Formatter};
use std::ops::{Deref, DerefMut};
use anyhow::{bail, Result};
use miette::{bail, IntoDiagnostic, Result};
use rmp_serde::Serializer;
use serde::Serialize;
use smallvec::SmallVec;
@ -184,7 +184,7 @@ impl From<&'_ [u8]> for EncodedVec<LARGE_VEC_SIZE> {
}
impl TryFrom<u8> for StorageTag {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: u8) -> std::result::Result<Self, Self::Error> {
use StorageTag::*;
Ok(match value {
@ -211,17 +211,17 @@ pub(crate) const VEC_SIZE_8: usize = 8;
#[inline]
pub(crate) fn decode_value(src: &[u8]) -> Result<DataValue> {
Ok(rmp_serde::from_slice(src)?)
Ok(rmp_serde::from_slice(src).into_diagnostic()?)
}
#[inline]
pub(crate) fn decode_value_from_key(src: &[u8]) -> Result<DataValue> {
Ok(rmp_serde::from_slice(&src[VEC_SIZE_24..])?)
Ok(rmp_serde::from_slice(&src[VEC_SIZE_24..]).into_diagnostic()?)
}
#[inline]
pub(crate) fn decode_value_from_val(src: &[u8]) -> Result<DataValue> {
Ok(rmp_serde::from_slice(&src[VEC_SIZE_8..])?)
Ok(rmp_serde::from_slice(&src[VEC_SIZE_8..]).into_diagnostic()?)
}
/// eid: 8 bytes (incl. tag)
@ -421,7 +421,7 @@ pub(crate) fn encode_sentinel_attr_val(aid: AttrId, val: &DataValue) -> EncodedV
#[inline]
pub(crate) fn decode_sentinel_attr_val(src: &[u8]) -> Result<(AttrId, DataValue)> {
let a_id = AttrId::from_bytes(&src[..VEC_SIZE_8]);
let val = rmp_serde::from_slice(&src[VEC_SIZE_8..])?;
let val = rmp_serde::from_slice(&src[VEC_SIZE_8..]).into_diagnostic()?;
Ok((a_id, val))
}

@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet};
use std::fmt::{Debug, Formatter};
use std::mem;
use anyhow::{anyhow, bail, Result};
use miette::{miette, bail, Result};
use itertools::Itertools;
use smartstring::SmartString;
@ -57,7 +57,7 @@ impl Expr {
match self {
Expr::Binding(k, idx) => {
let found_idx = *binding_map.get(k).ok_or_else(|| {
anyhow!("cannot find binding {}, this indicates a system error", k)
miette!("cannot find binding {}, this indicates a system error", k)
})?;
*idx = Some(found_idx)
}
@ -95,7 +95,7 @@ impl Expr {
Some(
param_pool
.get(s)
.ok_or_else(|| anyhow!("input parameter {} not found", s))?,
.ok_or_else(|| miette!("input parameter {} not found", s))?,
)
} else {
None
@ -177,7 +177,7 @@ impl Expr {
Expr::Binding(b, Some(i)) => Ok(bindings
.0
.get(*i)
.ok_or_else(|| anyhow!("binding '{}' not found in tuple (too short)", b))?
.ok_or_else(|| miette!("binding '{}' not found in tuple (too short)", b))?
.clone()),
Expr::Const(d) => Ok(d.clone()),
Expr::Apply(op, args) => {
@ -236,7 +236,7 @@ impl Expr {
if let Some(val) = args[1].get_const() {
if target == symb {
let s = val.get_string().ok_or_else(|| {
anyhow!("unexpected arg {:?} for OP_STARTS_WITH", val)
miette!("unexpected arg {:?} for OP_STARTS_WITH", val)
})?;
let lower = DataValue::Str(SmartString::from(s));
// let lower = DataValue::Str(s.to_string());

@ -1,7 +1,7 @@
use std::ops::{Div, Rem};
use std::str::FromStr;
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result, IntoDiagnostic};
use itertools::Itertools;
use num_traits::FloatConst;
use rand::prelude::*;
@ -43,7 +43,7 @@ pub(crate) fn op_is_in(args: &[DataValue]) -> Result<DataValue> {
let left = &args[0];
let right = args[1]
.get_list()
.ok_or_else(|| anyhow!("right hand side of 'is_in' is not a list"))?;
.ok_or_else(|| miette!("right hand side of 'is_in' is not a list"))?;
Ok(DataValue::Bool(right.contains(left)))
}
@ -800,7 +800,7 @@ define_op!(OP_REGEX, 1, false);
pub(crate) fn op_regex(args: &[DataValue]) -> Result<DataValue> {
Ok(match &args[0] {
r @ DataValue::Regex(_) => r.clone(),
DataValue::Str(s) => DataValue::Regex(RegexWrapper(regex::Regex::new(s)?)),
DataValue::Str(s) => DataValue::Regex(RegexWrapper(regex::Regex::new(s).into_diagnostic()?)),
v => bail!("cannot apply 'regex' to {:?}", v),
})
}
@ -980,7 +980,7 @@ define_op!(OP_SORTED, 1, false);
pub(crate) fn op_sorted(args: &[DataValue]) -> Result<DataValue> {
let mut arg = args[0]
.get_list()
.ok_or_else(|| anyhow!("cannot apply 'sort' to {:?}", args))?
.ok_or_else(|| miette!("cannot apply 'sort' to {:?}", args))?
.to_vec();
arg.sort();
Ok(DataValue::List(arg))
@ -990,7 +990,7 @@ define_op!(OP_REVERSE, 1, false);
pub(crate) fn op_reverse(args: &[DataValue]) -> Result<DataValue> {
let mut arg = args[0]
.get_list()
.ok_or_else(|| anyhow!("cannot apply 'reverse' to {:?}", args))?
.ok_or_else(|| miette!("cannot apply 'reverse' to {:?}", args))?
.to_vec();
arg.reverse();
Ok(DataValue::List(arg))
@ -998,7 +998,7 @@ pub(crate) fn op_reverse(args: &[DataValue]) -> Result<DataValue> {
define_op!(OP_HAVERSINE, 4, false);
pub(crate) fn op_haversine(args: &[DataValue]) -> Result<DataValue> {
let gen_err = || anyhow!("cannot computer haversine distance for {:?}", args);
let gen_err = || miette!("cannot computer haversine distance for {:?}", args);
let lat1 = args[0].get_float().ok_or_else(gen_err)?;
let lon1 = args[1].get_float().ok_or_else(gen_err)?;
let lat2 = args[2].get_float().ok_or_else(gen_err)?;
@ -1013,7 +1013,7 @@ pub(crate) fn op_haversine(args: &[DataValue]) -> Result<DataValue> {
define_op!(OP_HAVERSINE_DEG_INPUT, 4, false);
pub(crate) fn op_haversine_deg_input(args: &[DataValue]) -> Result<DataValue> {
let gen_err = || anyhow!("cannot computer haversine distance for {:?}", args);
let gen_err = || miette!("cannot computer haversine distance for {:?}", args);
let lat1 = args[0].get_float().ok_or_else(gen_err)? * f64::PI() / 180.;
let lon1 = args[1].get_float().ok_or_else(gen_err)? * f64::PI() / 180.;
let lat2 = args[2].get_float().ok_or_else(gen_err)? * f64::PI() / 180.;
@ -1030,7 +1030,7 @@ define_op!(OP_DEG_TO_RAD, 1, false);
pub(crate) fn op_deg_to_rad(args: &[DataValue]) -> Result<DataValue> {
let x = args[0]
.get_float()
.ok_or_else(|| anyhow!("cannot convert to radian: {:?}", args))?;
.ok_or_else(|| miette!("cannot convert to radian: {:?}", args))?;
Ok(DataValue::from(x * f64::PI() / 180.))
}
@ -1038,7 +1038,7 @@ define_op!(OP_RAD_TO_DEG, 1, false);
pub(crate) fn op_rad_to_deg(args: &[DataValue]) -> Result<DataValue> {
let x = args[0]
.get_float()
.ok_or_else(|| anyhow!("cannot convert to degrees: {:?}", args))?;
.ok_or_else(|| miette!("cannot convert to degrees: {:?}", args))?;
Ok(DataValue::from(x * 180. / f64::PI()))
}
@ -1046,7 +1046,7 @@ define_op!(OP_FIRST, 1, false);
pub(crate) fn op_first(args: &[DataValue]) -> Result<DataValue> {
Ok(args[0]
.get_list()
.ok_or_else(|| anyhow!("cannot compute 'first' of {:?}", args))?
.ok_or_else(|| miette!("cannot compute 'first' of {:?}", args))?
.first()
.cloned()
.unwrap_or(DataValue::Null))
@ -1056,7 +1056,7 @@ define_op!(OP_LAST, 1, false);
pub(crate) fn op_last(args: &[DataValue]) -> Result<DataValue> {
Ok(args[0]
.get_list()
.ok_or_else(|| anyhow!("cannot compute 'last' of {:?}", args))?
.ok_or_else(|| miette!("cannot compute 'last' of {:?}", args))?
.last()
.cloned()
.unwrap_or(DataValue::Null))
@ -1065,13 +1065,13 @@ pub(crate) fn op_last(args: &[DataValue]) -> Result<DataValue> {
define_op!(OP_CHUNKS, 2, false);
pub(crate) fn op_chunks(args: &[DataValue]) -> Result<DataValue> {
let arg = args[0].get_list().ok_or_else(|| {
anyhow!(
miette!(
"first argument of 'chunks' must be a list, got {:?}",
args[0]
)
})?;
let n = args[1].get_int().ok_or_else(|| {
anyhow!(
miette!(
"second argument of 'chunks' must be an integer, got {:?}",
args[1]
)
@ -1091,13 +1091,13 @@ pub(crate) fn op_chunks(args: &[DataValue]) -> Result<DataValue> {
define_op!(OP_CHUNKS_EXACT, 2, false);
pub(crate) fn op_chunks_exact(args: &[DataValue]) -> Result<DataValue> {
let arg = args[0].get_list().ok_or_else(|| {
anyhow!(
miette!(
"first argument of 'chunks_exact' must be a list, got {:?}",
args[0]
)
})?;
let n = args[1].get_int().ok_or_else(|| {
anyhow!(
miette!(
"second argument of 'chunks_exact' must be an integer, got {:?}",
args[1]
)
@ -1117,13 +1117,13 @@ pub(crate) fn op_chunks_exact(args: &[DataValue]) -> Result<DataValue> {
define_op!(OP_WINDOWS, 2, false);
pub(crate) fn op_windows(args: &[DataValue]) -> Result<DataValue> {
let arg = args[0].get_list().ok_or_else(|| {
anyhow!(
miette!(
"first argument of 'windows' must be a list, got {:?}",
args[0]
)
})?;
let n = args[1].get_int().ok_or_else(|| {
anyhow!(
miette!(
"second argument of 'windows' must be an integer, got {:?}",
args[1]
)
@ -1160,9 +1160,9 @@ define_op!(OP_GET, 2, false);
pub(crate) fn op_get(args: &[DataValue]) -> Result<DataValue> {
let l = args[0]
.get_list()
.ok_or_else(|| anyhow!("first argument to 'get' mut be a list, got args {:?}", args))?;
.ok_or_else(|| miette!("first argument to 'get' mut be a list, got args {:?}", args))?;
let n = args[1].get_int().ok_or_else(|| {
anyhow!(
miette!(
"second argument to 'get' mut be an integer, got args {:?}",
args
)
@ -1174,13 +1174,13 @@ pub(crate) fn op_get(args: &[DataValue]) -> Result<DataValue> {
define_op!(OP_MAYBE_GET, 2, false);
pub(crate) fn op_maybe_get(args: &[DataValue]) -> Result<DataValue> {
let l = args[0].get_list().ok_or_else(|| {
anyhow!(
miette!(
"first argument to 'maybe_get' mut be a list, got args {:?}",
args
)
})?;
let n = args[1].get_int().ok_or_else(|| {
anyhow!(
miette!(
"second argument to 'maybe_get' mut be an integer, got args {:?}",
args
)
@ -1195,19 +1195,19 @@ pub(crate) fn op_maybe_get(args: &[DataValue]) -> Result<DataValue> {
define_op!(OP_SLICE, 3, false);
pub(crate) fn op_slice(args: &[DataValue]) -> Result<DataValue> {
let l = args[0].get_list().ok_or_else(|| {
anyhow!(
miette!(
"first argument to 'slice' mut be a list, got args {:?}",
args
)
})?;
let m = args[1].get_int().ok_or_else(|| {
anyhow!(
miette!(
"second argument to 'slice' mut be an integer, got args {:?}",
args
)
})?;
let n = args[2].get_int().ok_or_else(|| {
anyhow!(
miette!(
"third argument to 'slice' mut be an integer, got args {:?}",
args
)
@ -1222,7 +1222,7 @@ pub(crate) fn op_chars(args: &[DataValue]) -> Result<DataValue> {
Ok(DataValue::List(
args[0]
.get_string()
.ok_or_else(|| anyhow!("'chars' can only be applied to string, got {:?}", args))?
.ok_or_else(|| miette!("'chars' can only be applied to string, got {:?}", args))?
.chars()
.map(|c| {
let mut s = SmartString::new();
@ -1267,7 +1267,7 @@ define_op!(OP_DECODE_BASE64, 1, false);
pub(crate) fn op_decode_base64(args: &[DataValue]) -> Result<DataValue> {
match &args[0] {
DataValue::Str(s) => {
let b = base64::decode(s)?;
let b = base64::decode(s).into_diagnostic()?;
Ok(DataValue::Bytes(b.into()))
}
v => bail!("'decode_base64' can only be applied to string, got {:?}", v),
@ -1284,7 +1284,7 @@ pub(crate) fn op_to_float(args: &[DataValue]) -> Result<DataValue> {
"NAN" => f64::NAN.into(),
"INF" => f64::INFINITY.into(),
"NEG_INF" => f64::NEG_INFINITY.into(),
s => f64::from_str(s)?.into(),
s => f64::from_str(s).into_diagnostic()?.into(),
},
v => bail!("'to_float' cannot be applied to {:?}", v),
})
@ -1318,13 +1318,13 @@ pub(crate) fn op_rand_bernoulli(args: &[DataValue]) -> Result<DataValue> {
define_op!(OP_RAND_INT, 2, false);
pub(crate) fn op_rand_int(args: &[DataValue]) -> Result<DataValue> {
let lower = &args[0].get_int().ok_or_else(|| {
anyhow!(
miette!(
"first argument to 'rand_int' must be an integer, got args {:?}",
args
)
})?;
let upper = &args[1].get_int().ok_or_else(|| {
anyhow!(
miette!(
"second argument to 'rand_int' must be an integer, got args {:?}",
args
)

@ -1,7 +1,7 @@
use std::fmt::{Debug, Formatter};
use std::time::{SystemTime, UNIX_EPOCH};
use anyhow::bail;
use miette::{bail, IntoDiagnostic};
use chrono::{DateTime, TimeZone, Utc};
use serde_derive::{Deserialize, Serialize};
@ -40,11 +40,11 @@ impl From<i64> for Validity {
}
impl TryFrom<&str> for Validity {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &str) -> Result<Self, Self::Error> {
let dt =
DateTime::parse_from_rfc2822(value).or_else(|_| DateTime::parse_from_rfc3339(value))?;
DateTime::parse_from_rfc2822(value).or_else(|_| DateTime::parse_from_rfc3339(value)).into_diagnostic()?;
let sysdt: SystemTime = dt.into();
let timestamp = sysdt.duration_since(UNIX_EPOCH).unwrap().as_micros() as i64;
Ok(Self(timestamp))
@ -52,7 +52,7 @@ impl TryFrom<&str> for Validity {
}
impl TryFrom<&JsonValue> for Validity {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &JsonValue) -> Result<Self, Self::Error> {
if let Some(v) = value.as_i64() {

@ -1,4 +1,4 @@
use anyhow::{anyhow, ensure};
use miette::{miette, ensure};
use serde_json::json;
pub(crate) use serde_json::Value as JsonValue;
@ -99,42 +99,42 @@ impl From<DataValue> for JsonValue {
}
impl TryFrom<&'_ JsonValue> for Symbol {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ JsonValue) -> Result<Self, Self::Error> {
let s = value
.as_str()
.ok_or_else(|| anyhow!("failed to convert {} to a symbol", value))?;
.ok_or_else(|| miette!("failed to convert {} to a symbol", value))?;
Ok(Symbol::from(s))
}
}
impl TryFrom<&'_ JsonValue> for Attribute {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ JsonValue) -> Result<Self, Self::Error> {
let map = value
.as_object()
.ok_or_else(|| anyhow!("expect object in attribute definition, got {}", value))?;
.ok_or_else(|| miette!("expect object in attribute definition, got {}", value))?;
let id = match map.get("id") {
None => AttrId(0),
Some(v) => AttrId::try_from(v)?,
};
let name = map
.get("name")
.ok_or_else(|| anyhow!("expect field 'name' in attribute definition, got {}", value))?;
.ok_or_else(|| miette!("expect field 'name' in attribute definition, got {}", value))?;
let symb = Symbol::try_from(name)?;
ensure!(!symb.is_reserved(), "cannot use reserved symbol {}", symb);
let cardinality = map
.get("cardinality")
.ok_or_else(|| anyhow!("expect field 'cardinality' in {}", value))?
.ok_or_else(|| miette!("expect field 'cardinality' in {}", value))?
.as_str()
.ok_or_else(|| anyhow!("expect field 'cardinality' to be a string, got {}", value))?;
.ok_or_else(|| miette!("expect field 'cardinality' to be a string, got {}", value))?;
let cardinality = AttributeCardinality::try_from(cardinality)?;
let val_type = map
.get("type")
.ok_or_else(|| anyhow!("expect field 'type' in {}", value))?
.ok_or_else(|| miette!("expect field 'type' in {}", value))?
.as_str()
.ok_or_else(|| anyhow!("expect field 'type' in {} to be a string", value))?;
.ok_or_else(|| miette!("expect field 'type' in {} to be a string", value))?;
let val_type = AttributeTyping::try_from(val_type)?;
let indexing = match map.get("index") {
@ -143,7 +143,7 @@ impl TryFrom<&'_ JsonValue> for Attribute {
Some(JsonValue::Bool(false)) => AttributeIndex::None,
Some(v) => AttributeIndex::try_from(
v.as_str()
.ok_or_else(|| anyhow!("cannot convert {} to attribute indexing", v))?,
.ok_or_else(|| miette!("cannot convert {} to attribute indexing", v))?,
)?,
};
@ -151,7 +151,7 @@ impl TryFrom<&'_ JsonValue> for Attribute {
None => false,
Some(v) => v
.as_bool()
.ok_or_else(|| anyhow!("cannot convert {} to attribute with history flag", v))?,
.ok_or_else(|| miette!("cannot convert {} to attribute with history flag", v))?,
};
Ok(Attribute {
@ -185,12 +185,12 @@ impl From<AttrId> for JsonValue {
}
impl TryFrom<&'_ JsonValue> for AttrId {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ JsonValue) -> Result<Self, Self::Error> {
let v = value
.as_u64()
.ok_or_else(|| anyhow!("cannot convert {} to attr id", value))?;
.ok_or_else(|| miette!("cannot convert {} to attr id", value))?;
Ok(AttrId(v))
}
}
@ -202,12 +202,12 @@ impl From<EntityId> for JsonValue {
}
impl TryFrom<&'_ JsonValue> for EntityId {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ JsonValue) -> Result<Self, Self::Error> {
let v = value
.as_u64()
.ok_or_else(|| anyhow!("cannot convert {} to entity id", value))?;
.ok_or_else(|| miette!("cannot convert {} to entity id", value))?;
Ok(EntityId(v))
}
}
@ -219,12 +219,12 @@ impl From<TxId> for JsonValue {
}
impl TryFrom<&'_ JsonValue> for TxId {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ JsonValue) -> Result<Self, Self::Error> {
let v = value
.as_u64()
.ok_or_else(|| anyhow!("cannot convert {} to tx id", value))?;
.ok_or_else(|| miette!("cannot convert {} to tx id", value))?;
Ok(TxId(v))
}
}

@ -2,7 +2,7 @@ use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::{Debug, Formatter};
use anyhow::{anyhow, bail, Result};
use miette::{miette, bail, Result};
use either::{Left, Right};
use smallvec::SmallVec;
use smartstring::{LazyCompact, SmartString};
@ -138,7 +138,7 @@ impl InputProgram {
match self
.prog
.get(&PROG_ENTRY)
.ok_or_else(|| anyhow!("program entry point not found"))?
.ok_or_else(|| miette!("program entry point not found"))?
{
InputRulesOrAlgo::Rules(rules) => Ok(&rules.last().unwrap().head),
InputRulesOrAlgo::Algo(_) => {

@ -1,6 +1,6 @@
use std::fmt::{Debug, Display, Formatter};
use anyhow::{ensure, Result};
use miette::{ensure, IntoDiagnostic, Result};
use lazy_static::lazy_static;
use serde_derive::{Deserialize, Serialize};
use smartstring::{LazyCompact, SmartString};
@ -27,9 +27,9 @@ impl From<&str> for Symbol {
}
impl TryFrom<&[u8]> for Symbol {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
Ok(std::str::from_utf8(value)?.into())
Ok(Symbol::from(std::str::from_utf8(value).into_diagnostic()?))
}
}

@ -1,6 +1,6 @@
use std::fmt::{Display, Formatter};
use anyhow::bail;
use miette::bail;
use serde_derive::{Deserialize, Serialize};
#[repr(u8)]
@ -29,7 +29,7 @@ impl StoreOp {
}
impl TryFrom<u8> for StoreOp {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(u: u8) -> Result<Self, Self::Error> {
Ok(match u {

@ -1,7 +1,7 @@
use std::cmp::{max, min, Ordering};
use std::fmt::{Debug, Formatter};
use anyhow::{ensure, Result};
use miette::{ensure, IntoDiagnostic, Result};
use itertools::Itertools;
use rmp_serde::Serializer;
use serde::Serialize;
@ -157,7 +157,7 @@ impl<'a> EncodedTuple<'a> {
"bad data length for data: {:x?}",
self.0
);
Ok(rmp_serde::from_slice(&self.0[pos..])?)
Ok(rmp_serde::from_slice(&self.0[pos..]).into_diagnostic()?)
}
pub(crate) fn iter(&self) -> EncodedTupleIter<'a> {

@ -3,7 +3,7 @@ use std::collections::BTreeSet;
use std::fmt::{Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use anyhow::{bail, Result};
use miette::{bail, Result};
use ordered_float::OrderedFloat;
use regex::Regex;
use rmp_serde::Serializer;

@ -1,6 +1,6 @@
#![warn(rust_2018_idioms, future_incompatible)]
pub use anyhow::Error;
pub use miette::Error;
pub use cozorocks::DbBuilder;
pub use data::encode::EncodedVec;

@ -1,7 +1,7 @@
use std::borrow::BorrowMut;
use std::str::FromStr;
use anyhow::{anyhow, Result};
use miette::{miette, Result, IntoDiagnostic};
use itertools::Itertools;
use lazy_static::lazy_static;
use pest::prec_climber::{Assoc, Operator, PrecClimber};
@ -25,7 +25,7 @@ pub(crate) enum ScriptType {
}
pub(crate) fn parse_query_to_json(src: &str) -> Result<(ScriptType, JsonValue)> {
let parsed = CozoScriptParser::parse(Rule::script, src)?.next().unwrap();
let parsed = CozoScriptParser::parse(Rule::script, src).into_diagnostic()?.next().unwrap();
Ok(match parsed.as_rule() {
Rule::query_script => (
ScriptType::Query,
@ -38,7 +38,7 @@ pub(crate) fn parse_query_to_json(src: &str) -> Result<(ScriptType, JsonValue)>
Rule::tx_script => (ScriptType::Tx, parsed_tx_to_json(parsed.into_inner())?),
Rule::sys_script => {
let opts = parsed_db_op_to_enum(parsed.into_inner())?;
let opts = serde_json::to_value(&opts)?;
let opts = serde_json::to_value(&opts).into_diagnostic()?;
(ScriptType::Sys, opts)
}
_ => unreachable!(),
@ -63,7 +63,7 @@ fn parsed_query_to_json(src: Pairs<'_>) -> Result<JsonValue> {
let data = build_expr::<WrapConst>(src.next().unwrap())?;
let data = data
.as_array()
.ok_or_else(|| anyhow!("expect const rules to be specified as an array"))?;
.ok_or_else(|| miette!("expect const rules to be specified as an array"))?;
let entries = const_rules
.entry(name.to_string())
.or_insert_with(|| json!([]))
@ -228,7 +228,7 @@ fn parse_limit_or_offset(src: Pair<'_>) -> Result<usize> {
}
fn str2usize(src: &str) -> Result<usize> {
Ok(usize::from_str(&src.replace('_', ""))?)
Ok(usize::from_str(&src.replace('_', "")).into_diagnostic()?)
}
fn parse_algo_rule(src: Pair<'_>) -> Result<JsonValue> {
@ -514,7 +514,7 @@ fn build_unary<W: ShouldWrap>(pair: Pair<'_>) -> Result<JsonValue> {
json!({"op": "negate", "args": [inner]})
}
Rule::pos_int => {
let i = s.replace('_', "").parse::<i64>()?;
let i = s.replace('_', "").parse::<i64>().into_diagnostic()?;
json!(i)
}
Rule::hex_pos_int => {
@ -530,7 +530,7 @@ fn build_unary<W: ShouldWrap>(pair: Pair<'_>) -> Result<JsonValue> {
json!(i)
}
Rule::dot_float | Rule::sci_float => {
let f = s.replace('_', "").parse::<f64>()?;
let f = s.replace('_', "").parse::<f64>().into_diagnostic()?;
json!(f)
}
Rule::null => JsonValue::Null,

@ -1,4 +1,4 @@
use anyhow::{bail, Result};
use miette::{bail, Result};
use serde_json::{json, Map};
use crate::data::json::JsonValue;

@ -1,4 +1,4 @@
use anyhow::{anyhow, bail, Result};
use miette::{miette, bail, Result};
use crate::parse::cozoscript::number::parse_int;
use crate::parse::cozoscript::Pair;
@ -31,7 +31,7 @@ fn parse_quoted_string(pair: Pair<'_>) -> Result<String> {
s if s.starts_with(r"\u") => {
let code = parse_int(s, 16) as u32;
let ch =
char::from_u32(code).ok_or_else(|| anyhow!("invalid UTF8 code {}", code))?;
char::from_u32(code).ok_or_else(|| miette!("invalid UTF8 code {}", code))?;
ret.push(ch);
}
s if s.starts_with('\\') => {
@ -60,7 +60,7 @@ fn parse_s_quoted_string(pair: Pair<'_>) -> Result<String> {
s if s.starts_with(r"\u") => {
let code = parse_int(s, 16) as u32;
let ch =
char::from_u32(code).ok_or_else(|| anyhow!("invalid UTF8 code {}", code))?;
char::from_u32(code).ok_or_else(|| miette!("invalid UTF8 code {}", code))?;
ret.push(ch);
}
s if s.starts_with('\\') => {

@ -1,6 +1,6 @@
use std::collections::BTreeSet;
use anyhow::Result;
use miette::{IntoDiagnostic, Result};
use crate::data::symb::Symbol;
use crate::parse::cozoscript::{Pairs, Rule};
@ -48,7 +48,7 @@ pub(crate) fn parsed_db_op_to_enum(mut src: Pairs<'_>) -> Result<SysOp> {
Rule::running_op => SysOp::ListRunning,
Rule::kill_op => {
let i_str = inner.into_inner().next().unwrap().as_str();
let i = u64::from_str_radix(i_str, 10)?;
let i = u64::from_str_radix(i_str, 10).into_diagnostic()?;
SysOp::KillRunning(i)
}
Rule::list_schema_op => SysOp::ListSchema,

@ -1,6 +1,6 @@
use std::str::FromStr;
use anyhow::Result;
use miette::{IntoDiagnostic, Result};
use itertools::Itertools;
use serde_json::json;
@ -58,7 +58,7 @@ fn parse_tx_el(src: Pair<'_>) -> Result<JsonValue> {
Rule::tx_map => parse_tx_map(src),
Rule::tx_list => parse_tx_list(src),
Rule::expr => build_expr::<NoWrapConst>(src),
Rule::neg_num => Ok(JsonValue::from_str(src.as_str())?),
Rule::neg_num => Ok(JsonValue::from_str(src.as_str()).into_diagnostic()?),
_ => unreachable!(),
}
}

@ -1,6 +1,6 @@
use std::cmp::max;
use anyhow::{anyhow, bail, Result};
use miette::{miette, bail, Result};
use itertools::Itertools;
use serde_json::Map;
@ -43,7 +43,7 @@ impl SessionTx {
};
let attr = self
.attr_by_name(&symb)?
.ok_or_else(|| anyhow!("attribute {} not found", symb))?;
.ok_or_else(|| miette!("attribute {} not found", symb))?;
let cardinality = attr.cardinality;
Ok(PullSpec::Attr(AttrPullSpec {
attr,
@ -83,25 +83,25 @@ impl SessionTx {
"as" => {
as_override =
Some(Symbol::from(v.as_str().ok_or_else(|| {
anyhow!("expect 'as' field to be string, got {}", v)
miette!("expect 'as' field to be string, got {}", v)
})?))
}
"limit" => {
take = Some(v.as_u64().ok_or_else(|| {
anyhow!("expect 'limit field to be non-negative integer, got {}", v)
miette!("expect 'limit field to be non-negative integer, got {}", v)
})? as usize)
}
"cardinality" => {
cardinality_override =
Some(AttributeCardinality::try_from(v.as_str().ok_or_else(
|| anyhow!("expect 'cardinality' field to be string, got {}", v),
|| miette!("expect 'cardinality' field to be string, got {}", v),
)?)?)
}
"default" => default_val = DataValue::from(v),
"pull" => {
let v = v
.as_str()
.ok_or_else(|| anyhow!("expect 'pull' field to be string, got {}", v))?;
.ok_or_else(|| miette!("expect 'pull' field to be string, got {}", v))?;
if v == "_id" {
pull_id = true
} else {
@ -125,7 +125,7 @@ impl SessionTx {
}
"depth" => {
recursion_depth = v.as_u64().ok_or_else(|| {
anyhow!("expect 'depth' field to be non-negative integer, got {}", v)
miette!("expect 'depth' field to be non-negative integer, got {}", v)
})? as usize
}
"spec" => {
@ -163,7 +163,7 @@ impl SessionTx {
};
let attr = self
.attr_by_name(&symb)?
.ok_or_else(|| anyhow!("attribute not found: {}", symb))?;
.ok_or_else(|| miette!("attribute not found: {}", symb))?;
let cardinality = cardinality_override.unwrap_or(attr.cardinality);
let nested = self.parse_pull(&JsonValue::Array(sub_target), depth + 1)?;

@ -1,7 +1,7 @@
use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, BTreeSet};
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result};
use itertools::Itertools;
use serde_json::{json, Map};
@ -34,7 +34,7 @@ pub(crate) enum SortDir {
}
impl TryFrom<&'_ JsonValue> for SortDir {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ JsonValue) -> std::result::Result<Self, Self::Error> {
match value {
@ -88,7 +88,7 @@ pub(crate) type ConstRules = BTreeMap<MagicSymbol, Vec<Tuple>>;
fn get_entry_head(prog: &BTreeMap<Symbol, InputRulesOrAlgo>) -> Result<&[Symbol]> {
match prog
.get(&PROG_ENTRY)
.ok_or_else(|| anyhow!("program entry point not found"))?
.ok_or_else(|| miette!("program entry point not found"))?
{
InputRulesOrAlgo::Rules(rules) => Ok(&rules.last().unwrap().head),
InputRulesOrAlgo::Algo(_) => {
@ -100,7 +100,7 @@ fn get_entry_head(prog: &BTreeMap<Symbol, InputRulesOrAlgo>) -> Result<&[Symbol]
fn validate_entry(prog: &BTreeMap<Symbol, InputRulesOrAlgo>) -> Result<()> {
match prog
.get(&PROG_ENTRY)
.ok_or_else(|| anyhow!("program entry point not found"))?
.ok_or_else(|| miette!("program entry point not found"))?
{
InputRulesOrAlgo::Rules(r) => {
ensure!(
@ -117,7 +117,7 @@ fn get_entry_arity(prog: &BTreeMap<Symbol, InputRulesOrAlgo>) -> Result<usize> {
Ok(
match prog
.get(&PROG_ENTRY)
.ok_or_else(|| anyhow!("program entry point not found"))?
.ok_or_else(|| miette!("program entry point not found"))?
{
InputRulesOrAlgo::Rules(rules) => rules[0].head.len(),
InputRulesOrAlgo::Algo(algo_apply) => algo_apply.arity()?,
@ -137,10 +137,10 @@ impl SessionTx {
};
let q = payload
.get("q")
.ok_or_else(|| anyhow!("expect field 'q' in query {}", payload))?;
.ok_or_else(|| miette!("expect field 'q' in query {}", payload))?;
let rules_payload = q
.as_array()
.ok_or_else(|| anyhow!("expect field 'q' to be an array in query {}", payload))?;
.ok_or_else(|| miette!("expect field 'q' to be an array in query {}", payload))?;
let mut prog = if rules_payload.is_empty() {
Default::default()
} else if rules_payload.first().unwrap().is_array() {
@ -160,12 +160,12 @@ impl SessionTx {
let limit = swap_result_option(payload.get("limit").map(|v| {
v.as_u64()
.map(|v| v as usize)
.ok_or_else(|| anyhow!("'limit' must be a positive number"))
.ok_or_else(|| miette!("'limit' must be a positive number"))
}))?;
let offset = swap_result_option(payload.get("offset").map(|v| {
v.as_u64()
.map(|v| v as usize)
.ok_or_else(|| anyhow!("'offset' must be a positive number"))
.ok_or_else(|| miette!("'offset' must be a positive number"))
}))?;
let timeout = match payload.get("timeout") {
None => None,
@ -174,7 +174,7 @@ impl SessionTx {
match expr.eval(&Tuple::default())? {
DataValue::Num(n) => {
let i = n.get_int().ok_or_else(|| {
anyhow!(":timeout requires seconds as argument, got {}", n)
miette!(":timeout requires seconds as argument, got {}", n)
})?;
ensure!(i > 0, ":timeout must be positive, got {}", i);
Some(i as u64)
@ -186,35 +186,35 @@ impl SessionTx {
if let Some(algo_rules) = payload.get("algo_rules") {
for algo_rule in algo_rules
.as_array()
.ok_or_else(|| anyhow!("'algo_rules' must be an array"))?
.ok_or_else(|| miette!("'algo_rules' must be an array"))?
{
let out_symbol = algo_rule
.get("algo_out")
.ok_or_else(|| anyhow!("algo rule requires field 'algo_out': {}", algo_rule))?
.ok_or_else(|| miette!("algo rule requires field 'algo_out': {}", algo_rule))?
.as_str()
.ok_or_else(|| anyhow!("'algo_out' mut be a string: {}", algo_rule))?;
.ok_or_else(|| miette!("'algo_out' mut be a string: {}", algo_rule))?;
let name_symbol = algo_rule
.get("algo_name")
.ok_or_else(|| anyhow!("algo rule requires field 'algo_name': {}", algo_rule))?
.ok_or_else(|| miette!("algo rule requires field 'algo_name': {}", algo_rule))?
.as_str()
.ok_or_else(|| anyhow!("'algo_name' mut be a string: {}", algo_rule))?;
.ok_or_else(|| miette!("'algo_name' mut be a string: {}", algo_rule))?;
let mut relations = vec![];
let mut options = BTreeMap::default();
for rel_def in algo_rule
.get("relations")
.ok_or_else(|| anyhow!("'relations' field required in algo rule"))?
.ok_or_else(|| miette!("'relations' field required in algo rule"))?
.as_array()
.ok_or_else(|| anyhow!("'relations' field must be an array"))?
.ok_or_else(|| miette!("'relations' field must be an array"))?
{
let args: Vec<Symbol> = rel_def
.get("rel_args")
.ok_or_else(|| anyhow!("field 'rel_args' required in {}", rel_def))?
.ok_or_else(|| miette!("field 'rel_args' required in {}", rel_def))?
.as_array()
.ok_or_else(|| anyhow!("field 'rel_args' must be an array in {}", rel_def))?
.ok_or_else(|| miette!("field 'rel_args' must be an array in {}", rel_def))?
.iter()
.map(|v| -> Result<Symbol> {
let s = v.as_str().ok_or_else(|| {
anyhow!("element of 'rel_args' must be string, got {}", v)
miette!("element of 'rel_args' must be string, got {}", v)
})?;
let s = Symbol::from(s);
s.validate_query_var()?;
@ -224,17 +224,17 @@ impl SessionTx {
if let Some(rule_name) = rel_def.get("rule") {
let rule_name = rule_name
.as_str()
.ok_or_else(|| anyhow!("'rule' must be a string, got {}", rule_name))?;
.ok_or_else(|| miette!("'rule' must be a string, got {}", rule_name))?;
relations.push(AlgoRuleArg::InMem(Symbol::from(rule_name), args));
} else if let Some(view_name) = rel_def.get("view") {
let view_name = view_name
.as_str()
.ok_or_else(|| anyhow!("'view' must be a string, got {}", view_name))?;
.ok_or_else(|| miette!("'view' must be a string, got {}", view_name))?;
relations.push(AlgoRuleArg::Stored(Symbol::from(view_name), args));
} else if let Some(triple_name) = rel_def.get("triple") {
let attr = self.parse_triple_atom_attr(triple_name)?;
// let triple_name = triple_name.as_str().ok_or_else(|| {
// anyhow!("'triple' must be a string, got {}", triple_name)
// miette!("'triple' must be a string, got {}", triple_name)
// })?;
let dir = match rel_def.get("backward") {
None => TripleDir::Fwd,
@ -247,7 +247,7 @@ impl SessionTx {
}
if let Some(opts) = algo_rule.get("options") {
let opts = opts.as_object().ok_or_else(|| {
anyhow!("'options' is required to be a map, got {}", opts)
miette!("'options' is required to be a map, got {}", opts)
})?;
for (k, v) in opts.iter() {
let expr = Self::parse_expr_arg(v, params_pool)?;
@ -275,18 +275,18 @@ impl SessionTx {
let const_rules = if let Some(rules) = payload.get("const_rules") {
rules
.as_object()
.ok_or_else(|| anyhow!("const rules is expected to be an object"))?
.ok_or_else(|| miette!("const rules is expected to be an object"))?
.iter()
.map(|(k, v)| -> Result<(MagicSymbol, Vec<Tuple>)> {
let data: Vec<Tuple> = v
.as_array()
.ok_or_else(|| anyhow!("rules spec is expected to be an array"))?
.ok_or_else(|| miette!("rules spec is expected to be an array"))?
.iter()
.map(|v| -> Result<Tuple> {
let tuple = v
.as_array()
.ok_or_else(|| {
anyhow!("data in rule is expected to be an array, got {}", v)
miette!("data in rule is expected to be an array, got {}", v)
})?
.iter()
.map(|v| Self::parse_const_expr(v, params_pool))
@ -316,12 +316,12 @@ impl SessionTx {
.get("sort")
.unwrap_or(&json!([]))
.as_array()
.ok_or_else(|| anyhow!("'sort' is expected to be an array"))?
.ok_or_else(|| miette!("'sort' is expected to be an array"))?
.iter()
.map(|sorter| -> Result<(Symbol, SortDir)> {
let sorter = sorter
.as_object()
.ok_or_else(|| anyhow!("'sort' must be an array of objects"))?;
.ok_or_else(|| miette!("'sort' must be an array of objects"))?;
ensure!(
sorter.len() == 1,
"'sort' spec must be an object of a single pair"
@ -363,7 +363,7 @@ impl SessionTx {
let opts = view_payload
.as_object()
.ok_or_else(|| anyhow!("view options must be an object"))?;
.ok_or_else(|| miette!("view options must be an object"))?;
let (op, name) = if let Some(name) = opts.get("create") {
(ViewOp::Create, name)
} else if let Some(name) = opts.get("rederive") {
@ -377,7 +377,7 @@ impl SessionTx {
};
let name = name
.as_str()
.ok_or_else(|| anyhow!("view name must be a string"))?;
.ok_or_else(|| miette!("view name must be a string"))?;
let name = Symbol::from(name);
ensure!(!name.is_reserved(), "view name {} is reserved", name);
let entry_arity = get_entry_arity(&prog)?;
@ -445,22 +445,22 @@ impl SessionTx {
let symb = Symbol::from(s as &str);
let idx = *entry_bindings
.get(&symb)
.ok_or_else(|| anyhow!("binding {} not found", symb))?;
.ok_or_else(|| miette!("binding {} not found", symb))?;
Ok((idx, None))
}
JsonValue::Object(m) => {
let symb = m
.get("pull")
.ok_or_else(|| anyhow!("expect field 'pull' in {:?}", m))?
.ok_or_else(|| miette!("expect field 'pull' in {:?}", m))?
.as_str()
.ok_or_else(|| anyhow!("expect 'pull' to be a binding in {:?}", m))?;
.ok_or_else(|| miette!("expect 'pull' to be a binding in {:?}", m))?;
let symb = Symbol::from(symb);
let idx = *entry_bindings
.get(&symb)
.ok_or_else(|| anyhow!("binding {} not found", symb))?;
.ok_or_else(|| miette!("binding {} not found", symb))?;
let spec = m
.get("spec")
.ok_or_else(|| anyhow!("expect field 'spec' in {:?}", m))?;
.ok_or_else(|| miette!("expect field 'spec' in {:?}", m))?;
let specs = self.parse_pull(spec, 0)?;
Ok((idx, Some(specs)))
}
@ -478,7 +478,7 @@ impl SessionTx {
) -> Result<BTreeMap<Symbol, InputRulesOrAlgo>> {
let rules = payload
.as_array()
.ok_or_else(|| anyhow!("expect array for rules, got {}", payload))?
.ok_or_else(|| miette!("expect array for rules, got {}", payload))?
.iter()
.map(|o| self.parse_input_rule_definition(o, default_vld, params_pool));
let mut collected: BTreeMap<Symbol, Vec<InputRule>> = BTreeMap::new();
@ -535,9 +535,9 @@ impl SessionTx {
) -> Result<InputAtom> {
let binding = payload
.get("unify")
.ok_or_else(|| anyhow!("expect expression to have field 'unify'"))?
.ok_or_else(|| miette!("expect expression to have field 'unify'"))?
.as_str()
.ok_or_else(|| anyhow!("expect field 'unify' to be a symbol"))?;
.ok_or_else(|| miette!("expect field 'unify' to be a symbol"))?;
let binding = Symbol::from(binding);
ensure!(
binding.is_query_var(),
@ -546,14 +546,14 @@ impl SessionTx {
);
let expr = payload
.get("expr")
.ok_or_else(|| anyhow!("expect unify map to have field 'expr'"))?;
.ok_or_else(|| miette!("expect unify map to have field 'expr'"))?;
let mut expr = Self::parse_expr_arg(expr, params_pool)?;
expr.partial_eval(params_pool)?;
let one_many_unif = match payload.get("multi") {
None => false,
Some(v) => v
.as_bool()
.ok_or_else(|| anyhow!("unification 'multi' field must be a boolean"))?,
.ok_or_else(|| miette!("unification 'multi' field must be a boolean"))?,
};
Ok(InputAtom::Unification(Unification {
binding,
@ -568,7 +568,7 @@ impl SessionTx {
if let Some(name) = payload.get("param") {
let name = name
.as_str()
.ok_or_else(|| anyhow!("input var cannot be specified as {}", name))?;
.ok_or_else(|| miette!("input var cannot be specified as {}", name))?;
ensure!(
name.starts_with('$') && name.len() > 1,
"wrong input var format: {}",
@ -579,17 +579,17 @@ impl SessionTx {
let name = payload
.get("op")
.ok_or_else(|| anyhow!("expect expression to have key 'pred'"))?
.ok_or_else(|| miette!("expect expression to have key 'pred'"))?
.as_str()
.ok_or_else(|| anyhow!("expect key 'pred' to be a string referring to a predicate"))?;
.ok_or_else(|| miette!("expect key 'pred' to be a string referring to a predicate"))?;
let op = get_op(name).ok_or_else(|| anyhow!("unknown operator {}", name))?;
let op = get_op(name).ok_or_else(|| miette!("unknown operator {}", name))?;
let mut args: Box<[Expr]> = payload
.get("args")
.ok_or_else(|| anyhow!("expect key 'args' in expression"))?
.ok_or_else(|| miette!("expect key 'args' in expression"))?
.as_array()
.ok_or_else(|| anyhow!("expect key 'args' to be an array"))?
.ok_or_else(|| miette!("expect key 'args' to be an array"))?
.iter()
.map(|v| Self::parse_expr_arg(v, params_pool))
.try_collect()?;
@ -667,15 +667,15 @@ impl SessionTx {
) -> Result<InputAtom> {
let rule_name = payload
.get("rule")
.ok_or_else(|| anyhow!("expect key 'rule' in rule atom"))?
.ok_or_else(|| miette!("expect key 'rule' in rule atom"))?
.as_str()
.ok_or_else(|| anyhow!("expect value for key 'rule' to be a string"))?
.ok_or_else(|| miette!("expect value for key 'rule' to be a string"))?
.into();
let args = payload
.get("args")
.ok_or_else(|| anyhow!("expect key 'args' in rule atom"))?
.ok_or_else(|| miette!("expect key 'args' in rule atom"))?
.as_array()
.ok_or_else(|| anyhow!("expect value for key 'args' to be an array"))?
.ok_or_else(|| miette!("expect value for key 'args' to be an array"))?
.iter()
.map(|value_rep| -> Result<InputTerm<DataValue>> {
if let Some(s) = value_rep.as_str() {
@ -713,15 +713,15 @@ impl SessionTx {
) -> Result<InputAtom> {
let rule_name = payload
.get("view")
.ok_or_else(|| anyhow!("expect key 'view' in rule atom"))?
.ok_or_else(|| miette!("expect key 'view' in rule atom"))?
.as_str()
.ok_or_else(|| anyhow!("expect value for key 'view' to be a string"))?
.ok_or_else(|| miette!("expect value for key 'view' to be a string"))?
.into();
let args = payload
.get("args")
.ok_or_else(|| anyhow!("expect key 'args' in rule atom"))?
.ok_or_else(|| miette!("expect key 'args' in rule atom"))?
.as_array()
.ok_or_else(|| anyhow!("expect value for key 'args' to be an array"))?
.ok_or_else(|| miette!("expect value for key 'args' to be an array"))?
.iter()
.map(|value_rep| -> Result<InputTerm<DataValue>> {
if let Some(s) = value_rep.as_str() {
@ -760,7 +760,7 @@ impl SessionTx {
) -> Result<(Symbol, InputRule)> {
let rule_name = payload
.get("rule")
.ok_or_else(|| anyhow!("expect key 'rule' in rule definition"))?;
.ok_or_else(|| miette!("expect key 'rule' in rule definition"))?;
let rule_name = Symbol::try_from(rule_name)?;
if !rule_name.is_prog_entry() {
rule_name.validate_not_reserved()?;
@ -771,16 +771,16 @@ impl SessionTx {
.unwrap_or(Ok(default_vld))?;
let args = payload
.get("args")
.ok_or_else(|| anyhow!("expect key 'args' in rule definition"))?
.ok_or_else(|| miette!("expect key 'args' in rule definition"))?
.as_array()
.ok_or_else(|| anyhow!("expect value for key 'args' to be an array"))?;
.ok_or_else(|| miette!("expect value for key 'args' to be an array"))?;
let mut args = args.iter();
let rule_head_payload = args
.next()
.ok_or_else(|| anyhow!("expect value for key 'args' to be a non-empty array"))?;
.ok_or_else(|| miette!("expect value for key 'args' to be a non-empty array"))?;
let rule_head_vec = rule_head_payload
.as_array()
.ok_or_else(|| anyhow!("expect rule head to be an array, got {}", rule_head_payload))?;
.ok_or_else(|| miette!("expect rule head to be an array, got {}", rule_head_payload))?;
let mut rule_head = vec![];
let mut rule_aggr = vec![];
for head_item in rule_head_vec {
@ -792,29 +792,29 @@ impl SessionTx {
} else if let Some(m) = head_item.as_object() {
let s = m
.get("symb")
.ok_or_else(|| anyhow!("expect field 'symb' in rule head map"))?
.ok_or_else(|| miette!("expect field 'symb' in rule head map"))?
.as_str()
.ok_or_else(|| {
anyhow!("expect field 'symb' in rule head map to be a symbol")
miette!("expect field 'symb' in rule head map to be a symbol")
})?;
let symbol = Symbol::from(s);
symbol.validate_query_var()?;
let aggr = m
.get("aggr")
.ok_or_else(|| anyhow!("expect field 'aggr' in rule head map"))?
.ok_or_else(|| miette!("expect field 'aggr' in rule head map"))?
.as_str()
.ok_or_else(|| {
anyhow!("expect field 'aggr' in rule head map to be a symbol")
miette!("expect field 'aggr' in rule head map to be a symbol")
})?;
let aggr = get_aggr(aggr)
.ok_or_else(|| anyhow!("aggregation '{}' not found", aggr))?
.ok_or_else(|| miette!("aggregation '{}' not found", aggr))?
.clone();
let aggr_args: Vec<DataValue> = match m.get("args") {
None => vec![],
Some(aggr_args) => aggr_args
.as_array()
.ok_or_else(|| anyhow!("aggregation args must be an array"))?
.ok_or_else(|| miette!("aggregation args must be an array"))?
.iter()
.map(|v| Self::parse_const_expr(v, params_pool))
.try_collect()?,
@ -900,7 +900,7 @@ impl SessionTx {
n @ ("conj" | "disj") => {
let args = v
.as_array()
.ok_or_else(|| anyhow!("expect array argument for atom {}", n))?
.ok_or_else(|| miette!("expect array argument for atom {}", n))?
.iter()
.map(|a| self.parse_input_atom(a, vld, params_pool))
.try_collect()?;
@ -943,7 +943,7 @@ impl SessionTx {
let symb = Symbol::from(k as &str);
let attr = self
.attr_by_name(&symb)?
.ok_or_else(|| anyhow!("attribute {} not found", symb))?;
.ok_or_else(|| miette!("attribute {} not found", symb))?;
ensure!(
attr.indexing.is_unique_index(),
"pull inside query must use unique index, of which {} is not",
@ -1024,7 +1024,7 @@ impl SessionTx {
let kw = Symbol::from(s as &str);
let attr = self
.attr_by_name(&kw)?
.ok_or_else(|| anyhow!("attribute {} not found", kw))?;
.ok_or_else(|| miette!("attribute {} not found", kw))?;
Ok(attr)
}
v => bail!("expect attribute name for triple atom, got {}", v),

@ -1,4 +1,4 @@
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result};
use itertools::Itertools;
use crate::data::attr::Attribute;
@ -15,17 +15,17 @@ impl AttrTxItem {
pub(crate) fn parse_request(req: &JsonValue) -> Result<(Vec<AttrTxItem>, String)> {
let map = req
.as_object()
.ok_or_else(|| anyhow!("expect object, got {}", req))?;
.ok_or_else(|| miette!("expect object, got {}", req))?;
let comment = match map.get("comment") {
None => "".to_string(),
Some(c) => c.to_string(),
};
let items = map
.get("attrs")
.ok_or_else(|| anyhow!("expect key 'attrs' in {:?}", map))?;
.ok_or_else(|| miette!("expect key 'attrs' in {:?}", map))?;
let items = items
.as_array()
.ok_or_else(|| anyhow!("expect array for value of key 'attrs', got {:?}", items))?;
.ok_or_else(|| miette!("expect array for value of key 'attrs', got {:?}", items))?;
ensure!(
!items.is_empty(),
"array for value of key 'attrs' must be non-empty"
@ -36,12 +36,12 @@ impl AttrTxItem {
}
impl TryFrom<&'_ JsonValue> for AttrTxItem {
type Error = anyhow::Error;
type Error = miette::Error;
fn try_from(value: &'_ JsonValue) -> Result<Self, Self::Error> {
let map = value
.as_object()
.ok_or_else(|| anyhow!("expect object for attribute tx, got {}", value))?;
.ok_or_else(|| miette!("expect object for attribute tx, got {}", value))?;
ensure!(
map.len() == 1,
"attr definition must have exactly one pair, got {}",

@ -1,4 +1,4 @@
use anyhow::Result;
use miette::{Result, IntoDiagnostic};
use pest::Parser;
use crate::data::program::InputProgram;
@ -15,7 +15,7 @@ pub(crate) enum CozoScript {
}
pub(crate) fn parse_script(src: &str) -> Result<CozoScript> {
let parsed = CozoScriptParser::parse(Rule::script, src)?.next().unwrap();
let parsed = CozoScriptParser::parse(Rule::script, src).into_diagnostic()?.next().unwrap();
Ok(match parsed.as_rule() {
Rule::query_script => CozoScript::Query(parse_query(parsed.into_inner())?),
Rule::schema_script => todo!(),

@ -2,7 +2,7 @@ use std::collections::btree_map::Entry;
use std::collections::BTreeMap;
use std::fmt::{Display, Formatter};
use anyhow::{anyhow, bail, ensure, Context, Result};
use miette::{miette, bail, ensure, Context, Result};
use serde_json::{json, Map};
use crate::data::attr::{Attribute, AttributeIndex, AttributeTyping};
@ -116,12 +116,12 @@ impl SessionTx {
) -> Result<(Vec<Quintuple>, String)> {
let map = req
.as_object()
.ok_or_else(|| anyhow!("expect tx request to be an object, got {}", req))?;
.ok_or_else(|| miette!("expect tx request to be an object, got {}", req))?;
let items = map
.get("tx")
.ok_or_else(|| anyhow!("expect field 'tx' in tx request object {}", req))?
.ok_or_else(|| miette!("expect field 'tx' in tx request object {}", req))?
.as_array()
.ok_or_else(|| anyhow!("expect field 'tx' to be an array in {}", req))?;
.ok_or_else(|| miette!("expect field 'tx' to be an array in {}", req))?;
let default_since = match map.get("since") {
None => Validity::current(),
Some(v) => v.try_into()?,
@ -147,7 +147,7 @@ impl SessionTx {
) -> Result<()> {
let item = item
.as_object()
.ok_or_else(|| anyhow!("expect tx request item to be an object, got {}", item))?;
.ok_or_else(|| miette!("expect tx request item to be an object, got {}", item))?;
let (inner, action) = {
if let Some(inner) = item.get("put") {
(inner, TxAction::Put)
@ -265,7 +265,7 @@ impl SessionTx {
);
let eid = eid
.as_u64()
.ok_or_else(|| anyhow!("cannot parse {} as entity id", eid))?;
.ok_or_else(|| miette!("cannot parse {} as entity id", eid))?;
let eid = EntityId(eid);
ensure!(eid.is_perm(), "expected perm entity id, got {:?}", eid);
collected.push(Quintuple {
@ -288,11 +288,11 @@ impl SessionTx {
let kw: Symbol = attr.try_into()?;
let attr = self
.attr_by_name(&kw)?
.ok_or_else(|| anyhow!("attribute not found {}", kw))?;
.ok_or_else(|| miette!("attribute not found {}", kw))?;
let eid = eid
.as_u64()
.ok_or_else(|| anyhow!("cannot parse {} as entity id", eid))?;
.ok_or_else(|| miette!("cannot parse {} as entity id", eid))?;
let eid = EntityId(eid);
ensure!(eid.is_perm(), "expect perm entity id, got {:?}", eid);
collected.push(Quintuple {
@ -325,7 +325,7 @@ impl SessionTx {
let kw: Symbol = attr_kw.try_into()?;
let attr = self
.attr_by_name(&kw)?
.ok_or_else(|| anyhow!("attribute not found: {}", kw))?;
.ok_or_else(|| miette!("attribute not found: {}", kw))?;
if attr.cardinality.is_many() && attr.val_type != AttributeTyping::List && val.is_array() {
for cur_val in val.as_array().unwrap() {
self.parse_tx_triple(eid, attr_kw, cur_val, action, since, temp_id_ctx, collected)?;
@ -411,7 +411,7 @@ impl SessionTx {
let kw = (k as &str).into();
let attr = self
.attr_by_name(&kw)?
.ok_or_else(|| anyhow!("attribute '{}' not found", kw))
.ok_or_else(|| miette!("attribute '{}' not found", kw))
.with_context(|| format!("cannot process {}", json!(item)))?;
has_unique_attr = has_unique_attr || attr.indexing.is_unique_index();
has_identity_attr = has_identity_attr || attr.indexing == AttributeIndex::Identity;
@ -450,7 +450,7 @@ impl SessionTx {
if let Some(given_id) = item.get(PERM_ID_FIELD) {
let given_id = given_id
.as_u64()
.ok_or_else(|| anyhow!("unable to interpret {} as entity id", given_id))?;
.ok_or_else(|| miette!("unable to interpret {} as entity id", given_id))?;
let given_id = EntityId(given_id);
ensure!(
given_id.is_perm(),
@ -476,7 +476,7 @@ impl SessionTx {
);
let temp_id_str = temp_id
.as_str()
.ok_or_else(|| anyhow!("unable to interpret {} as temp id", temp_id))?;
.ok_or_else(|| miette!("unable to interpret {} as temp id", temp_id))?;
eid = Some(temp_id_ctx.str2tempid(temp_id_str, true));
}
let eid = match eid {

@ -1,6 +1,6 @@
use std::collections::{BTreeMap, BTreeSet};
use anyhow::{anyhow, ensure, Context, Result};
use miette::{miette, ensure, Context, Result};
use itertools::Itertools;
use crate::data::aggr::Aggregation;
@ -195,7 +195,7 @@ impl SessionTx {
MagicAtom::Rule(rule_app) => {
let store = stores
.get(&rule_app.name)
.ok_or_else(|| anyhow!("undefined rule '{:?}' encountered", rule_app.name))?
.ok_or_else(|| miette!("undefined rule '{:?}' encountered", rule_app.name))?
.clone();
ensure!(
store.arity == rule_app.args.len(),
@ -294,7 +294,7 @@ impl SessionTx {
let store = stores
.get(&rule_app.name)
.ok_or_else(|| {
anyhow!("undefined rule encountered: '{:?}'", rule_app.name)
miette!("undefined rule encountered: '{:?}'", rule_app.name)
})?
.clone();
ensure!(

@ -1,7 +1,7 @@
use std::collections::{BTreeMap, BTreeSet};
use std::mem;
use anyhow::{anyhow, Result};
use miette::{miette, Result};
use log::{debug, log_enabled, trace, Level};
use crate::data::program::{MagicAlgoApply, MagicSymbol};
@ -39,7 +39,7 @@ impl SessionTx {
.get(&MagicSymbol::Muggle {
inner: PROG_ENTRY.clone(),
})
.ok_or_else(|| anyhow!("program entry not found in rules"))?
.ok_or_else(|| miette!("program entry not found in rules"))?
.clone();
for (idx, cur_prog) in strata.iter().enumerate() {
@ -146,7 +146,7 @@ impl SessionTx {
let mut algo_impl = algo_apply.algo.get_impl()?;
let out = stores
.get(rule_symb)
.ok_or_else(|| anyhow!("cannot find algo store {:?}", rule_symb))?;
.ok_or_else(|| miette!("cannot find algo store {:?}", rule_symb))?;
algo_impl.run(
self,
&algo_apply.rule_args,

@ -1,7 +1,7 @@
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Debug;
use anyhow::Result;
use miette::Result;
use itertools::Itertools;
use crate::algo::strongly_connected_components::TarjanScc;

@ -1,6 +1,6 @@
use std::collections::BTreeSet;
use anyhow::{bail, Result};
use miette::{bail, Result};
use itertools::Itertools;
use crate::data::expr::Expr;

@ -1,6 +1,6 @@
use std::collections::{BTreeSet, HashSet};
use anyhow::{ensure, Result};
use miette::{ensure, IntoDiagnostic, Result};
use either::{Left, Right};
use itertools::Itertools;
use serde_json::{json, Map};
@ -61,7 +61,7 @@ pub(crate) struct CurrentPath(SmallVec<[u16; 8]>);
impl CurrentPath {
pub(crate) fn new(idx: usize) -> Result<Self> {
Ok(Self(smallvec![idx.try_into()?]))
Ok(Self(smallvec![idx.try_into().into_diagnostic()?]))
}
fn get_from_root<'a>(&self, depth: usize, root: &'a [PullSpec]) -> &'a [PullSpec] {
let mut current = root;
@ -74,7 +74,7 @@ impl CurrentPath {
fn push(&self, idx: usize) -> Result<Self> {
let mut ret = CurrentPath(Default::default());
ret.0.clone_from(&self.0);
ret.0.push(idx.try_into()?);
ret.0.push(idx.try_into().into_diagnostic()?);
Ok(ret)
}
fn recurse_pop(&self, depth: usize) -> Self {
@ -117,10 +117,10 @@ impl SessionTx {
for data in res_iter {
let data = data?;
let encoded = data.encode_as_key(view_store.metadata.id);
vtx.del(&encoded)?;
vtx.del(&encoded).into_diagnostic()?;
}
vtx.commit()?;
vtx.commit().into_diagnostic()?;
} else {
// let mut vtx = self.view_db.transact().start();
//
@ -131,17 +131,17 @@ impl SessionTx {
// }
//
// vtx.commit()?;
let file = NamedTempFile::new()?;
let file = NamedTempFile::new().into_diagnostic()?;
let path = file.into_temp_path();
let path = path.to_string_lossy();
let mut writer = self.view_db.get_sst_writer(&path)?;
let mut writer = self.view_db.get_sst_writer(&path).into_diagnostic()?;
for data in res_iter {
let data = data?;
let encoded = data.encode_as_key(view_store.metadata.id);
writer.put(&encoded, &[])?;
writer.put(&encoded, &[]).into_diagnostic()?;
}
writer.finish()?;
self.view_db.ingest_sst_file(&path)?;
writer.finish().into_diagnostic()?;
self.view_db.ingest_sst_file(&path).into_diagnostic()?;
}
Ok(())
}
@ -558,7 +558,7 @@ impl SessionTx {
let mut it = self.tx.iterator().upper_bound(&upper_bound).start();
it.seek(&current);
while let Some((k_slice, v_slice)) = it.pair()? {
while let Some((k_slice, v_slice)) = it.pair().into_diagnostic()? {
debug_assert_eq!(
StorageTag::try_from(k_slice[0])?,
StorageTag::TripleEntityAttrValue

@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
use std::fmt::{Debug, Formatter};
use std::iter;
use anyhow::{anyhow, bail, Context, Result};
use miette::{miette, bail, Context, Result};
use either::{Left, Right};
use itertools::Itertools;
use log::error;
@ -95,7 +95,7 @@ impl UnificationRelation {
.map_ok(move |tuple| -> Result<Vec<Tuple>> {
let result_list = self.expr.eval(&tuple)?;
let result_list = result_list.get_list().ok_or_else(|| {
anyhow!("multi unification encountered non-list {:?}", result_list)
miette!("multi unification encountered non-list {:?}", result_list)
})?;
let mut coll = vec![];
for result in result_list {
@ -574,7 +574,7 @@ pub(crate) struct TripleRelation {
pub(crate) filters: Vec<Expr>,
}
pub(crate) fn flatten_err<T, E1: Into<anyhow::Error>, E2: Into<anyhow::Error>>(
pub(crate) fn flatten_err<T, E1: Into<miette::Error>, E2: Into<miette::Error>>(
v: std::result::Result<std::result::Result<T, E2>, E1>,
) -> Result<T> {
match v {

@ -1,7 +1,7 @@
use std::collections::BTreeSet;
use std::mem;
use anyhow::{bail, Result};
use miette::{bail, Result};
use crate::data::program::{NormalFormAtom, NormalFormRule};

@ -1,7 +1,7 @@
use std::cmp::Reverse;
use std::collections::BTreeMap;
use anyhow::Result;
use miette::Result;
use itertools::Itertools;
use crate::data::symb::Symbol;

@ -1,7 +1,7 @@
use std::collections::btree_map::Entry;
use std::collections::{BTreeMap, BTreeSet};
use anyhow::{ensure, Result};
use miette::{ensure, Result};
use itertools::Itertools;
use crate::data::program::{

@ -6,7 +6,7 @@ use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::{fs, thread};
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result, IntoDiagnostic};
use either::{Left, Right};
use itertools::Itertools;
use log::debug;
@ -80,7 +80,7 @@ impl Debug for Db {
impl Db {
pub fn build(builder: DbBuilder<'_>) -> Result<Self> {
let path = builder.opts.db_path;
fs::create_dir_all(path)?;
fs::create_dir_all(path).into_diagnostic()?;
let path_buf = PathBuf::from(path);
let mut triple_path = path_buf.clone();
triple_path.push("triple");
@ -98,8 +98,8 @@ impl Db {
.use_capped_prefix_extractor(true, SCRATCH_DB_KEY_PREFIX_LEN)
.use_custom_comparator("cozo_rusty_scratch_cmp", rusty_scratch_cmp, false);
let db = db_builder.build()?;
let view_db = view_db_builder.build()?;
let db = db_builder.build().into_diagnostic()?;
let view_db = view_db_builder.build().into_diagnostic()?;
let ret = Self {
db,
@ -120,14 +120,14 @@ impl Db {
pub fn compact_main(&self) -> Result<()> {
let l = smallest_key();
let u = largest_key();
self.db.range_compact(&l, &u)?;
self.db.range_compact(&l, &u).into_diagnostic()?;
Ok(())
}
pub fn compact_view(&self) -> Result<()> {
let l = Tuple::default().encode_as_key(ViewRelId(0));
let u = Tuple(vec![DataValue::Bot]).encode_as_key(ViewRelId(u64::MAX));
self.db.range_compact(&l, &u)?;
self.db.range_compact(&l, &u).into_diagnostic()?;
Ok(())
}
@ -311,7 +311,7 @@ impl Db {
.start();
let mut collected: BTreeMap<EntityId, JsonValue> = BTreeMap::default();
it.seek(&current);
while let Some((k_slice, v_slice)) = it.pair()? {
while let Some((k_slice, v_slice)) = it.pair().into_diagnostic()? {
debug_assert_eq!(
StorageTag::try_from(k_slice[0])?,
StorageTag::TripleEntityAttrValue
@ -382,10 +382,10 @@ impl Db {
pub fn run_json_query(&self, payload: &JsonValue) -> Result<JsonValue> {
let (k, v) = payload
.as_object()
.ok_or_else(|| anyhow!("json query must be an object"))?
.ok_or_else(|| miette!("json query must be an object"))?
.iter()
.next()
.ok_or_else(|| anyhow!("json query must be an object with keys"))?;
.ok_or_else(|| miette!("json query must be an object with keys"))?;
match k as &str {
"query" => self.run_query(v),
"schema" => self.transact_attributes(v),
@ -395,7 +395,7 @@ impl Db {
}
}
pub fn run_sys_op(&self, payload: JsonValue) -> Result<JsonValue> {
let op: SysOp = serde_json::from_value(payload)?;
let op: SysOp = serde_json::from_value(payload).into_diagnostic()?;
match op {
SysOp::Compact(opts) => {
for opt in opts {
@ -544,8 +544,8 @@ impl Db {
}
let key = Tuple(ks).encode_as_key(ViewRelId::SYSTEM);
let mut vtx = self.view_db.transact().start();
vtx.put(&key, v)?;
vtx.commit()?;
vtx.put(&key, v).into_diagnostic()?;
vtx.commit().into_diagnostic()?;
Ok(())
}
pub fn remove_meta_kv(&self, k: &[&str]) -> Result<()> {
@ -555,8 +555,8 @@ impl Db {
}
let key = Tuple(ks).encode_as_key(ViewRelId::SYSTEM);
let mut vtx = self.view_db.transact().start();
vtx.del(&key)?;
vtx.commit()?;
vtx.del(&key).into_diagnostic()?;
vtx.commit().into_diagnostic()?;
Ok(())
}
pub fn get_meta_kv(&self, k: &[&str]) -> Result<Option<Vec<u8>>> {
@ -566,7 +566,7 @@ impl Db {
}
let key = Tuple(ks).encode_as_key(ViewRelId::SYSTEM);
let vtx = self.view_db.transact().start();
Ok(match vtx.get(&key, false)? {
Ok(match vtx.get(&key, false).into_diagnostic()? {
None => None,
Some(slice) => Some(slice.to_vec()),
})
@ -601,7 +601,7 @@ impl Db {
} else {
self.started = true;
}
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => Ok(None),
Some((k_slice, v_slice)) => {
let encoded = EncodedTuple(k_slice).decode()?;
@ -612,7 +612,7 @@ impl Db {
.map(|v| {
v.get_string()
.map(|s| s.to_string())
.ok_or_else(|| anyhow!("bad key in meta store"))
.ok_or_else(|| miette!("bad key in meta store"))
})
.try_collect()?;
Ok(Some((ks, v_slice.to_vec())))
@ -647,8 +647,8 @@ impl Db {
.start();
it.seek(&lower);
let mut collected = vec![];
while let Some(v_slice) = it.val()? {
let meta: ViewRelMetadata = rmp_serde::from_slice(v_slice)?;
while let Some(v_slice) = it.val().into_diagnostic()? {
let meta: ViewRelMetadata = rmp_serde::from_slice(v_slice).into_diagnostic()?;
let name = meta.name.0;
let arity = meta.arity;
collected.push(json!([name, arity]));

@ -5,7 +5,7 @@ use std::ops::Bound::Included;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::{Arc, RwLock};
use anyhow::Result;
use miette::{miette, Result};
use itertools::Itertools;
use cozorocks::DbIter;
@ -381,7 +381,7 @@ impl Iterator for SortedIter {
self.it.next();
}
match self.it.pair() {
Err(e) => Some(Err(e.into())),
Err(e) => Some(Err(miette!(e))),
Ok(None) => None,
Ok(Some((_, v_slice))) => match EncodedTuple(v_slice).decode() {
Ok(res) => Some(Ok(res)),

@ -2,7 +2,7 @@ use std::collections::{BTreeMap, BTreeSet};
use std::sync::atomic::{AtomicU32, AtomicU64, Ordering};
use std::sync::Arc;
use anyhow::{anyhow, Result};
use miette::{IntoDiagnostic, miette, Result};
use rmp_serde::Serializer;
use serde::Serialize;
use smallvec::SmallVec;
@ -63,7 +63,7 @@ impl TxLog {
EncodedVec { inner: store }
}
pub(crate) fn decode(data: &[u8]) -> Result<Self> {
Ok(rmp_serde::from_slice(data)?)
Ok(rmp_serde::from_slice(data).into_diagnostic()?)
}
}
@ -99,7 +99,7 @@ impl SessionTx {
let e_upper = encode_sentinel_entity_attr(EntityId::MAX_PERM, AttrId::MIN_PERM);
let it = self.bounded_scan_last(&e_lower, &e_upper);
Ok(match it.key()? {
Ok(match it.key().into_diagnostic()? {
None => EntityId::MAX_TEMP,
Some(data) => EntityId::from_bytes(data),
})
@ -109,7 +109,7 @@ impl SessionTx {
let e_lower = encode_sentinel_attr_by_id(AttrId::MIN_PERM);
let e_upper = encode_sentinel_attr_by_id(AttrId::MAX_PERM);
let it = self.bounded_scan_last(&e_lower, &e_upper);
Ok(match it.key()? {
Ok(match it.key().into_diagnostic()? {
None => AttrId::MAX_TEMP,
Some(data) => AttrId::from_bytes(data),
})
@ -119,7 +119,7 @@ impl SessionTx {
let tuple = Tuple(vec![DataValue::Null]);
let t_encoded = tuple.encode_as_key(ViewRelId::SYSTEM);
let vtx = self.view_db.transact().start();
let found = vtx.get(&t_encoded, false)?;
let found = vtx.get(&t_encoded, false).into_diagnostic()?;
match found {
None => Ok(ViewRelId::SYSTEM),
Some(slice) => ViewRelId::raw_decode(&slice),
@ -130,7 +130,7 @@ impl SessionTx {
let e_lower = encode_tx(TxId::MAX_USER);
let e_upper = encode_tx(TxId::MAX_SYS);
let it = self.bounded_scan_first(&e_lower, &e_upper);
Ok(match it.key()? {
Ok(match it.key().into_diagnostic()? {
None => TxId::MAX_SYS,
Some(data) => TxId::from_bytes(data),
})
@ -141,8 +141,8 @@ impl SessionTx {
let encoded = encode_tx(tx_id);
let log = TxLog::new(tx_id, comment);
self.tx.put(&encoded, &log.encode())?;
self.tx.commit()?;
self.tx.put(&encoded, &log.encode()).into_diagnostic()?;
self.tx.commit().into_diagnostic()?;
if refresh {
let new_tx_id = TxId(self.last_tx_id.fetch_add(1, Ordering::AcqRel) + 1);
self.tx.set_snapshot();
@ -154,7 +154,7 @@ impl SessionTx {
pub(crate) fn get_write_tx_id(&self) -> Result<TxId> {
self.w_tx_id
.ok_or_else(|| anyhow!("attempting to write in read-only transaction"))
.ok_or_else(|| miette!("attempting to write in read-only transaction"))
}
pub(crate) fn bounded_scan(&mut self, lower: &[u8], upper: &[u8]) -> DbIter {
self.tx

@ -1,7 +1,7 @@
use std::fmt::{Debug, Formatter};
use std::sync::atomic::Ordering;
use anyhow::{anyhow, bail, Result};
use miette::{miette, bail, Result, IntoDiagnostic};
use rmp_serde::Serializer;
use serde::Serialize;
@ -130,7 +130,7 @@ impl ViewRelIterator {
} else {
self.started = true;
}
Ok(match self.inner.key()? {
Ok(match self.inner.key().into_diagnostic()? {
None => None,
Some(k_slice) => Some(EncodedTuple(k_slice).decode()?),
})
@ -149,14 +149,14 @@ impl SessionTx {
let key = DataValue::Str(name.0.clone());
let encoded = Tuple(vec![key]).encode_as_key(ViewRelId::SYSTEM);
let vtx = self.view_db.transact().start();
Ok(vtx.exists(&encoded, false)?)
Ok(vtx.exists(&encoded, false).into_diagnostic()?)
}
pub(crate) fn create_view_rel(&self, mut meta: ViewRelMetadata) -> Result<ViewRelStore> {
let key = DataValue::Str(meta.name.0.clone());
let encoded = Tuple(vec![key]).encode_as_key(ViewRelId::SYSTEM);
let mut vtx = self.view_db.transact().set_snapshot(true).start();
if vtx.exists(&encoded, true)? {
if vtx.exists(&encoded, true).into_diagnostic()? {
bail!(
"cannot create view {}: one with the same name already exists",
meta.name
@ -164,18 +164,18 @@ impl SessionTx {
};
let last_id = self.view_store_id.fetch_add(1, Ordering::SeqCst);
meta.id = ViewRelId::new(last_id + 1)?;
vtx.put(&encoded, &meta.id.raw_encode())?;
vtx.put(&encoded, &meta.id.raw_encode()).into_diagnostic()?;
let name_key =
Tuple(vec![DataValue::Str(meta.name.0.clone())]).encode_as_key(ViewRelId::SYSTEM);
let mut meta_val = vec![];
meta.serialize(&mut Serializer::new(&mut meta_val)).unwrap();
vtx.put(&name_key, &meta_val)?;
vtx.put(&name_key, &meta_val).into_diagnostic()?;
let tuple = Tuple(vec![DataValue::Null]);
let t_encoded = tuple.encode_as_key(ViewRelId::SYSTEM);
vtx.put(&t_encoded, &meta.id.raw_encode())?;
vtx.commit()?;
vtx.put(&t_encoded, &meta.id.raw_encode()).into_diagnostic()?;
vtx.commit().into_diagnostic()?;
Ok(ViewRelStore {
view_db: self.view_db.clone(),
metadata: meta,
@ -190,9 +190,9 @@ impl SessionTx {
let encoded = Tuple(vec![key]).encode_as_key(ViewRelId::SYSTEM);
let found = vtx
.get(&encoded, true)?
.ok_or_else(|| anyhow!("cannot find stored view {}", name))?;
let metadata: ViewRelMetadata = rmp_serde::from_slice(&found)?;
.get(&encoded, true).into_diagnostic()?
.ok_or_else(|| miette!("cannot find stored view {}", name))?;
let metadata: ViewRelMetadata = rmp_serde::from_slice(&found).into_diagnostic()?;
Ok(ViewRelStore {
view_db: self.view_db.clone(),
metadata,
@ -203,11 +203,11 @@ impl SessionTx {
let store = self.do_get_view_rel(name, &vtx)?;
let key = DataValue::Str(name.0.clone());
let encoded = Tuple(vec![key]).encode_as_key(ViewRelId::SYSTEM);
vtx.del(&encoded)?;
vtx.del(&encoded).into_diagnostic()?;
let lower_bound = Tuple::default().encode_as_key(store.metadata.id);
let upper_bound = Tuple::default().encode_as_key(store.metadata.id.next()?);
self.view_db.range_del(&lower_bound, &upper_bound)?;
vtx.commit()?;
self.view_db.range_del(&lower_bound, &upper_bound).into_diagnostic()?;
vtx.commit().into_diagnostic()?;
Ok(())
}
}

@ -1,6 +1,6 @@
use std::sync::atomic::Ordering;
use anyhow::{anyhow, bail, ensure, Result};
use miette::{miette, bail, ensure, Result, IntoDiagnostic};
use cozorocks::{DbIter, IterBuilder};
@ -44,7 +44,7 @@ impl SessionTx {
}
let anchor = encode_sentinel_attr_by_id(aid);
Ok(match self.tx.get(&anchor, false)? {
Ok(match self.tx.get(&anchor, false).into_diagnostic()? {
None => {
self.attr_by_id_cache.insert(aid, None);
None
@ -73,7 +73,7 @@ impl SessionTx {
}
let anchor = encode_sentinel_attr_by_name(name);
Ok(match self.tx.get(&anchor, false)? {
Ok(match self.tx.get(&anchor, false).into_diagnostic()? {
None => {
self.attr_by_kw_cache.insert(name.clone(), None);
None
@ -125,7 +125,7 @@ impl SessionTx {
pub(crate) fn amend_attr(&mut self, attr: Attribute) -> Result<AttrId> {
let existing = self
.attr_by_id(attr.id)?
.ok_or_else(|| anyhow!("expected attribute id {:?} not found", attr.id))?;
.ok_or_else(|| miette!("expected attribute id {:?} not found", attr.id))?;
let tx_id = self.get_write_tx_id()?;
if existing.name != attr.name {
ensure!(
@ -143,7 +143,7 @@ impl SessionTx {
);
let kw_sentinel = encode_sentinel_attr_by_name(&existing.name);
let attr_data = existing.encode_with_op_and_tx(StoreOp::Retract, tx_id);
self.tx.put(&kw_sentinel, &attr_data)?;
self.tx.put(&kw_sentinel, &attr_data).into_diagnostic()?;
}
self.put_attr(&attr, StoreOp::Assert)
}
@ -152,11 +152,11 @@ impl SessionTx {
let tx_id = self.get_write_tx_id()?;
let attr_data = attr.encode_with_op_and_tx(op, tx_id);
let id_encoded = encode_attr_by_id(attr.id, tx_id);
self.tx.put(&id_encoded, &attr_data)?;
self.tx.put(&id_encoded, &attr_data).into_diagnostic()?;
let id_sentinel = encode_sentinel_attr_by_id(attr.id);
self.tx.put(&id_sentinel, &attr_data)?;
self.tx.put(&id_sentinel, &attr_data).into_diagnostic()?;
let kw_sentinel = encode_sentinel_attr_by_name(&attr.name);
self.tx.put(&kw_sentinel, &attr_data)?;
self.tx.put(&kw_sentinel, &attr_data).into_diagnostic()?;
Ok(attr.id)
}
@ -174,7 +174,7 @@ impl SessionTx {
pub(crate) fn retract_attr_by_kw(&mut self, kw: &Symbol) -> Result<AttrId> {
let attr = self
.attr_by_name(kw)?
.ok_or_else(|| anyhow!("attribute not found: {}", kw))?;
.ok_or_else(|| miette!("attribute not found: {}", kw))?;
self.retract_attr(attr.id)
}
}
@ -200,7 +200,7 @@ impl AttrIter {
self.it.next();
}
loop {
match self.it.val()? {
match self.it.val().into_diagnostic()? {
None => return Ok(None),
Some(v) => {
let found_op = StoreOp::try_from(v[0])?;

@ -1,6 +1,6 @@
use std::sync::atomic::Ordering;
use anyhow::{anyhow, ensure, Result};
use miette::{ensure, miette, IntoDiagnostic, Result};
use cozorocks::{DbIter, IterBuilder};
@ -99,8 +99,11 @@ impl SessionTx {
) -> Result<()> {
let aid = attr.id;
let sentinel = encode_sentinel_entity_attr(eid, aid);
let gen_err = || anyhow!("required triple not found for {:?}, {:?}", eid, aid);
self.tx.get(&sentinel, true)?.ok_or_else(gen_err)?;
let gen_err = || miette!("required triple not found for {:?}, {:?}", eid, aid);
self.tx
.get(&sentinel, true)
.into_diagnostic()?
.ok_or_else(gen_err)?;
let v_in_key = if attr.cardinality.is_one() {
&DataValue::Guard
} else {
@ -109,7 +112,7 @@ impl SessionTx {
let eav_encoded = encode_eav_key(eid, attr.id, v_in_key, vld);
let eav_encoded_upper = encode_eav_key(eid, attr.id, v_in_key, Validity::MIN);
let it = self.bounded_scan_first(&eav_encoded, &eav_encoded_upper);
let (k_slice, v_slice) = it.pair()?.ok_or_else(gen_err)?;
let (k_slice, v_slice) = it.pair().into_diagnostic()?.ok_or_else(gen_err)?;
if StoreOp::try_from(v_slice[0])?.is_retract() {
return Err(gen_err());
}
@ -154,28 +157,30 @@ impl SessionTx {
let aev_encoded = encode_aev_key(attr.id, eid, v_in_key, vld_in_key);
if real_delete {
self.tx.del(&aev_encoded)?;
self.tx.del(&aev_encoded).into_diagnostic()?;
} else {
self.tx.put(&aev_encoded, &val_encoded)?;
self.tx.put(&aev_encoded, &val_encoded).into_diagnostic()?;
}
let eav_encoded = encode_eav_key(eid, attr.id, v_in_key, vld_in_key);
if real_delete {
self.tx.del(&eav_encoded)?;
self.tx.del(&eav_encoded).into_diagnostic()?;
} else {
self.tx.put(&eav_encoded, &val_encoded)?;
self.tx.put(&eav_encoded, &val_encoded).into_diagnostic()?;
}
// vae for ref types
if attr.val_type.is_ref_type() {
let vae_encoded = encode_vae_key(v.get_entity_id()?, attr.id, eid, vld_in_key);
if real_delete {
self.tx.del(&vae_encoded)?;
self.tx.del(&vae_encoded).into_diagnostic()?;
} else {
self.tx.put(
&vae_encoded,
&DataValue::Guard.encode_with_op_and_tx(op, tx_id),
)?;
self.tx
.put(
&vae_encoded,
&DataValue::Guard.encode_with_op_and_tx(op, tx_id),
)
.into_diagnostic()?;
}
}
@ -216,7 +221,7 @@ impl SessionTx {
v
);
}
} else if let Some(v_slice) = self.tx.get(&ave_encoded, false)? {
} else if let Some(v_slice) = self.tx.get(&ave_encoded, false).into_diagnostic()? {
let found_eid = decode_value_from_val(&v_slice)?.get_entity_id()?;
ensure!(
found_eid == eid,
@ -228,21 +233,27 @@ impl SessionTx {
}
let e_in_val_encoded = eid.as_datavalue().encode_with_op_and_tx(op, tx_id);
if real_delete {
self.tx.del(&ave_encoded)?;
self.tx.del(&ave_encoded).into_diagnostic()?;
} else {
self.tx.put(&ave_encoded, &e_in_val_encoded)?;
self.tx
.put(&ave_encoded, &e_in_val_encoded)
.into_diagnostic()?;
}
self.tx.put(
&encode_sentinel_attr_val(attr.id, v),
&tx_id.bytes_with_op(op),
)?;
self.tx
.put(
&encode_sentinel_attr_val(attr.id, v),
&tx_id.bytes_with_op(op),
)
.into_diagnostic()?;
}
self.tx.put(
&encode_sentinel_entity_attr(eid, attr.id),
&tx_id.bytes_with_op(op),
)?;
self.tx
.put(
&encode_sentinel_entity_attr(eid, attr.id),
&tx_id.bytes_with_op(op),
)
.into_diagnostic()?;
Ok(eid)
}
@ -339,7 +350,7 @@ impl SessionTx {
let mut counter = 0;
loop {
it.seek(&current);
match it.pair()? {
match it.pair().into_diagnostic()? {
None => return Ok(counter),
Some((k_slice, v_slice)) => {
let op = StoreOp::try_from(v_slice[0])?;
@ -352,7 +363,7 @@ impl SessionTx {
if op.is_assert() {
let cur_attr = self
.attr_by_id(cur_aid)?
.ok_or_else(|| anyhow!("attribute not found for {:?}", cur_aid))?;
.ok_or_else(|| miette!("attribute not found for {:?}", cur_aid))?;
self.retract_triple(cur_eid, &cur_attr, &cur_v, vld)?;
counter -= 1;
}
@ -376,7 +387,11 @@ impl SessionTx {
let lower = encode_ave_key_for_unique_v(attr.id, v, vld);
let upper = encode_ave_key_for_unique_v(attr.id, v, Validity::MIN);
Ok(
if let Some(v_slice) = self.bounded_scan_first(&lower, &upper).val()? {
if let Some(v_slice) = self
.bounded_scan_first(&lower, &upper)
.val()
.into_diagnostic()?
{
if StoreOp::try_from(v_slice[0])?.is_assert() {
// let (_, mut eid, _) = decode_ae_key(k_slice)?;
// if eid.is_zero() {
@ -574,7 +589,7 @@ impl TripleEntityAttrIter {
} else {
self.it.next();
}
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => Ok(None),
Some((k_slice, v_slice)) => {
let (eid, aid, _tid) = decode_ea_key(k_slice)?;
@ -621,7 +636,7 @@ impl TripleEntityAttrBeforeIter {
fn next_inner(&mut self) -> Result<Option<(EntityId, AttrId, DataValue)>> {
loop {
self.it.seek(&self.current);
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => return Ok(None),
Some((k_slice, v_slice)) => {
let (eid, aid, tid) = decode_ea_key(k_slice)?;
@ -682,7 +697,7 @@ impl TripleEntityAttrRangeIter {
} else {
self.it.next();
}
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => Ok(None),
Some((k_slice, v_slice)) => {
let (eid, aid, _tid) = decode_ea_key(k_slice)?;
@ -736,7 +751,7 @@ impl TripleEntityAttrRangeBeforeIter {
fn next_inner(&mut self) -> Result<Option<(EntityId, AttrId, DataValue)>> {
loop {
self.it.seek(&self.current);
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => return Ok(None),
Some((k_slice, v_slice)) => {
let (eid, aid, tid) = decode_ea_key(k_slice)?;
@ -794,7 +809,7 @@ impl TripleAttrEntityIter {
} else {
self.started = true;
}
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => Ok(None),
Some((k_slice, v_slice)) => {
let (aid, eid, _tid) = decode_ae_key(k_slice)?;
@ -841,7 +856,7 @@ impl TripleAttrEntityBeforeIter {
fn next_inner(&mut self) -> Result<Option<(AttrId, EntityId, DataValue)>> {
loop {
self.it.seek(&self.current);
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => return Ok(None),
Some((k_slice, v_slice)) => {
let (aid, eid, tid) = decode_ae_key(k_slice)?;
@ -902,7 +917,7 @@ impl TripleAttrValueRangeIter {
} else {
self.started = true;
}
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => Ok(None),
Some((k_slice, v_slice)) => {
let (aid, mut eid, _tid) = decode_ae_key(k_slice)?;
@ -956,7 +971,7 @@ impl TripleAttrValueRangeBeforeIter {
fn next_inner(&mut self) -> Result<Option<(AttrId, DataValue, EntityId)>> {
loop {
self.it.seek(&self.current);
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => return Ok(None),
Some((k_slice, v_slice)) => {
let (aid, mut eid, tid) = decode_ae_key(k_slice)?;
@ -1014,7 +1029,7 @@ impl TripleAttrValueIter {
} else {
self.started = true;
}
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => Ok(None),
Some((k_slice, v_slice)) => {
let (aid, mut eid, _tid) = decode_ae_key(k_slice)?;
@ -1061,7 +1076,7 @@ impl TripleAttrValueBeforeIter {
fn next_inner(&mut self) -> Result<Option<(AttrId, DataValue, EntityId)>> {
loop {
self.it.seek(&self.current);
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => return Ok(None),
Some((k_slice, v_slice)) => {
let (aid, mut eid, tid) = decode_ae_key(k_slice)?;
@ -1120,7 +1135,7 @@ impl TripleAttrValueAfterIter {
fn next_inner(&mut self) -> Result<Option<(AttrId, DataValue, EntityId)>> {
loop {
self.it.seek_back(&self.current);
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => return Ok(None),
Some((k_slice, v_slice)) => {
if compare_key(k_slice, &self.lower_bound) == std::cmp::Ordering::Less {
@ -1175,7 +1190,7 @@ impl TripleValueRefAttrIter {
} else {
self.started = true;
}
match self.it.key()? {
match self.it.key().into_diagnostic()? {
None => Ok(None),
Some(k_slice) => {
let (v_eid, aid, eid, _) = decode_vae_key(k_slice)?;
@ -1218,7 +1233,7 @@ impl TripleValueRefAttrBeforeIter {
fn next_inner(&mut self) -> Result<Option<(EntityId, AttrId, EntityId)>> {
loop {
self.it.seek(&self.current);
match self.it.pair()? {
match self.it.pair().into_diagnostic()? {
None => return Ok(None),
Some((k_slice, v_slice)) => {
let (v_eid, aid, eid, tid) = decode_vae_key(k_slice)?;

@ -2,7 +2,7 @@ use std::fs::read_to_string;
use std::str::FromStr;
use std::time::Instant;
use anyhow::Result;
use miette::{IntoDiagnostic, Result};
use num_traits::abs;
use serde_json::json;
@ -62,7 +62,7 @@ fn air_routes() -> Result<()> {
);
if attr_res.is_ok() {
let insertions = read_to_string("tests/air-routes-data.json")?;
let insertions = read_to_string("tests/air-routes-data.json").into_diagnostic()?;
let triple_insertion_time = Instant::now();
db.run_script(&insertions)?;
dbg!(triple_insertion_time.elapsed());
@ -164,7 +164,7 @@ fn air_routes() -> Result<()> {
r#"[
[614,307,307],[587,293,294],[566,282,284],[541,270,271],[527,264,263],[502,251,251],
[497,248,249],[494,247,247],[484,242,242],[465,232,233]]"#
)?
).into_diagnostic()?
);
let deg_centrality_ad_hoc_time = Instant::now();
@ -188,7 +188,7 @@ fn air_routes() -> Result<()> {
["MUC",541,270,271],["ORD",527,264,263],["DFW",502,251,251],["PEK",497,248,249],
["DXB",494,247,247],["ATL",484,242,242]
]"#
)?
).into_diagnostic()?
);
let dijkstra_time = Instant::now();

Loading…
Cancel
Save