icydb_core/db/executor/
mod.rs1mod context;
2mod delete;
3mod load;
4mod plan;
5mod save;
6pub(crate) mod trace;
7mod unique;
8mod upsert;
9
10pub(crate) use context::*;
11pub use delete::DeleteExecutor;
12pub use load::LoadExecutor;
13pub use save::SaveExecutor;
14pub(crate) use unique::resolve_unique_pk;
15pub use upsert::{UniqueIndexHandle, UpsertExecutor, UpsertResult};
16
17use crate::{
18 db::store::DataKey,
19 error::{ErrorClass, ErrorOrigin, InternalError},
20};
21use thiserror::Error as ThisError;
22
23#[cfg(test)]
24mod tests;
25
26#[derive(Debug, ThisError)]
31pub enum ExecutorError {
32 #[error("corruption detected ({origin}): {message}")]
33 Corruption {
34 origin: ErrorOrigin,
35 message: String,
36 },
37
38 #[error("index constraint violation: {0} ({1})")]
39 IndexViolation(String, String),
40
41 #[error("index not found: {0} ({1})")]
42 IndexNotFound(String, String),
43
44 #[error("index not unique: {0} ({1})")]
45 IndexNotUnique(String, String),
46
47 #[error("index key missing: {0} ({1})")]
48 IndexKeyMissing(String, String),
49
50 #[error("data key exists: {0}")]
51 KeyExists(DataKey),
52
53 #[error("primary key type mismatch: expected {0}, got {1}")]
54 KeyTypeMismatch(String, String),
55
56 #[error("primary key out of range for {0}: {1}")]
57 KeyOutOfRange(String, String),
58}
59
60impl ExecutorError {
61 #[must_use]
62 pub(crate) fn index_violation(path: &str, index_fields: &[&str]) -> Self {
64 Self::IndexViolation(path.to_string(), index_fields.join(", "))
65 }
66
67 pub(crate) const fn class(&self) -> ErrorClass {
68 match self {
69 Self::KeyExists(_) | Self::IndexViolation(_, _) => ErrorClass::Conflict,
70 Self::IndexNotFound(_, _)
71 | Self::IndexNotUnique(_, _)
72 | Self::IndexKeyMissing(_, _)
73 | Self::KeyTypeMismatch(_, _)
74 | Self::KeyOutOfRange(_, _) => ErrorClass::Unsupported,
75 Self::Corruption { .. } => ErrorClass::Corruption,
76 }
77 }
78
79 pub(crate) const fn origin(&self) -> ErrorOrigin {
80 match self {
81 Self::KeyExists(_) => ErrorOrigin::Store,
82 Self::IndexViolation(_, _)
83 | Self::IndexNotFound(_, _)
84 | Self::IndexNotUnique(_, _)
85 | Self::IndexKeyMissing(_, _) => ErrorOrigin::Index,
86 Self::Corruption { origin, .. } => *origin,
87 Self::KeyTypeMismatch(_, _) | Self::KeyOutOfRange(_, _) => ErrorOrigin::Executor,
88 }
89 }
90
91 pub(crate) fn corruption(origin: ErrorOrigin, message: impl Into<String>) -> Self {
92 Self::Corruption {
93 origin,
94 message: message.into(),
95 }
96 }
97}
98
99impl From<ExecutorError> for InternalError {
100 fn from(err: ExecutorError) -> Self {
101 Self::new(err.class(), err.origin(), err.to_string())
102 }
103}