From 2de4eea688c316ad6d130e2dfc6bd58da4d0f4af Mon Sep 17 00:00:00 2001
From: strawberry <strawberry@puppygock.gay>
Date: Sat, 20 Apr 2024 14:44:31 -0400
Subject: [PATCH] create better structure for admin query commands

Signed-off-by: strawberry <strawberry@puppygock.gay>
---
 src/service/admin/mod.rs                |   4 +-
 src/service/admin/query.rs              | 199 ------------------------
 src/service/admin/query/account_data.rs |  79 ++++++++++
 src/service/admin/query/appservice.rs   |  40 +++++
 src/service/admin/query/mod.rs          |   6 +
 src/service/admin/query/presence.rs     |  61 ++++++++
 src/service/admin/query/query.rs        |  36 +++++
 src/service/admin/query/rooms/alias.rs  |   0
 src/service/admin/query/rooms/mod.rs    |   1 +
 9 files changed, 225 insertions(+), 201 deletions(-)
 delete mode 100644 src/service/admin/query.rs
 create mode 100644 src/service/admin/query/account_data.rs
 create mode 100644 src/service/admin/query/appservice.rs
 create mode 100644 src/service/admin/query/mod.rs
 create mode 100644 src/service/admin/query/presence.rs
 create mode 100644 src/service/admin/query/query.rs
 create mode 100644 src/service/admin/query/rooms/alias.rs
 create mode 100644 src/service/admin/query/rooms/mod.rs

diff --git a/src/service/admin/mod.rs b/src/service/admin/mod.rs
index 5c5fc2b1..244df85f 100644
--- a/src/service/admin/mod.rs
+++ b/src/service/admin/mod.rs
@@ -30,7 +30,7 @@ use super::pdu::PduBuilder;
 use crate::{
 	service::admin::{
 		appservice::AppserviceCommand, debug::DebugCommand, federation::FederationCommand, media::MediaCommand,
-		query::QueryCommand, room::RoomCommand, server::ServerCommand, user::UserCommand,
+		query::query::QueryCommand, room::RoomCommand, server::ServerCommand, user::UserCommand,
 	},
 	services, Error, Result,
 };
@@ -284,7 +284,7 @@ impl Service {
 			AdminCommand::Federation(command) => federation::process(command, body).await?,
 			AdminCommand::Server(command) => server::process(command, body).await?,
 			AdminCommand::Debug(command) => debug::process(command, body).await?,
-			AdminCommand::Query(command) => query::process(command, body).await?,
+			AdminCommand::Query(command) => query::query::process(command, body).await?,
 		};
 
 		Ok(reply_message_content)
