mysqladm/client/commands/
show_db_privs.rs1use clap::Parser;
2use futures_util::SinkExt;
3use prettytable::{Cell, Row, Table};
4use tokio_stream::StreamExt;
5
6use crate::{
7 client::commands::erroneous_server_response,
8 core::{
9 common::yn,
10 database_privileges::{DATABASE_PRIVILEGE_FIELDS, db_priv_field_human_readable_name},
11 protocol::{ClientToServerMessageStream, Request, Response},
12 types::MySQLDatabase,
13 },
14};
15
16#[derive(Parser, Debug, Clone)]
17pub struct ShowDbPrivsArgs {
18 #[arg(num_args = 0..)]
20 name: Vec<MySQLDatabase>,
21
22 #[arg(short, long)]
24 json: bool,
25}
26
27pub async fn show_database_privileges(
28 args: ShowDbPrivsArgs,
29 mut server_connection: ClientToServerMessageStream,
30) -> anyhow::Result<()> {
31 let message = if args.name.is_empty() {
32 Request::ListPrivileges(None)
33 } else {
34 Request::ListPrivileges(Some(args.name.to_owned()))
35 };
36 server_connection.send(message).await?;
37
38 let privilege_data = match server_connection.next().await {
39 Some(Ok(Response::ListPrivileges(databases))) => databases
40 .into_iter()
41 .filter_map(|(database_name, result)| match result {
42 Ok(privileges) => Some(privileges),
43 Err(err) => {
44 eprintln!("{}", err.to_error_message(&database_name));
45 eprintln!("Skipping...");
46 println!();
47 None
48 }
49 })
50 .flatten()
51 .collect::<Vec<_>>(),
52 Some(Ok(Response::ListAllPrivileges(privilege_rows))) => match privilege_rows {
53 Ok(list) => list,
54 Err(err) => {
55 server_connection.send(Request::Exit).await?;
56 return Err(anyhow::anyhow!(err.to_error_message())
57 .context("Failed to list database privileges"));
58 }
59 },
60 response => return erroneous_server_response(response),
61 };
62
63 server_connection.send(Request::Exit).await?;
64
65 if args.json {
66 println!("{}", serde_json::to_string_pretty(&privilege_data)?);
67 } else if privilege_data.is_empty() {
68 println!("No database privileges to show.");
69 } else {
70 let mut table = Table::new();
71 table.add_row(Row::new(
72 DATABASE_PRIVILEGE_FIELDS
73 .into_iter()
74 .map(db_priv_field_human_readable_name)
75 .map(|name| Cell::new(&name))
76 .collect(),
77 ));
78
79 for row in privilege_data {
80 table.add_row(row![
81 row.db,
82 row.user,
83 c->yn(row.select_priv),
84 c->yn(row.insert_priv),
85 c->yn(row.update_priv),
86 c->yn(row.delete_priv),
87 c->yn(row.create_priv),
88 c->yn(row.drop_priv),
89 c->yn(row.alter_priv),
90 c->yn(row.index_priv),
91 c->yn(row.create_tmp_table_priv),
92 c->yn(row.lock_tables_priv),
93 c->yn(row.references_priv),
94 ]);
95 }
96 table.printstd();
97 }
98
99 Ok(())
100}