1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#[cfg(feature = "alter-table")]
mod alter_table;
#[cfg(feature = "alter-table")]
pub use alter_table::*;
#[cfg(not(feature = "alter-table"))]
pub trait AlterTable {}

#[cfg(feature = "auto-increment")]
mod auto_increment;
use crate::IndexFilter;
#[cfg(feature = "auto-increment")]
pub use auto_increment::AutoIncrement;
#[cfg(not(feature = "auto-increment"))]
pub trait AutoIncrement {}

use {
	crate::{
		data::{Row, Schema},
		result::Result,
		Value,
	},
	async_trait::async_trait,
	serde::Serialize,
	std::fmt::Debug,
	thiserror::Error,
};

#[derive(Error, Serialize, Debug, PartialEq)]
pub enum StorageError {
	#[error("this storage has not yet implemented this method")]
	Unimplemented,
}

pub struct Storage {
	storage: Option<Box<dyn FullStorage>>,
}
impl Storage {
	pub fn new(storage: Box<dyn FullStorage>) -> Self {
		let storage = Some(storage);
		Self { storage }
	}
	pub fn replace(&mut self, storage: Box<dyn FullStorage>) {
		self.storage.replace(storage);
	}
	pub fn take(&mut self) -> Box<dyn FullStorage> {
		self.storage
			.take()
			.expect("Unreachable: Storage wasn't replaced!")
	}
	pub fn take_readable(&mut self) -> &StorageInner {
		/*let storage = self.take();
		let readable = &*storage;
		self.replace(storage);
		readable*/
		unimplemented!()
	}
}

pub type StorageInner = dyn FullStorage;

pub trait FullStorage: Store + StoreMut + AlterTable + AutoIncrement {}

pub type RowIter = Box<dyn Iterator<Item = Result<(Value, Row)>>>;

/// By implementing `Store` trait, you can run `SELECT` queries.
#[async_trait(?Send)]
pub trait Store {
	async fn fetch_schema(&self, _table_name: &str) -> Result<Option<Schema>> {
		Err(StorageError::Unimplemented.into())
	}

	async fn scan_data(&self, _table_name: &str) -> Result<RowIter> {
		Err(StorageError::Unimplemented.into())
	}

	async fn scan_data_indexed(
		&self,
		_table_name: &str,
		_index_filters: IndexFilter,
	) -> Result<RowIter> {
		Err(StorageError::Unimplemented.into())
	}
	async fn scan_index(
		&self,
		_table_name: &str,
		_index_filter: IndexFilter,
	) -> Result<Vec<Value>> {
		Err(StorageError::Unimplemented.into())
	}
}

/// `StoreMut` takes role of mutation, related to `INSERT`, `CREATE`, `DELETE`, `DROP` and
/// `UPDATE`.
#[async_trait(?Send)]
pub trait StoreMut {
	async fn insert_schema(&mut self, _schema: &Schema) -> Result<()> {
		Err(StorageError::Unimplemented.into())
	}

	async fn delete_schema(&mut self, _table_name: &str) -> Result<()> {
		Err(StorageError::Unimplemented.into())
	}

	async fn insert_data(&mut self, _table_name: &str, _rows: Vec<Row>) -> Result<()> {
		Err(StorageError::Unimplemented.into())
	}

	async fn update_data(&mut self, _rows: Vec<(Value, Row)>) -> Result<()> {
		Err(StorageError::Unimplemented.into())
	}

	async fn delete_data(&mut self, _keys: Vec<Value>) -> Result<()> {
		Err(StorageError::Unimplemented.into())
	}

	async fn update_index(
		&mut self,
		_index_name: &str,
		_table_name: &str,
		_keys: Vec<(Value, Value)>,
	) -> Result<()> {
		Err(StorageError::Unimplemented.into())
	}
}