Skip to main content

tuwunel_service/migrations/
upgrade_legacy_mediaid_user.rs

1use ruma::UserId;
2use tuwunel_core::{
3	Result, info,
4	utils::{ReadyExt, stream::TryIgnore},
5	warn,
6};
7use tuwunel_database::SEP;
8
9use crate::Services;
10
11pub(super) async fn upgrade_legacy_mediaid_user(services: &Services) -> Result {
12	let db = &services.db;
13	let cork = db.cork_and_sync();
14	let mediaid_user = db["mediaid_user"].clone();
15
16	warn!("Upgrading legacy mediaid_user keys to composite (mxc, user_id) layout");
17
18	let (checked, upgraded, removed_invalid) = mediaid_user
19		.raw_stream()
20		.ignore_err()
21		.ready_fold(
22			(0_usize, 0_usize, 0_usize),
23			|(mut checked, mut upgraded, mut removed_invalid), (raw_key, raw_val)| {
24				checked = checked.saturating_add(1);
25
26				let has_sep = raw_key.contains(&SEP);
27				let user_id = str::from_utf8(raw_val)
28					.ok()
29					.and_then(|s| <&UserId>::try_from(s).ok());
30
31				match (has_sep, user_id) {
32					| (true, _) => {},
33					| (false, None) => {
34						warn!(
35							?raw_key,
36							?raw_val,
37							"Legacy entry has unparsable user_id, removing"
38						);
39
40						mediaid_user.remove(raw_key);
41						removed_invalid = removed_invalid.saturating_add(1);
42					},
43					| (false, Some(user_id)) => {
44						let mut new_key = raw_key.to_vec();
45
46						new_key.push(SEP);
47						new_key.extend_from_slice(user_id.as_bytes());
48
49						mediaid_user.put_raw(new_key, user_id.as_str());
50						mediaid_user.remove(raw_key);
51
52						upgraded = upgraded.saturating_add(1);
53					},
54				}
55
56				(checked, upgraded, removed_invalid)
57			},
58		)
59		.await;
60
61	drop(cork);
62	info!(
63		%checked,
64		%upgraded,
65		%removed_invalid,
66		"Upgraded legacy mediaid_user keys"
67	);
68
69	db["global"].insert(b"upgrade_legacy_mediaid_user", []);
70	mediaid_user.sort()
71}