aboutsummaryrefslogtreecommitdiff
path: root/src/api/s3_delete.rs
blob: 4d6805fbe496eb6a45bf900ce8a9dafdd1b77e34 (plain) (blame)
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
use std::sync::Arc;

use garage_util::data::*;
use garage_util::error::Error;

use garage_core::garage::Garage;
use garage_core::object_table::*;

pub async fn handle_delete(garage: Arc<Garage>, bucket: &str, key: &str) -> Result<UUID, Error> {
	let object = match garage
		.object_table
		.get(&bucket.to_string(), &key.to_string())
		.await?
	{
		None => {
			// No need to delete
			return Ok([0u8; 32].into());
		}
		Some(o) => o,
	};

	let interesting_versions = object.versions().iter().filter(|v| {
		v.data != ObjectVersionData::DeleteMarker && v.state != ObjectVersionState::Aborted
	});

	let mut must_delete = false;
	let mut timestamp = now_msec();
	for v in interesting_versions {
		must_delete = true;
		timestamp = std::cmp::max(timestamp, v.timestamp + 1);
	}

	if !must_delete {
		return Ok([0u8; 32].into());
	}

	let version_uuid = gen_uuid();

	let object = Object::new(
		bucket.into(),
		key.into(),
		vec![ObjectVersion {
			uuid: version_uuid,
			timestamp: now_msec(),
			mime_type: "application/x-delete-marker".into(),
			size: 0,
			state: ObjectVersionState::Complete,
			data: ObjectVersionData::DeleteMarker,
		}],
	);

	garage.object_table.insert(&object).await?;
	return Ok(version_uuid);
}