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 runtime_error::{ErrorClass, ErrorOrigin, RuntimeError},
21};
22use filter::*;
23use thiserror::Error as ThisError;
24
25pub(crate) struct WriteUnit {
27 _label: &'static str,
28}
29
30impl WriteUnit {
31 pub(crate) const fn new(label: &'static str) -> Self {
32 Self { _label: label }
33 }
34}
35
36#[derive(Debug, ThisError)]
41pub enum ExecutorError {
42 #[error("data key exists: {0}")]
43 KeyExists(DataKey),
44
45 #[error("data key not found: {0}")]
46 KeyNotFound(DataKey),
47
48 #[error("index constraint violation: {0} ({1})")]
49 IndexViolation(String, String),
50
51 #[error("index not found: {0} ({1})")]
52 IndexNotFound(String, String),
53
54 #[error("index not unique: {0} ({1})")]
55 IndexNotUnique(String, String),
56
57 #[error("index key missing: {0} ({1})")]
58 IndexKeyMissing(String, String),
59
60 #[error("index corrupted: {0} ({1}) -> {2} keys")]
61 IndexCorrupted(String, String, usize),
62
63 #[error("primary key type mismatch: expected {0}, got {1}")]
64 KeyTypeMismatch(String, String),
65
66 #[error("primary key out of range for {0}: {1}")]
67 KeyOutOfRange(String, String),
68}
69
70impl ExecutorError {
71 #[must_use]
72 pub(crate) fn index_violation(path: &str, index_fields: &[&str]) -> Self {
74 Self::IndexViolation(path.to_string(), index_fields.join(", "))
75 }
76
77 pub(crate) const fn class(&self) -> ErrorClass {
78 match self {
79 Self::KeyExists(_) | Self::IndexViolation(_, _) => ErrorClass::Conflict,
80 Self::KeyNotFound(_) => ErrorClass::InvariantViolation,
81 Self::IndexNotFound(_, _)
82 | Self::IndexNotUnique(_, _)
83 | Self::IndexKeyMissing(_, _)
84 | Self::KeyTypeMismatch(_, _)
85 | Self::KeyOutOfRange(_, _) => ErrorClass::Unsupported,
86 Self::IndexCorrupted(_, _, _) => ErrorClass::Corruption,
87 }
88 }
89
90 pub(crate) const fn origin(&self) -> ErrorOrigin {
91 match self {
92 Self::KeyExists(_) | Self::KeyNotFound(_) => ErrorOrigin::Store,
93 Self::IndexViolation(_, _)
94 | Self::IndexNotFound(_, _)
95 | Self::IndexNotUnique(_, _)
96 | Self::IndexKeyMissing(_, _)
97 | Self::IndexCorrupted(_, _, _) => ErrorOrigin::Index,
98 Self::KeyTypeMismatch(_, _) | Self::KeyOutOfRange(_, _) => ErrorOrigin::Executor,
99 }
100 }
101}
102
103impl From<ExecutorError> for RuntimeError {
104 fn from(err: ExecutorError) -> Self {
105 Self::new(err.class(), err.origin(), err.to_string())
106 }
107}