#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[non_exhaustive]
pub enum IsolationLevel {
ReadUncommitted,
#[default]
ReadCommitted,
RepeatableRead,
Serializable,
Snapshot,
}
impl IsolationLevel {
#[must_use]
pub fn as_sql(&self) -> &'static str {
match self {
Self::ReadUncommitted => "SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED",
Self::ReadCommitted => "SET TRANSACTION ISOLATION LEVEL READ COMMITTED",
Self::RepeatableRead => "SET TRANSACTION ISOLATION LEVEL REPEATABLE READ",
Self::Serializable => "SET TRANSACTION ISOLATION LEVEL SERIALIZABLE",
Self::Snapshot => "SET TRANSACTION ISOLATION LEVEL SNAPSHOT",
}
}
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::ReadUncommitted => "READ UNCOMMITTED",
Self::ReadCommitted => "READ COMMITTED",
Self::RepeatableRead => "REPEATABLE READ",
Self::Serializable => "SERIALIZABLE",
Self::Snapshot => "SNAPSHOT",
}
}
}
#[derive(Debug, Clone)]
#[must_use = "a savepoint should be used to rollback or it has no effect"]
pub struct SavePoint {
pub(crate) name: String,
}
impl SavePoint {
pub(crate) fn new(name: String) -> Self {
Self { name }
}
#[must_use]
pub fn name(&self) -> &str {
&self.name
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use super::*;
#[test]
fn test_isolation_level_sql() {
assert_eq!(
IsolationLevel::ReadCommitted.as_sql(),
"SET TRANSACTION ISOLATION LEVEL READ COMMITTED"
);
assert_eq!(
IsolationLevel::Snapshot.as_sql(),
"SET TRANSACTION ISOLATION LEVEL SNAPSHOT"
);
}
#[test]
fn test_isolation_level_name() {
assert_eq!(IsolationLevel::ReadCommitted.name(), "READ COMMITTED");
assert_eq!(IsolationLevel::Serializable.name(), "SERIALIZABLE");
}
#[test]
fn test_savepoint_name() {
let sp = SavePoint::new("my_savepoint".to_string());
assert_eq!(sp.name(), "my_savepoint");
assert_eq!(sp.name, "my_savepoint");
}
#[test]
fn test_default_isolation_level() {
let level = IsolationLevel::default();
assert_eq!(level, IsolationLevel::ReadCommitted);
}
}