create better structure for admin query commands
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
b93215d7f2
commit
2de4eea688
9 changed files with 225 additions and 201 deletions
|
@ -30,7 +30,7 @@ use super::pdu::PduBuilder;
|
||||||
use crate::{
|
use crate::{
|
||||||
service::admin::{
|
service::admin::{
|
||||||
appservice::AppserviceCommand, debug::DebugCommand, federation::FederationCommand, media::MediaCommand,
|
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,
|
services, Error, Result,
|
||||||
};
|
};
|
||||||
|
@ -284,7 +284,7 @@ impl Service {
|
||||||
AdminCommand::Federation(command) => federation::process(command, body).await?,
|
AdminCommand::Federation(command) => federation::process(command, body).await?,
|
||||||
AdminCommand::Server(command) => server::process(command, body).await?,
|
AdminCommand::Server(command) => server::process(command, body).await?,
|
||||||
AdminCommand::Debug(command) => debug::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)
|
Ok(reply_message_content)
|
||||||
|
|
|
@ -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
|
|
||||||
),
|
|
||||||
))
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
79
src/service/admin/query/account_data.rs
Normal file
79
src/service/admin/query/account_data.rs
Normal file
|
@ -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
|
||||||
|
),
|
||||||
|
))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
40
src/service/admin/query/appservice.rs
Normal file
40
src/service/admin/query/appservice.rs
Normal file
|
@ -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
|
||||||
|
),
|
||||||
|
))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
6
src/service/admin/query/mod.rs
Normal file
6
src/service/admin/query/mod.rs
Normal file
|
@ -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;
|
61
src/service/admin/query/presence.rs
Normal file
61
src/service/admin/query/presence.rs
Normal file
|
@ -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
|
||||||
|
),
|
||||||
|
))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
36
src/service/admin/query/query.rs
Normal file
36
src/service/admin/query/query.rs
Normal file
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
0
src/service/admin/query/rooms/alias.rs
Normal file
0
src/service/admin/query/rooms/alias.rs
Normal file
1
src/service/admin/query/rooms/mod.rs
Normal file
1
src/service/admin/query/rooms/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub(crate) use alias;
|
Loading…
Add table
Add a link
Reference in a new issue