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