use std::fmt;
use thiserror::Error;
pub type KernelResult<T> = Result<T, KernelError>;
#[derive(Error, Debug)]
pub enum KernelError {
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
#[error("Transaction error: {kind}")]
Transaction { kind: TransactionErrorKind },
#[error("WAL error: {kind}")]
Wal { kind: WalErrorKind },
#[error("Page error: {kind}")]
Page { kind: PageErrorKind },
#[error("Catalog error: {kind}")]
Catalog { kind: CatalogErrorKind },
#[error("Plugin error: {message}")]
Plugin { message: String },
#[error("Data corruption detected: {details}")]
Corruption { details: String },
#[error("Recovery error: {details}")]
Recovery { details: String },
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum TransactionErrorKind {
NotFound(u64),
AlreadyCommitted,
AlreadyAborted,
WriteWriteConflict { row_id: u64 },
SerializationFailure,
Deadlock,
Timeout,
}
impl fmt::Display for TransactionErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotFound(id) => write!(f, "transaction {} not found", id),
Self::AlreadyCommitted => write!(f, "transaction already committed"),
Self::AlreadyAborted => write!(f, "transaction already aborted"),
Self::WriteWriteConflict { row_id } => {
write!(f, "write-write conflict on row {}", row_id)
}
Self::SerializationFailure => write!(f, "serialization failure"),
Self::Deadlock => write!(f, "deadlock detected"),
Self::Timeout => write!(f, "transaction timeout"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum WalErrorKind {
InvalidLsn(u64),
ChecksumMismatch { expected: u32, actual: u32 },
Corrupted,
Full,
FsyncFailed,
}
impl fmt::Display for WalErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::InvalidLsn(lsn) => write!(f, "invalid LSN: {}", lsn),
Self::ChecksumMismatch { expected, actual } => {
write!(
f,
"checksum mismatch: expected {}, got {}",
expected, actual
)
}
Self::Corrupted => write!(f, "WAL corrupted"),
Self::Full => write!(f, "WAL full"),
Self::FsyncFailed => write!(f, "fsync failed"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum PageErrorKind {
NotFound(u64),
Corrupted(u64),
BufferPoolFull,
InvalidSize,
}
impl fmt::Display for PageErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotFound(id) => write!(f, "page {} not found", id),
Self::Corrupted(id) => write!(f, "page {} corrupted", id),
Self::BufferPoolFull => write!(f, "buffer pool full"),
Self::InvalidSize => write!(f, "invalid page size"),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CatalogErrorKind {
TableNotFound(String),
TableExists(String),
ColumnNotFound(String),
SchemaMismatch,
}
impl fmt::Display for CatalogErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::TableNotFound(name) => write!(f, "table '{}' not found", name),
Self::TableExists(name) => write!(f, "table '{}' already exists", name),
Self::ColumnNotFound(name) => write!(f, "column '{}' not found", name),
Self::SchemaMismatch => write!(f, "schema mismatch"),
}
}
}