Skip to content

Commit

Permalink
feat: add database open options
Browse files Browse the repository at this point in the history
  • Loading branch information
peeeuzin committed May 3, 2024
1 parent ff5b60b commit 889275e
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .hooky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ set -o errexit
set -o nounset
set -o pipefail

. ./tests/run_tests.sh
. ./tests/run-tests.sh

exit 0
30 changes: 28 additions & 2 deletions src/collection/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
mod storage;
mod wal;

use crate::config;
use crate::error::{self, Result};
use crate::{config, OpenOptions};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::ops::RangeBounds;
use std::{
Expand Down Expand Up @@ -103,6 +103,7 @@ pub enum TransactionStatus {
pub struct Collection<T: Sync + Send + Clone + Debug + Serialize + DeserializeOwned + 'static> {
memtable: Memtable<T>,
storage: Storage,
config: config::DustDataConfig,
pub wal: Wal,
}

Expand All @@ -118,6 +119,7 @@ impl<T: Sync + Send + Clone + Debug + Serialize + 'static + DeserializeOwned> Co
Self {
memtable: Arc::new(RwLock::new(HashMap::new())),
wal,
config,
storage,
}
}
Expand Down Expand Up @@ -149,6 +151,12 @@ impl<T: Sync + Send + Clone + Debug + Serialize + 'static + DeserializeOwned> Co
panic!("Transaction already committed");
}

if self.config.open_options == OpenOptions::ReadOnly {
return Err(error::Error::Cannot(
"commit a transaction, due read-only mode".to_string(),
));
}

if transaction.data.is_empty() {
return Ok(());
}
Expand All @@ -162,7 +170,7 @@ impl<T: Sync + Send + Clone + Debug + Serialize + 'static + DeserializeOwned> Co
data: wal_operations,
};

wal.write(transaction_log);
wal.write(transaction_log)?;

transaction.status = TransactionStatus::Committed;

Expand All @@ -185,6 +193,12 @@ impl<T: Sync + Send + Clone + Debug + Serialize + 'static + DeserializeOwned> Co
where
R: RangeBounds<usize>,
{
if self.config.open_options == OpenOptions::ReadOnly {
return Err(error::Error::Cannot(
"commit a transaction, due read-only mode".to_string(),
));
}

let mut rollback_transactions = {
let wal = self.wal.read().map_err(|_| error::Error::Deadlock)?;
wal.revert_range(range)?
Expand All @@ -208,6 +222,12 @@ impl<T: Sync + Send + Clone + Debug + Serialize + 'static + DeserializeOwned> Co
_ => {}
}

if self.config.open_options == OpenOptions::ReadOnly {
return Err(error::Error::Cannot(
"commit a transaction, due read-only mode".to_string(),
));
}

let tx_id = transaction.tx_id();

let mut rollback_transaction = {
Expand All @@ -232,6 +252,12 @@ impl<T: Sync + Send + Clone + Debug + Serialize + 'static + DeserializeOwned> Co
_ => {}
}

if self.config.open_options == OpenOptions::ReadOnly {
return Err(error::Error::Cannot(
"commit a transaction, due read-only mode".to_string(),
));
}

let tx_id = transaction.tx_id();

let revert_transaction = {
Expand Down
13 changes: 11 additions & 2 deletions src/collection/wal.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::error::{Error, Result};
use crate::error::{self, Error, Result};
use crate::OpenOptions;

use super::{config, Operation, Transaction};
use flate2::{read::GzDecoder, write::GzEncoder, Compression};
Expand Down Expand Up @@ -171,16 +172,24 @@ impl Wal {
Ok(transaction)
}

pub fn write<T>(&mut self, transaction: TransactionLog<T>)
pub fn write<T>(&mut self, transaction: TransactionLog<T>) -> Result<()>
where
T: Sync + Send + Clone + Debug + Serialize + 'static + DeserializeOwned,
{
if self.config.open_options == OpenOptions::ReadOnly {
return Err(error::Error::Cannot(
"commit a transaction, due read-only mode".to_string(),
));
}

let offset = self.current_file.file.metadata().unwrap().len() as usize;
let bytes = Self::serialize_value(&transaction);

self.index
.write(transaction.tx_id, self.current_file.id, offset);
self.current_file.file.write_all(&bytes).unwrap();

Ok(())
}

pub fn read<T>(&self, tx_id: usize) -> Result<Option<TransactionLog<T>>>
Expand Down
18 changes: 18 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
use std::path::{Path, PathBuf};

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum OpenOptions {
/// Open the database in read-only mode.
ReadOnly,
/// Open the database in read-write mode.
ReadWrite,
}

#[derive(Debug, Clone)]
pub struct DustDataConfig {
pub wal: WALConfig,
pub data_path: PathBuf,
pub storage: StorageConfig,
pub open_options: OpenOptions,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -52,6 +61,7 @@ impl DustDataConfig {
wal: WALConfig::new(),
data_path: PathBuf::from("./data"),
storage: StorageConfig::new(),
open_options: OpenOptions::ReadWrite,
}
}

Expand Down Expand Up @@ -82,6 +92,14 @@ impl DustDataConfig {
self
}

/// The open options for the database.
/// Default: OpenOptions::ReadWrite
/// This is the mode in which the database is opened.
pub fn open_options(&mut self, open_options: OpenOptions) -> &mut Self {
self.open_options = open_options;
self
}

pub fn build(&self) -> Self {
self.clone()
}
Expand Down
2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub enum Error {
NotFound(String),
CorruptedData(String),
Other(String),
Cannot(String),
}

impl Debug for Error {
Expand All @@ -22,6 +23,7 @@ impl Debug for Error {
Error::CorruptedData(err) => write!(f, "Corrupted data: {}", err),
Error::AlreadyExists(message) => write!(f, "{} already exists", message),
Error::NotFound(message) => write!(f, "{} not found", message),
Error::Cannot(message) => write!(f, "cannot {}", message),
}
}
}
Expand Down
File renamed without changes.

0 comments on commit 889275e

Please sign in to comment.