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("primary key type mismatch: expected {0}, got {1}")]
70 KeyTypeMismatch(String, String),
71
72 #[error("primary key out of range for {0}: {1}")]
73 KeyOutOfRange(String, String),
74}
75
76impl ExecutorError {
77 #[must_use]
78 pub(crate) fn index_violation(path: &str, index_fields: &[&str]) -> Self {
80 Self::IndexViolation(path.to_string(), index_fields.join(", "))
81 }
82
83 pub(crate) const fn class(&self) -> ErrorClass {
84 match self {
85 Self::KeyExists(_) | Self::IndexViolation(_, _) => ErrorClass::Conflict,
86 Self::IndexNotFound(_, _)
87 | Self::IndexNotUnique(_, _)
88 | Self::IndexKeyMissing(_, _)
89 | Self::KeyTypeMismatch(_, _)
90 | Self::KeyOutOfRange(_, _) => ErrorClass::Unsupported,
91 Self::Corruption { .. } => ErrorClass::Corruption,
92 }
93 }
94
95 pub(crate) const fn origin(&self) -> ErrorOrigin {
96 match self {
97 Self::KeyExists(_) => ErrorOrigin::Store,
98 Self::IndexViolation(_, _)
99 | Self::IndexNotFound(_, _)
100 | Self::IndexNotUnique(_, _)
101 | Self::IndexKeyMissing(_, _) => ErrorOrigin::Index,
102 Self::Corruption { origin, .. } => *origin,
103 Self::KeyTypeMismatch(_, _) | Self::KeyOutOfRange(_, _) => ErrorOrigin::Executor,
104 }
105 }
106
107 pub(crate) fn corruption(origin: ErrorOrigin, message: impl Into<String>) -> Self {
108 Self::Corruption {
109 origin,
110 message: message.into(),
111 }
112 }
113}
114
115impl From<ExecutorError> for InternalError {
116 fn from(err: ExecutorError) -> Self {
117 Self::new(err.class(), err.origin(), err.to_string())
118 }
119}