mysqladm/client/commands/
show_db_privs.rs

1use 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    /// The name of the database(s) to show
19    #[arg(num_args = 0..)]
20    name: Vec<MySQLDatabase>,
21
22    /// Print the information as JSON
23    #[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}