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
#![cfg(feature = "auto-increment")]
use {
	super::{error::err_into, SledDatabase},
	crate::{AutoIncrement, Error, Result},
	async_trait::async_trait,
	fstrings::*,
	sled::transaction::ConflictableTransactionError,
};

#[async_trait(?Send)]
impl AutoIncrement for SledDatabase {
	async fn generate_increment_values(
		&mut self,
		table_name: String,
		columns: Vec<(
			usize,  /*index*/
			String, /*name*/
			i64,    /*row_count*/
		) /*column*/>,
	) -> Result<
		Vec<(
			(usize /*index*/, String /*name*/), /*column*/
			i64,                                /*start_value*/
		)>,
	> {
		self.tree
			.transaction(|tree| {
				let mut results = vec![];
				for (column_index, column_name, row_count) in &columns {
					// KG: I couldn't get the colunns variable in here for some reason (because it is an enclosure?)
					let (column_index, column_name, row_count): (usize, String, i64) =
						(*column_index, column_name.clone(), *row_count);
					let table_name = table_name.clone();
					let key = f!("generator/{table_name}/{column_name}");
					let key = key.as_bytes();

					let start_ivec = tree.get(key)?;
					let start_value = start_ivec
						.map(|value| bincode::deserialize(&value))
						.unwrap_or(Ok(1))
						.map_err(err_into)
						.map_err(ConflictableTransactionError::Abort)?;

					let end_value = start_value + row_count;
					let end_ivec = bincode::serialize(&end_value)
						.map_err(err_into)
						.map_err(ConflictableTransactionError::Abort)?;

					tree.insert(key, end_ivec)?;
					results.push(((column_index, column_name), start_value));
				}
				Ok(results)
			})
			.map_err(Error::from)
	}

	async fn set_increment_value(
		&mut self,
		table_name: &str,
		column_name: &str,
		end: i64,
	) -> Result<()> {
		let end_ivec = bincode::serialize(&end).map_err(err_into)?;

		let key = f!("generator/{table_name}/{column_name}");
		let key = key.as_bytes();

		self.tree.insert(key, end_ivec).map_err(err_into)?;

		Ok(())
	}
}