diff --git a/src/service/admin/query.rs b/src/service/admin/query.rs
deleted file mode 100644
index b86387f6..00000000
--- a/src/service/admin/query.rs
+++ /dev/null
@@ -1,199 +0,0 @@
-use clap::Subcommand;
-use ruma::{
-	events::{room::message::RoomMessageEventContent, RoomAccountDataEventType},
-	RoomId, UserId,
-};
-
-use crate::{services, Result};
-
-#[cfg_attr(test, derive(Debug))]
-#[derive(Subcommand)]
-/// Query tables from database
-pub(crate) enum QueryCommand {
-	/// - account_data.rs iterators and getters
-	#[command(subcommand)]
-	AccountData(AccountData),
-
-	/// - appservice.rs iterators and getters
-	#[command(subcommand)]
-	Appservice(Appservice),
-
-	/// - presence.rs iterators and getters
-	#[command(subcommand)]
-	Presence(Presence),
-}
-
-#[cfg_attr(test, derive(Debug))]
-#[derive(Subcommand)]
-/// All the getters and iterators from src/database/key_value/account_data.rs
-/// via services()
-pub(crate) enum AccountData {
-	/// - Returns all changes to the account data that happened after `since`.
-	ChangesSince {
-		/// Full user ID
-		user_id: Box<UserId>,
-		/// UNIX timestamp since (u64)
-		since: u64,
-		/// Optional room ID of the account data
-		room_id: Option<Box<RoomId>>,
-	},
-
-	/// - Searches the account data for a specific kind.
-	Get {
-		/// Full user ID
-		user_id: Box<UserId>,
-		/// Account data event type
-		kind: RoomAccountDataEventType,
-		/// Optional room ID of the account data
-		room_id: Option<Box<RoomId>>,
-	},
-}
-
-#[cfg_attr(test, derive(Debug))]
-#[derive(Subcommand)]
-/// All the getters and iterators from src/database/key_value/appservice.rs via
-/// services()
-pub(crate) enum Appservice {
-	/// - Gets the appservice registration info/details from the ID as a string
-	GetRegistration {
-		/// Appservice registration ID
-		appservice_id: Box<str>,
-	},
-}
-
-#[cfg_attr(test, derive(Debug))]
-#[derive(Subcommand)]
-/// All the getters and iterators from src/database/key_value/presence.rs via
-/// services()
-pub(crate) enum Presence {
-	/// - Returns the latest presence event for the given user.
-	GetPresence {
-		/// Full user ID
-		user_id: Box<UserId>,
-	},
-
-	/// - Returns the most recent presence updates that happened after the event
-	///   with id `since`.
-	PresenceSince {
-		/// UNIX timestamp since (u64)
-		since: u64,
-	},
-}
-
-/// Processes admin command
-#[allow(non_snake_case)]
-pub(crate) async fn process(command: QueryCommand, _body: Vec<&str>) -> Result<RoomMessageEventContent> {
-	match command {
-		QueryCommand::AccountData(AccountData) => account_data(AccountData).await,
-		QueryCommand::Appservice(Appservice) => appservice(Appservice).await,
-		QueryCommand::Presence(Presence) => presence(Presence).await,
-	}
-}
-
-/// All the getters and iterators in key_value/account_data.rs via services()
-async fn account_data(subcommand: AccountData) -> Result<RoomMessageEventContent> {
-	match subcommand {
-		AccountData::ChangesSince {
-			user_id,
-			since,
-			room_id,
-		} => {
-			let timer = tokio::time::Instant::now();
-			let results = services()
-				.account_data
-				.db
-				.changes_since(room_id.as_deref(), &user_id, since)?;
-			let query_time = timer.elapsed();
-
-			Ok(RoomMessageEventContent::text_html(
-				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", results),
-				format!(
-					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
-					results
-				),
-			))
-		},
-		AccountData::Get {
-			user_id,
-			kind,
-			room_id,
-		} => {
-			let timer = tokio::time::Instant::now();
-			let results = services()
-				.account_data
-				.db
-				.get(room_id.as_deref(), &user_id, kind)?;
-			let query_time = timer.elapsed();
-
-			Ok(RoomMessageEventContent::text_html(
-				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", results),
-				format!(
-					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
-					results
-				),
-			))
-		},
-	}
-}
-
-/// All the getters and iterators in key_value/appservice.rs via services()
-async fn appservice(subcommand: Appservice) -> Result<RoomMessageEventContent> {
-	match subcommand {
-		Appservice::GetRegistration {
-			appservice_id,
-		} => {
-			let timer = tokio::time::Instant::now();
-			let results = services()
-				.appservice
-				.db
-				.get_registration(appservice_id.as_ref())?;
-			let query_time = timer.elapsed();
-
-			Ok(RoomMessageEventContent::text_html(
-				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", results),
-				format!(
-					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
-					results
-				),
-			))
-		},
-	}
-}
-
-/// All the getters and iterators in key_value/appservice.rs via services()
-async fn presence(subcommand: Presence) -> Result<RoomMessageEventContent> {
-	match subcommand {
-		Presence::GetPresence {
-			user_id,
-		} => {
-			let timer = tokio::time::Instant::now();
-			let results = services().presence.db.get_presence(&user_id)?;
-			let query_time = timer.elapsed();
-
-			Ok(RoomMessageEventContent::text_html(
-				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", results),
-				format!(
-					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
-					results
-				),
-			))
-		},
-		Presence::PresenceSince {
-			since,
-		} => {
-			let timer = tokio::time::Instant::now();
-			let results = services().presence.db.presence_since(since);
-			let query_time = timer.elapsed();
-
-			let presence_since: Vec<(_, _, _)> = results.collect();
-
-			Ok(RoomMessageEventContent::text_html(
-				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", presence_since),
-				format!(
-					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
-					presence_since
-				),
-			))
-		},
-	}
-}
diff --git a/src/service/admin/query/account_data.rs b/src/service/admin/query/account_data.rs
new file mode 100644
index 00000000..34bba0f6
--- /dev/null
+++ b/src/service/admin/query/account_data.rs
@@ -0,0 +1,79 @@
+use clap::Subcommand;
+use ruma::{
+	events::{room::message::RoomMessageEventContent, RoomAccountDataEventType},
+	RoomId, UserId,
+};
+
+use crate::{services, Result};
+
+#[cfg_attr(test, derive(Debug))]
+#[derive(Subcommand)]
+/// All the getters and iterators from src/database/key_value/account_data.rs
+/// via services()
+pub(crate) enum AccountData {
+	/// - Returns all changes to the account data that happened after `since`.
+	ChangesSince {
+		/// Full user ID
+		user_id: Box<UserId>,
+		/// UNIX timestamp since (u64)
+		since: u64,
+		/// Optional room ID of the account data
+		room_id: Option<Box<RoomId>>,
+	},
+
+	/// - Searches the account data for a specific kind.
+	Get {
+		/// Full user ID
+		user_id: Box<UserId>,
+		/// Account data event type
+		kind: RoomAccountDataEventType,
+		/// Optional room ID of the account data
+		room_id: Option<Box<RoomId>>,
+	},
+}
+
+/// All the getters and iterators in key_value/account_data.rs via services()
+pub(crate) async fn account_data(subcommand: AccountData) -> Result<RoomMessageEventContent> {
+	match subcommand {
+		AccountData::ChangesSince {
+			user_id,
+			since,
+			room_id,
+		} => {
+			let timer = tokio::time::Instant::now();
+			let results = services()
+				.account_data
+				.db
+				.changes_since(room_id.as_deref(), &user_id, since)?;
+			let query_time = timer.elapsed();
+
+			Ok(RoomMessageEventContent::text_html(
+				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", results),
+				format!(
+					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
+					results
+				),
+			))
+		},
+		AccountData::Get {
+			user_id,
+			kind,
+			room_id,
+		} => {
+			let timer = tokio::time::Instant::now();
+			let results = services()
+				.account_data
+				.db
+				.get(room_id.as_deref(), &user_id, kind)?;
+			let query_time = timer.elapsed();
+
+			Ok(RoomMessageEventContent::text_html(
+				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", results),
+				format!(
+					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
+					results
+				),
+			))
+		},
+	}
+}
diff --git a/src/service/admin/query/appservice.rs b/src/service/admin/query/appservice.rs
new file mode 100644
index 00000000..2ab3c1a1
--- /dev/null
+++ b/src/service/admin/query/appservice.rs
@@ -0,0 +1,40 @@
+use clap::Subcommand;
+use ruma::events::room::message::RoomMessageEventContent;
+
+use crate::{services, Result};
+
+#[cfg_attr(test, derive(Debug))]
+#[derive(Subcommand)]
+/// All the getters and iterators from src/database/key_value/appservice.rs via
+/// services()
+pub(crate) enum Appservice {
+	/// - Gets the appservice registration info/details from the ID as a string
+	GetRegistration {
+		/// Appservice registration ID
+		appservice_id: Box<str>,
+	},
+}
+
+/// All the getters and iterators in key_value/appservice.rs via services()
+pub(crate) async fn appservice(subcommand: Appservice) -> Result<RoomMessageEventContent> {
+	match subcommand {
+		Appservice::GetRegistration {
+			appservice_id,
+		} => {
+			let timer = tokio::time::Instant::now();
+			let results = services()
+				.appservice
+				.db
+				.get_registration(appservice_id.as_ref())?;
+			let query_time = timer.elapsed();
+
+			Ok(RoomMessageEventContent::text_html(
+				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", results),
+				format!(
+					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
+					results
+				),
+			))
+		},
+	}
+}
diff --git a/src/service/admin/query/mod.rs b/src/service/admin/query/mod.rs
new file mode 100644
index 00000000..04c98a8d
--- /dev/null
+++ b/src/service/admin/query/mod.rs
@@ -0,0 +1,6 @@
+#[allow(clippy::module_inception)]
+pub(crate) mod query;
+
+pub(crate) mod account_data;
+pub(crate) mod appservice;
+pub(crate) mod presence;
diff --git a/src/service/admin/query/presence.rs b/src/service/admin/query/presence.rs
new file mode 100644
index 00000000..7df4858a
--- /dev/null
+++ b/src/service/admin/query/presence.rs
@@ -0,0 +1,61 @@
+use clap::Subcommand;
+use ruma::{events::room::message::RoomMessageEventContent, UserId};
+
+use crate::{services, Result};
+
+#[cfg_attr(test, derive(Debug))]
+#[derive(Subcommand)]
+/// All the getters and iterators from src/database/key_value/presence.rs via
+/// services()
+pub(crate) enum Presence {
+	/// - Returns the latest presence event for the given user.
+	GetPresence {
+		/// Full user ID
+		user_id: Box<UserId>,
+	},
+
+	/// - Returns the most recent presence updates that happened after the event
+	///   with id `since`.
+	PresenceSince {
+		/// UNIX timestamp since (u64)
+		since: u64,
+	},
+}
+
+/// All the getters and iterators in key_value/presence.rs via services()
+pub(crate) async fn presence(subcommand: Presence) -> Result<RoomMessageEventContent> {
+	match subcommand {
+		Presence::GetPresence {
+			user_id,
+		} => {
+			let timer = tokio::time::Instant::now();
+			let results = services().presence.db.get_presence(&user_id)?;
+			let query_time = timer.elapsed();
+
+			Ok(RoomMessageEventContent::text_html(
+				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", results),
+				format!(
+					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
+					results
+				),
+			))
+		},
+		Presence::PresenceSince {
+			since,
+		} => {
+			let timer = tokio::time::Instant::now();
+			let results = services().presence.db.presence_since(since);
+			let query_time = timer.elapsed();
+
+			let presence_since: Vec<(_, _, _)> = results.collect();
+
+			Ok(RoomMessageEventContent::text_html(
+				format!("Query completed in {query_time:?}:\n\n```\n{:?}```", presence_since),
+				format!(
+					"<p>Query completed in {query_time:?}:</p>\n<pre><code>{:?}\n</code></pre>",
+					presence_since
+				),
+			))
+		},
+	}
+}
diff --git a/src/service/admin/query/query.rs b/src/service/admin/query/query.rs
new file mode 100644
index 00000000..6d56eca2
--- /dev/null
+++ b/src/service/admin/query/query.rs
@@ -0,0 +1,36 @@
+use clap::Subcommand;
+use ruma::events::room::message::RoomMessageEventContent;
+
+use super::{
+	account_data::{account_data, AccountData},
+	appservice::{appservice, Appservice},
+	presence::{presence, Presence},
+};
+use crate::Result;
+
+#[cfg_attr(test, derive(Debug))]
+#[derive(Subcommand)]
+/// Query tables from database
+pub(crate) enum QueryCommand {
+	/// - account_data.rs iterators and getters
+	#[command(subcommand)]
+	AccountData(AccountData),
+
+	/// - appservice.rs iterators and getters
+	#[command(subcommand)]
+	Appservice(Appservice),
+
+	/// - presence.rs iterators and getters
+	#[command(subcommand)]
+	Presence(Presence),
+}
+
+/// Processes admin query commands
+#[allow(non_snake_case)]
+pub(crate) async fn process(command: QueryCommand, _body: Vec<&str>) -> Result<RoomMessageEventContent> {
+	match command {
+		QueryCommand::AccountData(AccountData) => account_data(AccountData).await,
+		QueryCommand::Appservice(Appservice) => appservice(Appservice).await,
+		QueryCommand::Presence(Presence) => presence(Presence).await,
+	}
+}
diff --git a/src/service/admin/query/rooms/alias.rs b/src/service/admin/query/rooms/alias.rs
new file mode 100644
index 00000000..e69de29b
diff --git a/src/service/admin/query/rooms/mod.rs b/src/service/admin/query/rooms/mod.rs
new file mode 100644
index 00000000..10d83ca6
--- /dev/null
+++ b/src/service/admin/query/rooms/mod.rs
@@ -0,0 +1 @@
+pub(crate) use alias;